以下の状態を過学習といいます。
- トレーニングデータの評価値が良い
- テストデータの評価値が悪い
このクエストでは、下記の手法に対して、これらの評価値がどうなるのかを確認します。
- 線形回帰(
LinearRegression
) - Ridge回帰(
Ridge
) - サポートベクターマシン回帰(
SVR
) - ランダムフォレスト回帰(
RandomForestRegressor
)
まずは、線形回帰とRidge回帰を比較します。
%precision 3
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.metrics import mean_squared_error
np.random.seed(23)
M, N = 80, 32
# ダミーデータ
X = np.random.randn(M, N)
y = X.sum(1) * 0.4 + np.random.randn(M)
ダミーデータ(X, y)を使います。
過学習を避ける上で、説明変数の選択は重要です。ダミーデータの全説明変数は、目的変数と弱い相関があるので、説明変数の選択は済んでいることにします。
# トレーニングデータとテストデータの平均二乗誤差を計算
def calc_score(model):
lst1, lst2 = [], []
for i in range(20): # 20回の平均を取る
X_train, X_test, y_train, y_test = (
train_test_split(X, y, test_size=M//2, random_state=i))
model.fit(X_train, y_train)
lst1.append(mean_squared_error(y_train, model.predict(X_train)))
lst2.append(mean_squared_error(y_test, model.predict(X_test)))
score1 = np.mean(lst1)
score2 = np.mean(lst2)
return score1, score2
結果を入れるlst1, lst2を用意します
以下、20回繰り返します
トレーニングデータとテストデータを半々に分割します
modelを使って回帰します
lst1にトレーニングデータの平均二乗誤差を入れます。
lst2にテストデータの平均二乗誤差を入れます。
score1にlst1の平均を入れます。
score2にlst2の平均を入れます。
# 線形回帰のとき
model = LinearRegression()
score1, score2 = calc_score(model)
float(score1), float(score2) # トレーニングデータとテストデータの平均二乗誤差
(0.165, 10.038)
線形回帰のときは、(0.165, 10.038)
になり、テストデータの平均二乗誤差が大きいので、過学習しているといえます。
# Ridge回帰のとき
model = Ridge()
score3, score4 = calc_score(model)
float(score3), float(score4) # トレーニングデータとテストデータの平均二乗誤差
(0.195, 3.906)
Ridge回帰のときは、(0.195, 3.906)になり、テストデータの平均二乗誤差が小さくなっており、正則化の効果で汎化性能が高くなっています。
コメント