重回帰分析サンプル(python)




#はじめに


機械学習を学ぶ際に、数学とpythonでの解析という2つの課題がある。

機械学習を学ぶにあたり、書店を回ると以下の__「三大勢力」__が存在する事に気が付く。

+ __プログラムに特化した書籍__
+ __理論の数学オンリーの書籍(+ソースコードもある場合もある)__
+ __数式もプログラムも一切使わない物語風の書籍__

上記の中で、比較的読みやすく、ソースコードも入っている下記の書籍から学習を
スタートした。
参考書籍：『最短コースでわかるディープラーニングの数学　赤石 雅典著』

機械学習＋pythonは色々なサンプルがあり、便利なライブラリを使って予測、
分類ができる反面、ソースを少し書き換えると動作しなかったりしたので、
注意しないといけない部分にコメントを記載している。

今回挑戦したのは、多重線形回帰。
書籍の付録のコードに変数とコメントを追加してみた。

```python

# 必要ライブラリの宣言
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt


# PDF出力用
from IPython.display import set_matplotlib_formats
set_matplotlib_formats('png', 'pdf')

from sklearn.datasets import load_boston
# 学習用データ準備
boston = load_boston()
# x_orgにboston.dataをytにboston.targetを定義
x_org, yt = boston.data, boston.target
# feather_namesにboston.feature_names(項目名)を定義
feature_names = boston.feature_names
# x_orgとytの次元数を表示
print('元データ', x_org.shape, yt.shape)
print('項目名: ', feature_names)

# データ絞り込み (項目 RMのみ)
x_data = x_org[:,feature_names == 'RM']
x_add = x_org[:,feature_names == 'DIS']
x_add2 = x_org[:,feature_names == 'LSTAT']
print('絞り込み後', x_data.shape)

# ダミー変数を追加 arr:配列,obj:データを入れる位置,value:データの値
# np.insert(arr,obj,value,axis)
# x_dataの先頭に要素1をもつデータを追加した行列をxとする
x = np.insert(x_data, 0, 1.0, axis=1)
x3 = np.hstack((x,x_add,x_add2))
print('ダミー変数追加後', x3.shape)

```



```python

# 入力データxの表示 (ダミー変数を含む)
print(x3.shape)
print(x3[:5,:])

# 正解データ yの表示
print(yt[:5])

# 散布図の表示
# matplotlib.pyplot.scatter:第一、第二引数は出力したいデータ、ｓ：散布図のマーカーの太さ
            
plt.scatter(x[:,1], yt, s=10, c='b')
plt.xlabel('ROOM', fontsize=14)
plt.ylabel('PRICE', fontsize=14)
plt.show()

# 予測関数 (1, x)の値から予測値ypを計算する
def pred(x, w):
    return(x @ w)
```

```python

# 初期化処理
# データ系列総数
M  = x3.shape[0]

# 入力データ次元数(ダミー変数を含む)
D = x3.shape[1]

# 繰り返し回数
iters = 50000

# 学習率
alpha = 0.01

# 重みベクトルの初期値 (すべての値を1にする)
w = np.ones(D)

# 評価結果記録用 (損失関数値のみ記録)
history = np.zeros((0,2))


```

```python

# 繰り返しループ
for k in range(iters):
    
    # 予測値の計算 
    yp = pred(x3, w)
    
    # 誤差の計算 
    yd = yp - yt
    
    # 勾配降下法の実装 
    w = w - alpha * (x3.T @ yd) / M
    
    # 学習曲線描画用データ計算、保存
    if ( k % 100 == 0):
        # 損失関数値の計算 
        loss = np.mean(yd ** 2) / 2
        # 計算結果の記録
        history = np.vstack((history, np.array([k, loss])))
        # 画面表示
        print( "iter = %d  loss = %f" % (k, loss))    
        print("w0 = %f w1= %f w2 = %f w3=%f" %(w[0],w[1],w[2],w[3]))

```

```python

# 初期化処理 (パラメータを適切な値に変更)

# データ系列総数
M  = x3.shape[0]

# 入力データ次元数(ダミー変数を含む)
D = x3.shape[1]

# 繰り返し回数
#iters = 50000
iters = 2000

# 学習率
#alpha = 0.01
alpha = 0.001

# 重みベクトルの初期値 (すべての値を1にする)
w = np.ones(D)

# 評価結果記録用 (損失関数値のみ記録)
history = np.zeros((0,2))

```

```python

# 繰り返しループ
for k in range(iters):
    
    # 予測値の計算 
    yp = pred(x3, w)
    
    # 誤差の計算 
    yd = yp - yt
    
    # 勾配降下法の実装 
    w = w - alpha * (x3.T @ yd) / M
    
    # 学習曲線描画用データの計算、保存
    if ( k % 100 == 0):
        # 損失関数値の計算
        loss = np.mean(yd ** 2) / 2
        # 計算結果の記録
        history = np.vstack((history, np.array([k, loss])))
        # 画面表示
        print( "iter = %d  loss = %f" % (k, loss)) 
        print("2:w0 = %f w1= %f w2 = %f w3= %f" %(w[0],w[1],w[2],w[3]))

```


```python

# 最終的な損失関数初期値、最終値
print('損失関数初期値: %f' % history[0,1])
print('損失関数最終値: %f' % history[-1,1])


# 学習曲線の表示 (最初の10個分を除く)
plt.plot(history[:,0], history[:,1])
plt.show()
```