機械学習ライブラリScikit-learn
前回、機械学習ライブラリScikit-learnのボストンの住宅価格を予想するのにデータを標準化、正規化をした後、LinearRegressionモデルで機械学習をしてみました。
今回は同じようにして標準化、正規化したデータを使って、Lassoモデル、ElasticNetモデルで機械学習を行ってみます。
まずはいつも通りデータの読み込みから。
<セル1>
from sklearn.datasets import load_boston
import pandas as pd
boston = load_boston()
df = pd.DataFrame(boston.data, columns=boston.feature_names)
df["MEDV"] = boston.target
df
実行結果
そしてデータを標準化と正規化をしていきます。
<セル2>
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler
x = df.loc[:, ["CRIM", "RM", "LSTAT"]]
y = df.loc[:, "MEDV"]
std_model = StandardScaler()
x_std = std_model.fit_transform(x)
norm_model = MinMaxScaler()
x_norm = norm_model.fit_transform(x)
実行結果
これで準備は完了です。
前回のプログラムを分かりやすく書き換える
前回、LinearRegressionモデルで標準化、正規化の効果を試したプログラムにLassoモデル、ElasticNetモデルを組み込んでいこうと思います。
<セル2>
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
import numpy as np
trial = 100
pred_lr_score = []; pred_std_lr_score =[]; pred_norm_lr_score = []
for i in range(trial):
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)
x_std_train, x_std_test, y_std_train, y_std_test = train_test_split(x_std, y, test_size=0.2, train_size=0.8)
x_norm_train, x_norm_test, y_norm_train, y_norm_test = train_test_split(x_norm, y, test_size=0.2, train_size=0.8)
model_lr = LinearRegression()
model_std_lr = LinearRegression()
model_norm_lr = LinearRegression()
model_lr.fit(x_train, y_train)
model_std_lr.fit(x_std_train, y_std_train)
model_norm_lr.fit(x_norm_train, y_norm_train)
pred_lr = model_lr.predict(x_test)
pred_std_lr = model_std_lr.predict(x_std_test)
pred_norm_lr = model_norm_lr.predict(x_norm_test)
pred_lr_score.append(r2_score(y_test, pred_lr))
pred_std_lr_score.append(r2_score(y_std_test, pred_std_lr))
pred_norm_lr_score.append(r2_score(y_norm_test, pred_norm_lr))
pred_lr_ave = np.average(np.array(pred_lr_score))
pred_std_lr_ave = np.average(np.array(pred_std_lr_score))
pred_norm_lr_ave = np.average(np.array(pred_norm_lr_score))
print(pred_lr_ave, pred_std_lr_ave, pred_norm_lr_ave)
実行結果
0.6251955895149124 0.6285481272482702 0.6384084236567933
ただ次々とモデルを組み込んでいくと、どこがどのモデルのプログラムか分からなくなるので、機械学習の部分を書き換えます。
どう書き換えるかというと、処理ごとで分割していたところを、モデルごとに分割するという感じで書き換えます。
ということでこの部分を、
model_lr = LinearRegression()
model_std_lr = LinearRegression()
model_norm_lr = LinearRegression()
model_lr.fit(x_train, y_train)
model_std_lr.fit(x_std_train, y_std_train)
model_norm_lr.fit(x_norm_train, y_norm_train)
pred_lr = model_lr.predict(x_test)
pred_std_lr = model_std_lr.predict(x_std_test)
pred_norm_lr = model_norm_lr.predict(x_norm_test)
pred_lr_score.append(r2_score(y_test, pred_lr))
pred_std_lr_score.append(r2_score(y_std_test, pred_std_lr))
pred_norm_lr_score.append(r2_score(y_norm_test, pred_norm_lr))
こう書き換えます。
model_lr = LinearRegression()
model_lr.fit(x_train, y_train)
pred_lr = model_lr.predict(x_test)
pred_lr_score.append(r2_score(y_test, pred_lr))
model_std_lr = LinearRegression()
model_std_lr.fit(x_std_train, y_std_train)
pred_std_lr = model_std_lr.predict(x_std_test)
pred_std_lr_score.append(r2_score(y_std_test, pred_std_lr))
model_norm_lr = LinearRegression()
model_norm_lr.fit(x_norm_train, y_norm_train)
pred_norm_lr = model_norm_lr.predict(x_norm_test)
pred_norm_lr_score.append(r2_score(y_norm_test, pred_norm_lr))
これにより一つの段落が一つのモデルの処理になり、後で分かりやすくなります。
Lassoモデル、ElasticNetモデルを組み込む
ではLassoモデル、ElasticNetモデルを組み込んでいきましょう。
追加するライブラリはモデルの2つ。
from sklearn.linear_model import Lasso
from sklearn.linear_model import ElasticNet
そして後はLassoモデルの処理とElasticNetモデルの処理を追加していきます。
まずはLassoモデルの処理から。
model_lasso = Lasso()
model_lasso.fit(x_train, y_train)
pred_lasso = model_lasso.predict(x_test)
pred_lasso_score.append(r2_score(y_test, pred_lasso))
model_std_lasso = Lasso()
model_std_lasso.fit(x_std_train, y_std_train)
pred_std_lasso = model_std_lasso.predict(x_std_test)
pred_std_lasso_score.append(r2_score(y_std_test, pred_std_lasso))
model_norm_lasso = Lasso()
model_norm_lasso.fit(x_norm_train, y_norm_train)
pred_norm_lasso = model_norm_lasso.predict(x_norm_test)
pred_norm_lasso_score.append(r2_score(y_norm_test, pred_norm_lasso))
次にElasticNetモデルの処理。
model_en = ElasticNet()
model_en.fit(x_train, y_train)
pred_en = model_en.predict(x_test)
pred_en_score.append(r2_score(y_test, pred_en))
model_std_en = ElasticNet()
model_std_en.fit(x_std_train, y_std_train)
pred_std_en = model_std_en.predict(x_std_test)
pred_std_en_score.append(r2_score(y_std_test, pred_std_en))
model_norm_en = ElasticNet()
model_norm_en.fit(x_norm_train, y_norm_train)
pred_norm_en = model_norm_en.predict(x_norm_test)
pred_norm_en_score.append(r2_score(y_norm_test, pred_norm_en))
どちらも最初の段落が何もしていないデータ、2段目が標準化したデータ、3段目が正規化したデータでの処理です。
後は平均値の計算、表示を加えるとこんな感じになります。
<セル3>
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.linear_model import ElasticNet
from sklearn.metrics import r2_score
import numpy as np
trial = 100
pred_lr_score = []; pred_std_lr_score =[]; pred_norm_lr_score = []
pred_lasso_score = []; pred_std_lasso_score = []; pred_norm_lasso_score = []
pred_en_score = []; pred_std_en_score = []; pred_norm_en_score = []
for i in range(trial):
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)
x_std_train, x_std_test, y_std_train, y_std_test = train_test_split(x_std, y, test_size=0.2, train_size=0.8)
x_norm_train, x_norm_test, y_norm_train, y_norm_test = train_test_split(x_norm, y, test_size=0.2, train_size=0.8)
model_lr = LinearRegression()
model_lr.fit(x_train, y_train)
pred_lr = model_lr.predict(x_test)
pred_lr_score.append(r2_score(y_test, pred_lr))
model_std_lr = LinearRegression()
model_std_lr.fit(x_std_train, y_std_train)
pred_std_lr = model_std_lr.predict(x_std_test)
pred_std_lr_score.append(r2_score(y_std_test, pred_std_lr))
model_norm_lr = LinearRegression()
model_norm_lr.fit(x_norm_train, y_norm_train)
pred_norm_lr = model_norm_lr.predict(x_norm_test)
pred_norm_lr_score.append(r2_score(y_norm_test, pred_norm_lr))
model_lasso = Lasso()
model_lasso.fit(x_train, y_train)
pred_lasso = model_lasso.predict(x_test)
pred_lasso_score.append(r2_score(y_test, pred_lasso))
model_std_lasso = Lasso()
model_std_lasso.fit(x_std_train, y_std_train)
pred_std_lasso = model_std_lasso.predict(x_std_test)
pred_std_lasso_score.append(r2_score(y_std_test, pred_std_lasso))
model_norm_lasso = Lasso()
model_norm_lasso.fit(x_norm_train, y_norm_train)
pred_norm_lasso = model_norm_lasso.predict(x_norm_test)
pred_norm_lasso_score.append(r2_score(y_norm_test, pred_norm_lasso))
model_en = ElasticNet()
model_en.fit(x_train, y_train)
pred_en = model_en.predict(x_test)
pred_en_score.append(r2_score(y_test, pred_en))
model_std_en = ElasticNet()
model_std_en.fit(x_std_train, y_std_train)
pred_std_en = model_std_en.predict(x_std_test)
pred_std_en_score.append(r2_score(y_std_test, pred_std_en))
model_norm_en = ElasticNet()
model_norm_en.fit(x_norm_train, y_norm_train)
pred_norm_en = model_norm_en.predict(x_norm_test)
pred_norm_en_score.append(r2_score(y_norm_test, pred_norm_en))
pred_lr_ave = np.average(np.array(pred_lr_score))
pred_std_lr_ave = np.average(np.array(pred_std_lr_score))
pred_norm_lr_ave = np.average(np.array(pred_norm_lr_score))
pred_lasso_ave = np.average(np.array(pred_lasso_score))
pred_std_lasso_ave = np.average(np.array(pred_std_lasso_score))
pred_norm_lasso_ave = np.average(np.array(pred_norm_lasso_score))
pred_en_ave = np.average(np.array(pred_en_score))
pred_std_en_ave = np.average(np.array(pred_std_en_score))
pred_norm_en_ave = np.average(np.array(pred_norm_en_score))
print(pred_lr_ave, pred_std_lr_ave, pred_norm_lr_ave, pred_lasso_ave, pred_std_lasso_ave, pred_norm_lasso_ave, pred_en_ave, pred_std_en_ave, pred_norm_en_ave)
実行結果
0.6271352730578258 0.6273988042003288 0.6430302631752858 0.5924658782746538 0.6107730695970007 0.23101389811233983 0.5773827966016526 0.5853423422079327 0.04969310466296231
なかなか膨大なプログラムになってきましたが、とりあえず今回はこのままいきましょう。
Lassoモデル、ElasticNetモデルに対する標準化、正規化の効果を見てみる
それではプログラムも完成したということで、Lassoモデル、ElasticNetモデルに対する標準化、正規化の効果を検討してみましょう。
いつも通りプログラムで100回試行して平均値を出し、それを5回試してみます。
モデル | 標準化 or 正規化 | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 |
LinearRegression | なし | 0.62714 | 0.63841 | 0.63594 | 0.63024 | 0.61714 |
LinearRegression | 標準化 | 0.62740 | 0.63155 | 0.62762 | 0.64076 | 0.63498 |
LinearRegression | 正規化 | 0.64303 | 0.63157 | 0.63321 | 0.63313 | 0.62717 |
Lasso | なし | 0.59247 | 0.59687 | 0.60009 | 0.60384 | 0.58902 |
Lasso | 標準化 | 0.61077 | 0.61412 | 0.60935 | 0.62000 | 0.61583 |
Lasso | 正規化 | 0.23101 | 0.22544 | 0.22842 | 0.22991 | 0.23005 |
ElasticNet | なし | 0.57738 | 0.58206 | 0.58518 | 0.58932 | 0.57585 |
ElasticNet | 標準化 | 0.58534 | 0.58697 | 0.58370 | 0.59413 | 0.58964 |
ElasticNet | 正規化 | 0.04969 | 0.04909 | 0.04860 | 0.04642 | 0.04938 |
さぁわかりにくいですね。
表をそれぞれのモデルに分割して、さらにそれぞれの回で良くなったものを青色で、悪くなったものを赤色にしてみましょう。
まずはLinearRegressionから。
モデル | 標準化 or 正規化 | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 |
LinearRegression | なし | 0.62714 | 0.63841 | 0.63594 | 0.63024 | 0.61714 |
LinearRegression | 標準化 | 0.62740 | 0.63155 | 0.62762 | 0.64076 | 0.63498 |
LinearRegression | 正規化 | 0.64303 | 0.63157 | 0.63321 | 0.63313 | 0.62717 |
何もしない vs 標準化 では2:3でわずかに標準化した方がいい。
何もしない vs 正規化 ではこちらも2:3でわずかに正規化した方がいい。
といっても本当にわずかな差なので、前回の結論通りほぼ結果は変わっていないと言っていいでしょう。
次にLassoモデル。
モデル | 標準化 or 正規化 | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 |
Lasso | なし | 0.59247 | 0.59687 | 0.60009 | 0.60384 | 0.58902 |
Lasso | 標準化 | 0.61077 | 0.61412 | 0.60935 | 0.62000 | 0.61583 |
Lasso | 正規化 | 0.23101 | 0.22544 | 0.22842 | 0.22991 | 0.23005 |
何もしない vs 標準化 では0:5で標準化した方がいい。
何もしない vs 正規化 では5:0で何もしない方がいい。
標準化に関しては、ここまで差が出てくれるなら間違いなく良くなっていると感じられます。
ただ正規化に関しては、どこかでプログラムを間違えたんじゃないかというくらい結果が悪くなっています。
Lassoモデルと正規化は相性が悪いのでしょうか?
ちゃんとした知識がないと答えるのが難しいところだと思いますので、とりあえず放置ということで。
次にElasticNetモデル。
モデル | 標準化 or 正規化 | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 |
ElasticNet | なし | 0.57738 | 0.58206 | 0.58518 | 0.58932 | 0.57585 |
ElasticNet | 標準化 | 0.58534 | 0.58697 | 0.58370 | 0.59413 | 0.58964 |
ElasticNet | 正規化 | 0.04969 | 0.04909 | 0.04860 | 0.04642 | 0.04938 |
何もしない vs 標準化 では 1:4で標準化した方がいい。
何もしない vs 正規化 では 5:0で何もしない方がいい。
ということでElasticNetモデルでは、標準化するとわずかによい感じがしますが、正規化すると全くダメになってしまいました。
こちらも原因を究明するには、ちゃんとした知識がないと難しいのではないかと感じます。
現段階では漠然とした知識で進めているのですが、こういうものなんだという感覚を養った後に知識をインプットしたときに入りやすいので、とりあえずこのまま進めていきます。
ということで今回の結果としては、
- Lassoモデルで標準化すると精度は良くなる。
- LassoモデルでもElasticNetモデルでも正規化は全く予想がうまくいかなくなった。
ということでした。
次回はさらにRidgeRegression、SVRで同じように標準化、正規化を試していきましょう。
ではでは今回はこんな感じで。
コメント