この記事ではscikit-learnを使った線形回帰モデルのサンプルを紹介します。
線形回帰とは回帰式を用いて、説明変数の値から目的変数を予測するモデルです。
まずは必要なライブラリをインポートします。
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
from sklearn.datasets import load_boston
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')
次に今回使用するデータをロードします。
今回使用するデータはscikit-learnのデータセットに入っているボストンの住宅価格のサンプルデータです。
data = load_boston()
読み込んだデータから特徴量と教師データを取り出します。
X = data.data
y = data.target
print(X.shape)
print(y.shape)
scikit-learnのtrain_test_splitを使って、トレーニングデータの一部を検証用データとして分けておきます。
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
特徴量をスケーリングします。
スケーリングはトレーニングデータと検証データを分けてからスケーリングするように気をつけましょう。
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_val_scaled = scaler.transform(X_val)
学習を実行します。
linear = LinearRegression()
linear.fit(X_train_scaled, y_train)
検証データで誤差を検証します。今回は平均2乗誤差を使います。
y_pred_train = linear.predict(X_train_scaled)
y_pred_val = linear.predict(X_val_scaled)
mse_train = mean_squared_error(y_train, y_pred_train)
mse_val = mean_squared_error(y_val, y_pred_val)
print('train mse: {}'.format(mse_train))
print('validation mse: {}'.format(mse_val))
結果は以下の通りです。
train mse: 21.641412753226312
validation mse: 24.291119474973517
L1正則化とL2正則化
scikit-learnにはL1正則化とL2正則化を行った線形回帰のモデルもあります。LassoとRidgeというクラスを使うと正則化が行えます。
使い方はLinearRegressionと同じで、コードは以下のようになります。
lasso = Lasso()
lasso.fit(X_train_scaled, y_train)
y_pred_train = lasso.predict(X_train_scaled)
y_pred_val = lasso.predict(X_val_scaled)
mse_train = mean_squared_error(y_train, y_pred_train)
mse_val = mean_squared_error(y_val, y_pred_val)
print('train mse: {}'.format(mse_train))
print('validation mse: {}'.format(mse_val))
train mse: 65.50687943535733
validation mse: 54.458243466391465
L1正則化を行うと説明変数の回帰係数に制約があるので、各説明変数の回帰係数が0に近づきます。
学習したモデルから回帰係数の値を確認してみます。
print(lasso.coef_)
[-0. 0. -0. 0. -0. 0.
-0. 0. -0. -0.85254537 -0. 0.
-8.25432563]
ほとんどの回帰係数が0になっていることがわかります。
L1正則化を使うとこのようにスパースな回帰係数になるので、変数選択を行う際にも使うことができます。
次に、L2正則化のリッジ回帰も同様です。
コードは以下のようになります。
ridge = Ridge()
ridge.fit(X_train_scaled, y_train)
モデルの精度を確認すると以下のようになります。
y_pred_train = ridge.predict(X_train_scaled)
y_pred_val = ridge.predict(X_val_scaled)
mse_train = mean_squared_error(y_train, y_pred_train)
mse_val = mean_squared_error(y_val, y_pred_val)
print('train mse: {}'.format(mse_train))
print('validation mse: {}'.format(mse_val))
train mse: 21.980328837907162
validation mse: 23.730076213059387
元々のLinearRegressionと比べて、トレーニングデータの誤差は大きくなりましたが、検証データの誤差は小さくなっています。
L2正則化によって、トレーニングデータに過剰に適合してしまう過学習が抑えられています。
この記事では、scikit-learnでの回帰モデルの構築方法を紹介しました。