次元削減をすることで、説明変数の数を減らせます。それにより過学習を抑えられます。
ここでは、説明変数の数を減らしたときに、以下を確認します。
- トレーニングデータの平均二乗誤差が大きくなる。
- テストデータの平均二乗誤差の増加量は、トレーニングデータより小さい。
つまり、説明変数が少ないとトレーニングデータに比べてテストデータの性能が上がり、過学習が抑えられています。
%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.decomposition import PCA
df = pd.read_csv("input/boston.csv") # ボストン市の住宅価格データ一式
X, y = df.iloc[:, :-1], df.iloc[:, -1]
# 全説明変数のときの結果
X_train, X_test, y_train, y_test = (
train_test_split(X, y, test_size=len(y)//2, random_state=0))
lr = LinearRegression().fit(X_train, y_train)
score1 = mean_squared_error(y_train, lr.predict(X_train))
score2 = mean_squared_error(y_test, lr.predict(X_test))
score1, score2 # トレーニングデータとテストデータの平均二乗誤差
(19.628348663079148, 25.30166176584622)
# 次元削減の効果
res1, res2 = [], []
nums = [13, 11, 9, 7, 5, 3]
for num in nums:
X_pca = PCA(num, random_state=0).fit_transform(X)
X_train, X_test, y_train, y_test = (
train_test_split(X_pca, y, test_size=len(y)//2, random_state=0))
lr = LinearRegression().fit(X_train, y_train)
res1.append(mean_squared_error(y_train, lr.predict(X_train)))
res2.append(mean_squared_error(y_test, lr.predict(X_test)))
# グラフで比較
plt.xlabel('Number of explanatory variable')
plt.ylabel('Mean Squared Error')
plt.ylim((0, 70))
plt.xticks(range(len(nums)), nums)
plt.plot(res1, label='Training')
plt.plot(res2, label='Test')
plt.legend();
次元削減は、sklearn.decomposition.PCA
を使って、PCA(新しい次元数).fit_transform(元のデータ)
とするとできます。
ボストン市の住宅価格データでは、RM, PTRATIO, B, LSTAT
といった有用な説明変数と、ノイズに近い説明変数が混じっています。
次元数を変えたときのトレーニングデータ(青い線)とテストデータ(オレンジの線)の平均二乗誤差をグラフで比較します。
次元削減をすると、情報量が減るのでトレーニングデータの平均二乗誤差は増えていきます。
テストデータの平均二乗誤差も増えていきますが、過学習が抑えられるので、増え方は緩やかになります。
コメント