今日からはじめるPython機械学習プログラミング基礎 教師あり学習その1


初めて記事を書いてみました。
初心者向けかつ自分自身のアウトプットの練習を兼ねているので、間違っている点があればご指摘いただければ幸いです。

##教師あり学習
説明変数：Xから目的変数：Yを予測するモデルを求める手法です。訓練データには答えである正解ラベル（目的変数）が与えられており（教師あり）、モデルから出力される目的変数が訓練データの目的変数にできる限り近付くように繰り返しパラメータを調整する学習をします。

##教師なし学習
データから背後にある規則性を導き出す手法です。訓練データには正解ラベル（目的変数）が与えられておらず（教師なし）、特定数のクラスターに分類するクラスタリング、特徴を失わないようにデータの次元を圧縮する主成分分析などがあります。

##強化学習
プログラムの一連の行動に対して報酬を与え、その報酬が最大になるように繰り返し学習させることで、機械に実現させたい行動を得ようとする手法です。教師なし学習と同様に、正解ラベル（目的変数）は与えられていません。将棋、囲碁などのゲームで有名なのはこの強化学習です。


#教師あり学習のコードを書いてみる
まずは教師あり学習をやってみたいと思います。

教師あり学習はカテゴリー分けである分類と、数量を扱う回帰に分けられます。
今回はデータセットとしてボストンの住宅価格を予測（回帰）するプログラミングを書いてみましょう。実行環境はPython3.7(Anaconda on Windows)です。

##重回帰分析
まずは教師あり学習のうち、最も基本的な重回帰分析を実装してみます。

###データの読み込み
```.py
#モジュールのインポート
from sklearn.datasets import load_boston
import pandas as pd
from scipy import stats
from sklearn import linear_model
from sklearn.model_selection import train_test_split

#データをデータフレームへ入れる
boston=load_boston()
df_boston=pd.DataFrame(boston.data,columns=boston.feature_names)
df_boston.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554003/aa124f73-6613-150b-8846-8bc5d3d34717.png)

説明変数の意味は次の通りです。

|略称  |意味  |
|---|---|
|CRIM|犯罪発生率|
|ZN|住居区画の密集度|
|INDUS|	非小売業の土地割合|
|CHAS|	チャールズ川 (1: 川の周辺, 0: それ以外)|
|NOX|	NOx濃度|
|RM|	平均部屋数|
|AGE|	1940年より前に建てられた物件割合|
|DIS|	5つのボストン市の雇用施設からの重み付き距離|
|RAD|	大きな道路へのアクセスしやすさ|
|TAX|	$10,000ドルあたりの所得税率|
|PTRATIO|	教師あたりの生徒数|
|B|黒人の比率 1000(Bk – 0.63)^2|
|LSTAT|	低所得者の割合 |

実はboston.dataの中には目的変数であるPRICEが入っていません。
boston.targetという別のファイルから取ってくる必要があります。

```.py
df_boston["PRICE"] = pd.DataFrame(boston.target)
df_boston.head()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554003/eb4f9be3-6ded-6893-adca-833985060e2c.png)

今度はちゃんとPRICEも入っていますね。

###標準化した上で重回帰分析をする
今回はデータを標準化することにします。説明変数によって値の大きさがバラバラであり、そのままでは回帰係数直接比較できないからです。

※標準化...説明変数ごとに平均が0、標準偏差が1となるように値を再計算すること

```.py
#標準化
df_boston = df_boston.apply(stats.zscore, axis=0)

#学習データとテストデータを分ける
train,test = train_test_split(df_boston,test_size=0.2,random_state=100)
X_train = train.drop("PRICE", 1)
Y_train = train.PRICE
X_test = test.drop("PRICE",1)
Y_test = test.PRICE

clf = linear_model.LinearRegression()
clf.fit(X_train,Y_train)


#標準化偏回帰係数を表示
df_result = pd.DataFrame({"Name":X.columns,"Coef":clf.coef_})
df_result.sort_values("Coef",ascending=False)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554003/1281daa8-0e01-c9bd-4540-fdfd2bd61cb4.png)

この標準化偏回帰係数は、今回の重回帰において得られたモデルに対し、各説明変数が1変化したときの目的変数の変化量を示します。
"RM:平均部屋数"の係数が最も大きく、"LSTAT:低所得者の割合"の係数が最も小さくなりました。
直感ともマッチしていますね。

###テストデータでモデルを検証
```.py
#決定係数を表示
clf.score(X_test,Y_test)
0.7555033086871294
```
説明変数が13個もある割に0.76という数値はそれなりでしょうか。
具体的な予測値も見てみましょう。

```.py
#matplotlib inline
import matplotlib.pyplot as plt
Y_train_pred = clf.predict(X_train)
Y_test_pred = clf.predict(X_test)

plt.figure(figsize=(5,5))
plt.scatter(Y_test,clf.predict(X_test))
plt.xlabel("test_data",size=15)
plt.ylabel("prediction",size=15)
plt.xlim(-2.2,3.2)
plt.ylim(-2.2,3.2)
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554003/0a9a7e71-8185-1f6c-d532-0a10c298fd55.png)


うーん、良く当たっているのもあればそうでないのもありますね。特にtest_data=3付近の大きな値をうまく予測できていないようです。

他にも見るところはあるのですが、今回の重回帰分析はここまでにしましょう。

##決定木によるモデル構築
重回帰分析はExcelでもできてしまうのであまりありがたみがないですよね（失礼）。
せっかくなので教師あり機械学習で良く用いられる決定木を使ったモデルを構築してみましょう。

###決定木とは
決定木とは木構造を用いて分類や回帰を行う機械学習の手法の一つです。
モデルとしては
・RandomForest
・XGBoost
・LightGBM
などがあります。今回はXGBoostを使ってみます。


```.py
#モジュールのインポート
import xgboost as xgb
from sklearn.model_selection import GridSearchCV
params = {"learning_rate":[0.1,0.3],
        "max_depth": [2,3,5],
         "subsample":[0.8,0.9,1],
         "colsample_bytree": [0.5,1.0],
         }
model = xgb.XGBRegressor(objective="reg:squarederror")
cv = GridSearchCV(model,params,cv=10)
cv.fit(X_train,Y_train)

#決定係数を表示
cv.score(X_test,Y_test)
0.8842850742314474
```
重回帰分析よりも高い決定係数が得られました。決定係数よりもMSEで表す方が適切かも知れませんが。

```.py
Y_train_pred = cv.predict(X_train)
Y_test_pred = cv.predict(X_test)

plt.figure(figsize=(5,5))
plt.scatter(Y_test,clf.predict(X_test),label="MRA")
plt.scatter(Y_test,Y_test_pred,label="XGB")
plt.xlabel("test_data",size=15)
plt.ylabel("prediction",size=15)
plt.legend()
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554003/f214eb4e-b616-82ff-9bd4-6a8492216e96.png)

重回帰分析（MRA）と比較しました。散布図でもXGBoostの精度の高さが良く分かります。
重回帰分析でもXGBoostでも似たようなずれ方をしているデータがあるので、今回扱った特徴量以外の要因も効いている可能性がありそうです。

第一回はここまでで、次回は様々な決定木のモデルで分類問題を解いてみたいと思います。