{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## 선형 회귀를 사용한 머신러닝 연습" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "사이킷런은 아나콘다 배포판에 기본으로 포함되어 있습니다. 여기에서 사용할 데이터셋은 사이킷런에 포함되어 있는 예제 데이터셋으로 당뇨병 데이터셋입니다. 당뇨병 데이터셋을 로드하기 위해 먼저 `datasets` 모듈을 임포트합니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "from sklearn import datasets\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`load_diabetes()` 함수는 `Bunch` 클래스의 객체를 반환합니다. 이 객체는 파이썬의 딕셔너리와 유사하고 사이킷런에서 예제 데이터셋을 위해 만든 것입니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "diabetes = datasets.load_diabetes()\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`diabetes`는 일반 딕셔너리처럼 `keys()` 메서드에서 객체가 가지고 있는 키 값을 모두 반환해줍니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "diabetes.keys()\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`data` 키에 훈련 데이터가 있고, `target` 키에 타깃 레이블이 있습니다. 나머지 두 개의 컬럼은 데이터셋에 대한 설명과, 컬럼의 이름을 가지고 있습니다. `data`와 `target`의 데이터 타입이 무엇인지 확인해 보겠습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "type(diabetes.data)\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "type(diabetes.target)\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "데이터가 넘파이 배열로 되어 있으므로 배열의 차원을 확인해 보겠습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "diabetes.data.shape\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "diabetes.target.shape\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "데이터에 어떤 값이 들어 있는지 잠깐 확인해 보겠습니다. 전체 데이터는 양이 많으므로 처음 두 개의 샘플만 출력합니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "diabetes.data[:2]\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "diabetes.target[:2]\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "문제를 간단하게 시각화하기 위해서 하나의 특성만을 사용해 보겠습니다. 세 번째 특성을 출력하면 타깃과 상관관계가 있음을 확인할 수 있습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "import matplotlib.pyplot as plt\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "plt.scatter(diabetes.data[:, 2], diabetes.target)\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "그럼 이제 확률적 경사 하강법을 사용하는 사이킷런의 `SGDRegressor` 모델을 임포트합니다. 이 모델은 회귀를 위한 모델입니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "from sklearn.linear_model import SGDRegressor\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`SGDRegressor` 클래스의 객체를 만들겠습니다. 객체를 만들 때 여러 매개변수를 전달할 수 있지만 지금은 기본 값을 사용하겠습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "sgd_regr = SGDRegressor()\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "사이킷런의 모델 객체를 출력하면 친절하게 현재 객체에 설정된 매개변수 값을 함께 보여줍니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "sgd_regr\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "이제 당뇨병 데이터의 세 번째 특성을 사용해 모델을 학습시킬 차례입니다. 두 번째 특성을 선택해서 별도의 변수 `x`에 저장합니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "x = diabetes.data[:, 2]\n", "x.shape\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "변수 `x`의 크기를 확인해 보면 1차원 배열임을 알 수 있습니다. 사이킷런은 입력 데이터가 항상 2차원 배열일 것으로 간주하고 있습니다. 1차원 배열을 넣으면 에러가 발생합니다. 넘파이에서 배열의 크기를 변경하는 함수는 `reshape()` 메서드입니다.\n", "\n", "특히 `-1`로 지정된 차원은 다른 차원이 모두 채워진 후 남은 차원을 의미합니다. `(-1, 1)`로 차원을 지정하게 되면 전체 원소의 개수는 그대로 유지하고 2차원 배열을 간단하게 만들 수 있습니다. 사이킷런은 관례적으로 행렬(2차원배열)에는 대문자 변수를 사용합니다. 여기에서도 대문자 `X`를 사용하겠습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "X = x.reshape(-1, 1)\n", "X.shape\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "그럼 간단히 변환된 데이터가 어떻게 차이나는지 확인해 보죠. 2개의 행만 출력해 보겠습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "x[:2]\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "이제 위에서 만든 `sgd_regr` 모델을 학습시킬 차례입니다. 사이킷런에서 학습하는 메서드는 모두 `fit()`입니다. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "sgd_regr.fit(X, diabetes.target)\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "확률적 경사 하강법은 점진적으로 모델 파라미터를 변경하기 때문에 반복적으로 학습이 진행됩니다. 이 경고는 반복 횟수를 지정하는 `max_iter`의 기본값이 5로 지정되었다는 것을 알려줍니다. 이는 확실히 충분하지 않은 값이므로 반복 횟수를 늘려서 실행해 보겠습니다. 반복 횟수를 늘리려면 `sgd_regr` 객체를 다시 생성해 주어야 합니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "sgd_regr = SGDRegressor(max_iter=20000)\n", "sgd_regr.fit(X, diabetes.target)\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "사이킷런의 선형 모델은 찾은 모델 파라미터를 각각 `coef_`와 `intercept_` 속성에 저장하고 있습니다. 즉 \n", "\n", "$$ y = coef\\_ \\times x + intercept\\_ $$\n", "\n", "의 모델 파라미터를 찾은 것입니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "sgd_regr.coef_, sgd_regr.intercept_\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "찾은 직선을 화면에 출력해 보겠습니다. `matplotlib`은 여러 개의 그래프를 중복해서 그릴 수 있으며 한 셀의 실행이 끝나면 자동으로 `plt.show()` 함수를 호출해 줍니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "plt.scatter(x, diabetes.target)\n", "plt.plot(x, x * sgd_regr.coef_ + sgd_regr.intercept_)\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "확률적 경사 하강법은 신경망 알고리즘에서 사용하는 대표적인 방법입니다. 그리고 데이터셋이 클 경우 선택할 수 있는 좋을 최적화 알고리즘입니다. \n", "\n", "오래전부터 선형 회귀에는 행렬 분해 방식을 사용하여 정규 방정식의 해를 계산하는 방식이 사용되었습니다. 사이킷런에도 `LinearRegression` 클래스에서 이를 지원합니다.\n", "\n", "$$w = (X^TX)^{-1}X^Ty$$\n", "\n", "역시 동일하게 `linear_model` 패키지에서 `LinearRegression` 클래스를 임포트하겠습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "from sklearn.linear_model import LinearRegression\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`LinearRegression` 클래스의 객체를 생성합니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "lin_regr = LinearRegression()\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "앞에서 만든 데이터를 사용해 `fit()` 메서드를 호출하면 학습이 됩니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "lin_regr.fit(X, diabetes.target)\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "찾은 기울기와 절편을 출력하고 `sgd_regr`의 속성과 비교해 보겠습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "lin_regr.coef_, lin_regr.intercept_, sgd_regr.coef_, sgd_regr.intercept_\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "앞에서와 동일하게 그래프로 나타내 보겠습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# 다음 셀에 코드를 직접 입력해 보세요\n", "plt.scatter(x, diabetes.target)\n", "plt.plot(x, x * lin_regr.coef_ + lin_regr.intercept_)\n", "plt.plot(x, x * sgd_regr.coef_ + sgd_regr.intercept_)\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.3" } }, "nbformat": 4, "nbformat_minor": 2 }