次元削除 回帰分析

次元削減をすることで、説明変数の数を減らせます。それにより過学習を抑えられます。

ここでは、説明変数の数を減らしたときに、以下を確認します。

  • トレーニングデータの平均二乗誤差が大きくなる。
  • テストデータの平均二乗誤差の増加量は、トレーニングデータより小さい。

つまり、説明変数が少ないとトレーニングデータに比べてテストデータの性能が上がり、過学習が抑えられています。

%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といった有用な説明変数と、ノイズに近い説明変数が混じっています。

次元数を変えたときのトレーニングデータ(青い線)とテストデータ(オレンジの線)の平均二乗誤差をグラフで比較します。

次元削減をすると、情報量が減るのでトレーニングデータの平均二乗誤差は増えていきます。
テストデータの平均二乗誤差も増えていきますが、過学習が抑えられるので、増え方は緩やかになります。

コメント

タイトルとURLをコピーしました