半歩ずつ進める機械学習　～scikit-learnボストン住宅価格編～⑥

##前回まで
[前回の投稿][1]でアンサンブル学習について学びました
ボストン住宅価格の分析は[第5回][2]をまでやったので
今回は今まで学んだ回帰モデルを使って、住宅価格の予測を行い
各モデルの性能の比較等を行い、最もスコアの高いモデルを探したいと思います。
また、これ以上モデル精度を向上させようと思うと、新たな説明変数を作り出したり
特徴量エンジニアリングなど深い考察が必要になってくると思うので
ボストン住宅価格予測のシリーズは一旦今回で終了とします。

##前準備
データセットの準備を行います

```python3
from sklearn.datasets import load_boston
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
import optuna
from sklearn.metrics import r2_score
import pandas as pd

#データをロード
boston = load_boston()
#説明変数（特徴量）
env_data = pd.DataFrame(boston.data,columns = boston.feature_names)
#目的変数
price_data = boston.target
#標準化の為のスケーラー
sc = preprocessing.StandardScaler()

#トレーニングデータとテストデータに8:2で分割
train_x,test_x,train_y,test_y = train_test_split(env_data,price_data,train_size=0.8,random_state = 1)
#説明変数のデータを標準化（トレーニング・テスト共に）
train_z = sc.fit_transform(train_x)
test_z = sc.transform(test_x)
```

今回は、適当に抜き出した20%のテストデータに対する精度を比較します
尚、評価指標は**R2(決定係数）**で、各モデルの最適なパラメータは**Optuna**を使用して探索します。

##スコアの比較
まず[こちらの投稿][3]でも使用した線形回帰モデル

+ LinearRegression
+ RidgeRegression
+ LassoRegression
+ ElasticNet

の4種を試します。

最初なんでOptunaでパラメータを探索するコードも一応載せておきます。

```python3
def objective(trial):
    param_alpha = trial.suggest_loguniform("alpha",0.01,0.99)
    rg = Ridge(alpha = param_alpha)
    rg.fit(train_z,train_y)
    y_pred = rg.predict(test_z)
    return -r2_score(test_y,y_pred)

study.optimize(objective,n_trials=100)
```

これでOptunaが100回色んなパラメータを試して、最もいい結果を教えてくれます。
同様にLassoとElasticNetでも、調整が必要なパラメータをOptunaで探索して、モデルを作った結果が以下の通りです。
※LinearRegressionはパラメータ調整不要です。

```Python3
#LinearRegressionのスコアと回帰係数
0.7634174432138474
[-1.02670073  1.35041325  0.12557673  0.57522815 -2.28609206  2.13083882
  0.12702443 -3.17856741  2.64730569 -1.87781254 -2.14296387  0.6693739
 -3.92551025]

#Ridgeの最適なパラメータとスコアと回帰係数
{'alpha': 0.25656679388194054}
0.7634194135089943
[-1.0237994   1.34354031  0.11764531  0.57630209 -2.27619676  2.13460282
  0.12424175 -3.16811722  2.6219629  -1.85414075 -2.14044692  0.66931952
 -3.92023612]

#Lasso
{'alpha': 0.010047112511124178}
0.7631170706450768
[-0.99831839  1.29174495  0.0293067   0.5775133  -2.20104366  2.14914265
  0.0814358  -3.131492    2.44517928 -1.6796851  -2.12150588  0.65885479
 -3.90137101]

#ElasticNet
{'alpha': 0.010084492155669412, 'l1_ratio': 0.4619694446057495}
0.7631062567225662
[-0.99066052  1.26917972  0.02116619  0.58431576 -2.16642431  2.16897669
  0.08409038 -3.070708    2.35999211 -1.6083605  -2.11246275  0.66417315
 -3.87096163]

```

当たり前の事かもしれませんが、どれも殆ど変わりませんね
LinearRegressionを汎化させたモデルなんで、半分以上外れ値とかいう変な訓練データでなければ
多重共線性を考慮しない場合、R2スコアがLinear以上になる事は多分ないです
（そんな事ないぞ！って場合はご指摘お願いします...)

次はSVRです。

```python3
#SVRのスコアとパラメータ
{'C': 29.66829387885759, 'epsilon': 2.671890919549504}
0.9361811123936056
```

CはSVRの正則化項の強度を調整するパラメータです（高い程正則化の強度が弱くなる）
OptunaでのCの探索範囲を1-30にしてるんですが、ほぼ上限に張り付いてます
スコアもかなり高いんで、過学習が起きてる気がします

次にXGBoostを試しました

```python3
#xgboost
{'max_depth': 25, 'learning_rate': 0.33418368822954464}
0.9314838487998569
```

探索したパラメータは2個だけですが、SVR同様かなり高いスコアが出ています。

##結果
雑にスコアだけを掲載しましたが、やはりSVRとXGBoostなど非線形モデルで高いスコアが出ましたが
表現力の高さ故、過学習には注意が必要かと思います

今までの投稿のスコアを纏めただけなんで、改めて投稿する程でもありませんが
一旦シメる為に投稿しました。

次回以降は、scikit-learnの分類問題をやるか
Kaggleの適当なコンペに挑戦してみようと思います。

[1]:https://qiita.com/Mukomiz/items/ac5ce56b8eac43c6a43f
[2]:https://qiita.com/Mukomiz/items/f5c562ff8b538c1502d7
[3]:https://qiita.com/Mukomiz/items/450b6821cf31e6a0dbc6