前回に引き続き、Udemy【世界で74万人が受講】基礎から理解し、Pythonで実装!機械学習26のアルゴリズムを理論と実践を通じてマスターしようで学んだ内容をアウトプットしていきたいと思います。
回帰(Regression)とは
回帰モデルは、あるデータ(独立変数)からある値(従属変数)を予測する際に使われます。
例:独立変数の年齢、階級から従属変数である給料を予測する。
ここでは、線形回帰(単回帰、重回帰)、多項式回帰、サポートベクトル回帰、回帰木、ランダムフォレストの手法を学んだ。
単回帰
単回帰とは、ざっくり言うと以下の式を作って独立変数$x$から従属変数$y$を求める手法です。もっとも当てはまりの良い直線を引くために最小二乗法を用いて$w_0$と$w_1$を算出します。
y = w_0 + w_1x
とりあえず、学んだ内容でScikit-learnのデータセットのボストン市の住宅価格を使って、RM(平均部屋数)を独立変数、MEDV(住宅価格)を従属変数として単回帰分析をしたいと思います。
単回帰は機械学習の中でも一番シンプルなので機械学習の流れを掴むのにはいいと思います。
ライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
データセットの読み込み
boston = load_boston()
boston_data = pd.DataFrame(boston.data, columns = boston.feature_names).assign(MEDV=np.array(boston.target))
独立変数Xと従属変数yの設定
X = boston_data[['RM']].values
y = boston_data['MEDV'].values
訓練用データセットとテスト用データセットへの分割(8:2)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)
訓練用データセットを使った学習
reg = LinearRegression()
reg.fit(X_train, y_train)
テスト用データセットを使った予測を実行し予測値とテスト用データセットの値を比較
y_pred = reg.predict(X_test)
np.set_printoptions(precision=2)
print(np.concatenate((y_pred.reshape(len(y_pred), 1), y_test.reshape(len(y_test), 1)), 1))
出力結果
[[22.9 22.6 ]
[21.81 50. ]
[23.28 23. ]
・・・
(省略)
・・・
[17.35 18.7 ]
[23.3 28.1 ]
[24.23 19.8 ]]
結果の可視化
plt.scatter(X_train, y_train, color = 'red', label='train_data')
plt.plot(X_train, reg.predict(X_train), color = 'blue', label='predict_data')
plt.title('RM vs MEDV')
plt.xlabel('RM')
plt.ylabel('MEDV')
plt.legend()
plt.show()
決定係数で回帰の当てはまりの良さを確認
r2_score(y_test, y_pred)
出力結果
0.42394386816456275
重回帰
重回帰とは、ざっくり言うと単回帰で扱った独立変数が1つから2つ以上に増えたもので、2つの場合でいうと独立変数$x_1$, $x_2$から従属変数$y$を求める手法です。単回帰は平面の図で表わせましたが、重回帰で独立変数が増えれば増えるほど高次元になっていくので図で表すのは不可能になってきます。
y = w_0 + w_1x_1 + w_2x_2・・・w_nx_n
また、線形回帰の前提として以下の5つの条件を満たさない場合は線形回帰を使うべきではないようです。
1.線形性
2.内生性がないこと
3.正規性と同分散性
4.自己相関がないこと
5.多重共線性がないこと
とりあえず、ここでも学んだ内容でScikit-learnのデータセットのボストン市の住宅価格を使って、MEDV(住宅価格)以外のデータすべてを独立変数、MEDV(住宅価格)を従属変数として重回帰分析をしたいと思います。
ライブラリのインポート
import numpy as np
import pandas as pd
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
データセットの読み込み
boston = load_boston()
boston_data = pd.DataFrame(boston.data, columns = boston.feature_names).assign(MEDV=np.array(boston.target))
X = boston_data.iloc[:, :-1].values
y = boston_data.iloc[:, -1].values
訓練用データとテスト用へデータセットの分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)
訓練用データを使ったモデルの訓練
reg = LinearRegression()
reg.fit(X_train, y_train)
テスト用データを使った結果の予測
y_pred = reg.predict(X_test)
np.set_printoptions(precision=2)
print(np.concatenate((y_pred.reshape(len(y_pred), 1), y_test.reshape(len(y_test), 1)), 1))
出力結果
[[24.89 22.6 ]
[23.72 50. ]
[29.36 23. ]
・・・
(省略)
・・・
[17.94 18.7 ]
[25.31 28.1 ]
[22.37 19.8 ]]
モデルの評価
r2_score(y_test, y_pred)
出力結果
0.5892223849182507
多項式回帰
その名の通り以下のような多項の式で回帰分析を行います。
y = w_0 + w_1x + w_2x^2
線形回帰の当てはまりが良くない時に使ったりするけど、直感的にデータを見て多項式回帰の方が当てはまりが良いとわかることは少ないようです。
とりあえず、ここでも学んだ内容でScikit-learnのデータセットのボストン市の住宅価格を使って、MEDV(住宅価格)以外のデータすべてを独立変数、MEDV(住宅価格)を従属変数として多項式分析を用いて回帰分析をしたいと思います。
ライブラリのインポート
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import r2_score
データセットの読み込み
boston = load_boston()
boston_data = pd.DataFrame(boston.data, columns = boston.feature_names).assign(MEDV=np.array(boston.target))
X = boston_data.iloc[:, :-1].values
y = boston_data.iloc[:, -1].values
訓練用データとテスト用へデータセットの分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)
訓練用データを使ったモデルの訓練
poly_reg = PolynomialFeatures(degree = 2)
X_poly = poly_reg.fit_transform(X_train)
reg = LinearRegression()
reg.fit(X_poly, y_train)
テスト用データを使った結果の予測
y_pred = reg.predict(poly_reg.transform(X_test))
np.set_printoptions(precision=2)
print(np.concatenate((y_pred.reshape(len(y_pred),1), y_test.reshape(len(y_test),1)),1))
出力結果
[[21.53 22.6 ]
[28.83 50. ]
[27.24 23. ]
・・・
(省略)
・・・
[15.17 18.7 ]
[25.74 28.1 ]
[19.24 19.8 ]]
モデルの評価
r2_score(y_test, y_pred)
出力結果
0.6903318065831567
サポートベクトル回帰
サポートベクトルとは線形を前提とした場合、まずはデータに対して当てはまりの良い直線を引く、その前後に平行な直線を引いてそこに乗るベクトルの事をサポートベクトルと呼ぶ。
当てはまりの良い線からサポートベクトルの距離ε(イプシロン)はハイパーパラメータでサポートベクトルマシンを使う際にこちらで指定する必要がある。
サポートベクトルによって支えられた直線の外にあるデータとの距離が最小になるような一番当てはまりの良い線を算出する。
具体的には以下の式が最小になるようにする。
C\sum\xi + \frac{1}{2} \begin{Vmatrix} w \end{Vmatrix}^2
それでは、ここでも学んだ内容でScikit-learnのデータセットのボストン市の住宅価格を使って、MEDV(住宅価格)以外のデータすべてを独立変数、MEDV(住宅価格)を従属変数としてサポートベクトル回帰を用いて回帰分析をしたいと思います。
ライブラリのインポート
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVR
from sklearn.metrics import r2_score
データセットの読み込み
boston = load_boston()
boston_data = pd.DataFrame(boston.data, columns = boston.feature_names).assign(MEDV=np.array(boston.target))
X = boston_data.iloc[:, :-1].values
y = boston_data.iloc[:, -1].values
y = y.reshape(len(y),1) # フィーチャースケーリングの為に変換
訓練用データとテスト用へデータセットの分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)
フィーチャースケーリング
sc_X = StandardScaler()
sc_y = StandardScaler()
X_train = sc_X.fit_transform(X_train)
y_train = sc_y.fit_transform(y_train)
訓練用データを使ったモデルの訓練
reg = SVR(kernel = 'rbf')
reg.fit(X_train, y_train)
テスト用データを使った結果の予測
y_pred = sc_y.inverse_transform(reg.predict(sc_X.transform(X_test)))
np.set_printoptions(precision=2)
print(np.concatenate((y_pred.reshape(len(y_pred),1), y_test.reshape(len(y_test),1)),1))
出力結果
[[23.93 22.6 ]
[21.53 50. ]
[25.11 23. ]
・・・
(省略)
・・・
[17.71 18.7 ]
[25.28 28.1 ]
[19.77 19.8 ]]
モデルの評価
r2_score(y_test, y_pred)
出力結果
0.6895937132707022
回帰木
まず、決定木(Decision Tree)とは以下のように条件分岐を繰り返すことで分類や回帰を行うモデルで回帰に使う場合を回帰木と言います。
回帰木の場合は下のグラフのように従属変数の最小2乗法で以下の式が最小になるように独立変数でグループ分けをする線を引く。
\sum(\hat{y}-y)^2
それでは、ここでも学んだ内容でScikit-learnのデータセットのボストン市の住宅価格を使って、MEDV(住宅価格)以外のデータすべてを独立変数、MEDV(住宅価格)を従属変数として回帰木を用いて回帰分析をしたいと思います。
ライブラリのインポート
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import r2_score
データセットの読み込み
boston = load_boston()
boston_data = pd.DataFrame(boston.data, columns = boston.feature_names).assign(MEDV=np.array(boston.target))
X = boston_data.iloc[:, :-1].values
y = boston_data.iloc[:, -1].values
訓練用データとテスト用へデータセットの分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)
訓練用データを使ったモデルの訓練
reg = DecisionTreeRegressor(random_state = 0)
reg.fit(X_train, y_train)
テスト用データを使った結果の予測
y_pred = reg.predict(X_test)
np.set_printoptions(precision=2)
print(np.concatenate((y_pred.reshape(len(y_pred),1), y_test.reshape(len(y_test),1)),1))
出力結果
[[23.7 22.6]
[20.8 50. ]
[20.6 23. ]
・・・
(省略)
・・・
[19.7 18.7]
[25. 28.1]
[20.1 19.8]]
モデルの評価
r2_score(y_test, y_pred)
出力結果
0.6019035496385025
ランダムフォレスト(回帰)
ランダムフォレストとは独立して学習させた多数の決定木を沢山重ねて、その中で多数決をとってどの値を用いるのかを決定することができる。
ランダムフォレストのパラメータとしては定木の本数があり多ければ多いほど性能が安定しますが、一方で学習時間や予測時間も増加していきます。
それでは、ここでも学んだ内容でScikit-learnのデータセットのボストン市の住宅価格を使って、MEDV(住宅価格)以外のデータすべてを独立変数、MEDV(住宅価格)を従属変数としてランダムフォレストを用いて回帰分析をしたいと思います。
ライブラリのインポート
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import r2_score
データセットの読み込み
boston = load_boston()
boston_data = pd.DataFrame(boston.data, columns = boston.feature_names).assign(MEDV=np.array(boston.target))
X = boston_data.iloc[:, :-1].values
y = boston_data.iloc[:, -1].values
訓練用データとテスト用へデータセットの分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)
訓練用データを使ったモデルの訓練
reg = RandomForestRegressor(n_estimators = 100, random_state = 0)
reg.fit(X_train, y_train)
テスト用データを使った結果の予測
y_pred = reg.predict(X_test)
np.set_printoptions(precision=2)
print(np.concatenate((y_pred.reshape(len(y_pred),1), y_test.reshape(len(y_test),1)),1))
出力結果
[[23.93 22.6 ]
[29.11 50. ]
[22.14 23. ]
・・・
(省略)
・・・
[18.91 18.7 ]
[23.72 28.1 ]
[20.35 19.8 ]]
モデルの評価
r2_score(y_test, y_pred)
出力結果
0.7734908201180223
回帰分析まとめ
モデル | 長所 | 短所 |
---|---|---|
線形回帰 | 特徴量の関係性がわかりやすい | 線形回帰の前提条件を満たさないと使えない |
多項式回帰 | 非線形の問題に対して良い当てはまりをする | 多項式の次数の設定次第で精度が変わる |
サポートベクトル回帰 | 適用が簡単で高い精度が出やすい | フィーチャースケーリング(標準化)が必要 |
回帰木 | 線形、非線形どちらでも使える | データ数が少ないと精度が低くなりがち |
ランダムフォレスト | 線形、非線形どちらでも使え、精度も高い | 使用する決定木の数を指定する必要があり、多くすると精度が高くなるが学習時間や予測時間も増加する |