sklearn.datasetsのload_bostonを用いた重回帰分析の練習

#さっそく初めていきたいと思います。

pythonのsklearn.datasetsの中には学習に適したデータセットが公開されています。

こちらで詳しくコードを書いて説明をしていきます。

ちなみに
![公式のサイト](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_boston.html?highlight=boston#sklearn.datasets.load_boston)はこちらです。

実際に手を動かす前に各変数の説明を載せておきます。

列名|説明|
|---|---|
CRIM|町ごとの一人あたりの犯罪率
ZN|宅地の比率が２５，０００平方フィートを超える敷地に区画されている。
INDUS|小売業の商業が占める面積の割合
CHAS|チャールズ川沿いかどうか。１→川の周辺　０→それ以外
NOX|窒素酸化物の濃度
RM|住居の平均部屋数
AGE|1940年より前に建てられた持ち主が住んでいる物件の割合
DIS|５つのボストン雇用施設からの重み付き距離
RAD|ラジアルハイウェイへのアクセス可能性の指標
TAX|10,000ドルあたりの税額固定資産税率
PTRATIO|生徒教師の比率
B|街における黒人の割合
LSTAT|人口あたり地位が低い割合

まず必要なライブラリを取り込んでいきます。
```python:in
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
```

さっそくデータセットを取り込んでいきます。
カラムにはデータセットのカラムをそのまま使おうと思います。
```python:in
from sklearn.datasets import load_boston
dataset = load_boston()
x, t = dataset.data, dataset.target
columns = dataset.feature_names
```

次にデータセットの確認をしていきましょう。
```python:in
type(x), x.shape, type(t), t.shape
```
```:out
(numpy.ndarray, (506, 13), numpy.ndarray, (506,)) 
```
データはNumPyのndarray型で格納されていることが確認できました。
また、x　とt　にはそれぞれ「506行１３列」と「５０６行１列」が格納されていることがわかるでしょうか。

格納されている型をDataFrame型に変換しましょう。
```python:in
df = pd.DataFrame(x, columns=columns)
df.head(3)
```
out
|CRIM	|ZN	|INDUS	|CHAS	|NOX	|RM	|AGE	|DIS	|RAD	|TAX	|PTRATIO	|B	|LSTAT
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|0	|0.00632	|18.0	|2.31	|0.0	|0.538	|6.575	|65.2	|4.0900	|1.0	|296.0	|15.3	|396.90	|4.98|
|1	|0.02731	|0.0	|7.07	|0.0	|0.469	|6.421	|78.9	|4.9671	|2.0	|242.0	|17.8	|396.90	|9.14
|2	|0.02729	|0.0	|7.07	|0.0	|0.469	|7.185	|61.1	|4.9671	|2.0	|242.0	|17.8	|392.83	|4.03


そしてdfにTargetというカラムを追加します。

```python:in
df['Target'] = t
df.head(3)
```

out
|CRIM	|ZN	|INDUS	|CHAS	|NOX	|RM	|AGE	|DIS	|RAD	|TAX	|PTRATIO	|B	|LSTAT |Target
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|0	|0.00632	|18.0	|2.31	|0.0	|0.538	|6.575	|65.2	|4.0900	|1.0	|296.0	|15.3	|396.90	|4.98| 24.6
|1	|0.02731	|0.0	|7.07	|0.0	|0.469	|6.421	|78.9	|4.9671	|2.0	|242.0	|17.8	|396.90	|9.14 |21.6
|2	|0.02729	|0.0	|7.07	|0.0	|0.469	|7.185	|61.1	|4.9671	|2.0	|242.0	|17.8	|392.83	|4.03 |34.7

Targetというカラムが追加されたのが確認できますでしょうか。

それではデータを分割するフェーズに移りたいと思います。

なぜこのようなことをするのかというと、過学習を防ぐためです。

例えば練習では高い精度で分析できても本番でそれが発揮できなきゃ意味がありません。
このような機能を汎化性能といいます。
これは機械学習の大きな課題ですので覚えておいて損はないワードです。

```python:in
from sklearn.model_selection import train_test_split
```

ここで関数が登場します。
sklearn.model/selection.train_test_split()
です。

以下ではxをx_train, x_test、tをt_train, t_testに分割しています。
```python:in
x_train, x_test, t_train, t_test = train_test_split(x, t, test_size=0.3, random_state=0)
```

ここではモデルをインポートしています。
次の行ではインスタンスが生成されています。
```python:in
from sklearn.linear_model import LinearRegression
model = LinearRegression()
```

モデルの学習をしています。
ここで入力値にx_train、目標値にt_trainが使用されていることに注目してください。
```python:in
model.fit(x_train, t_train)
```
出力結果です。
```python:out
LinearRegression()
```

重回帰分析では重みをw、バイアスをbとして表現していました。
ここで求まったwの値はmodel.coef_に。
バイアスbの値はmodel.intercept_に格納されています。

結果を見ていきます。
```python:in
model.coef_
```



学習後のwを見ていきましょう。
```python:out
model.coef_
array([-1.21310401e-01,  4.44664254e-02,  1.13416945e-02,  2.51124642e+00,
       -1.62312529e+01,  3.85906801e+00, -9.98516565e-03, -1.50026956e+00,
        2.42143466e-01, -1.10716124e-02, -1.01775264e+00,  6.81446545e-03,
       -4.86738066e-01])
```

可読性を上げるためにヒストグラムにしてみます。
```python:in
plt.figure(figsize=(10, 7))
plt.bar(x=columns, height=model.coef_)
```

out
![sklearn.datasetsを用いたload_boston_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728563/01e5bad7-ef9c-7ebe-5583-d4f2b976375a.png)

次に学習後のbを見ていきます。
```python:in
model.intercept_
```

```python:out
37.93710774183309
```

次に計算して求まった決定係数を見ていきましょう。
とりあえずは1に近いほど高精度という認識で良いでしょう。
```python:in
print('train score: ', model.score(x_train, t_train))
print('test score: ', model.score(x_test, t_test))
```
学習済みモデルを用いて学習用データセットで計算してみた結果(train score)はおおよそ0.76になりました。
また、テスト用データセット(test score)はおおよそ0.67という結果を示しました。
ここではtrain scoreがより大きい値を示していることがわかり、予測値と目標値に大きな差異が生まれていることがわかります。
これを過学習といいます。
```python:out
train score:  0.7645451026942549
test score:  0.6733825506400171
```

ここまでお疲れさまでした。
次で最後の操作となります。

最後に新たな入力値を与えて推論を行ってみましょう。
```python:in
y = model.predict(x_test)
```

predict()メソッドにテスト用データセットからサンプルをひとつ取り出してみましょう。
```python:in
print('予測値: ', y[0])
print('目標値: ', t_test[0])
```

ここでもわずかに予測値が目標値を上回っていることがわかりました。
```python:out
予測値:  24.935707898576915
目標値:  22.6
```