【初心者】コピペでできるRidge・Lasso回帰

スポンサーリンク
Python

非エンジニアサラリーマンがお届けする、コピペでできる機械学習シリーズのRidge・Lasso回帰編です。XGBoostは機械学習のなかでも、非常に予測精度が高いです。Kaggleなどの機械学習のコンペでも多く用いられています。

問題解決にコードは最低限でいいと考えています。コードはコピーして、データ収集や結果の解釈に力を注いで下さい。だれでも、すぐに実践できるようにscikit-learnのデータセットを使います。また、自身のデータでもすぐにコピペできるように、scikit-learnのデータセットを一旦データフレームにしてから機械学習を実施していきます。

環境構築は、【2020年最新】Anacondaのインストール方法

それでは、やっていきましょう!

必要なライブラリ―をインポート

import pandas as pd
import numpy as np
from sklearn.datasets import load_boston
import matplotlib.pyplot as plt
import japanize_matplotlib
%matplotlib inline
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")

今回のデータセットはscikit-learnのデータセットにあるbostonを使用します。

データセットを整える

【超重要】はじめてのデータ収集方法

目的変数:住宅価格(の中央値)
説明変数:目的変数に関係しそうな、さまざまなデータ

boston = load_boston()
df = pd.DataFrame(data = boston.data, columns = boston.feature_names)
df['PRICE'] = boston.target
df

上のコードはデータフレームにするためのコードです。
bostonのデータセットで実践する場合は上のコードを実行して下さい。
自身のデータを使用する場合は、以下のコードから実行して下さい。

機械学習がしやすいデータの形に整える

X = df.iloc[:,:-1].values  # 説明変数(最後の列以外)
y = df.iloc[:,-1].values   # 目的変数(最後の列のみ)

訓練用のデータとテスト用のデータに分割する

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size = 0.25,
    random_state = 1)

説明変数を標準化する。

標準化とは、平均0、標準偏差1になるように数値を変換しておくこと。

標準化したほうが、精度が向上する場合があるための処理です。

Ridge回帰

from sklearn.linear_model import Ridge
from sklearn.model_selection import GridSearchCV

# グリッドサーチを行うためのパラメーター
param = [{'alpha': [0.01, 0.1, 1, 10, 100]
         }]

gs_ridge = GridSearchCV(estimator = Ridge(random_state=1), 
                  param_grid = param,
                  cv = 10,
                  n_jobs = -1)
gs_rideg = gs_ridge.fit(X_train_st, y_train)

# 裁量スコアとなるパラメータ値を出力
print(gs_ridge.best_params_)

出力:
{‘alpha’: 10}

alpha=10がもっとも精度が高かった。
これを使い、説明変数で、目的変数を予測する。

y_train_pred = gs_ridge.predict(X_train_st)
y_test_pred = gs_ridge.predict(X_test_st)

グラフを書いて、分かりやすく可視化する

plt.scatter(y_test, y_test_pred)
plt.xlabel('テストデータ')
plt.ylabel('予測データ')
plt.savefig('ridge_scatter.jpg')

出力:

以下のコードで、どの程度差があるかを可視化します。
赤線で示しているのが、差が0で予測と実際の値が一致してるということです。
すなわち、点が赤線に近い近いほうが予測精度が高いことが分かります。

plt.scatter(y_train_pred,  y_train_pred - y_train,
            c='steelblue', marker='o', edgecolor='white',
            label='訓練データ')
plt.scatter(y_test_pred,  y_test_pred - y_test,
            c='limegreen', marker='s', edgecolor='white',
            label='テストデータ')
plt.xlabel('予測値')
plt.ylabel('予測と正解との差')
plt.legend(loc='upper left')
plt.hlines(y=0, xmin=-10, xmax=50, color='r', lw=1.5, alpha=0.5)
plt.xlim([-10, 50])
plt.tight_layout()
plt.savefig('ridge_graph.jpg')
plt.show()

出力:

モデルの評価(Ridge回帰)

from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error

print('MSE  train: %.3f, test: %.3f' % (
        mean_squared_error(y_train, y_train_pred),
        mean_squared_error(y_test, y_test_pred)))
print('RMSE train: %.3f,  test: %.3f' %(
        np.sqrt(mean_squared_error(y_train, y_train_pred)),
        np.sqrt(mean_squared_error(y_test, y_test_pred))))
print('R^2  train: %.3f,  test: %.3f' % (
        r2_score(y_train, y_train_pred),
        r2_score(y_test, y_test_pred)))

出力:
MSE train: 22.612, test: 22.039
RMSE train: 4.755, test: 4.695
R^2 train: 0.715, test: 0.778

初心者のための回帰問題の評価指標

MSE:小さいほうが当てはまりがよい

RMSE:小さいほうが当てはまり良い

R²:1に近いほうが良い

訓練データ(train)と、テストデータ(test)で上の評価を実施する。

下のコードで、予測とテストの差をヒストグラムで可視化する。

一応、正規分布になっているほうが、いいとされています。

sns.distplot((y_test-y_test_pred),bins=50)
plt.savefig('ridge_residuals.jpg')

Lasso回帰

from sklearn.linear_model import Lasso
from sklearn.model_selection import GridSearchCV

# グリッドサーチを行うためのパラメーター
param = [{'alpha': [0.001, 0.01, 0.1, 1, 10]
         }]

gs_lasso = GridSearchCV(estimator = Lasso(random_state=1), 
                  param_grid = param,
                  cv = 10,
                  n_jobs = -1)
gs_lasso = gs_lasso.fit(X_train_st, y_train)

# 裁量スコアとなるパラメータ値を出力
print(gs_lasso.best_params_)

出力:
{‘alpha’: 0.01}

alpha=0.01がもっとも精度が高かった。
これを使い、説明変数で、目的変数を予測する。

y_train_pred = gs_lasso.predict(X_train_st)
y_test_pred = gs_lasso.predict(X_test_st)

グラフを書いて、分かりやすく可視化する

plt.scatter(y_test, y_test_pred)
plt.xlabel('テストデータ')
plt.ylabel('予測データ')
plt.savefig('lasso_scatter.jpg')

出力:

以下のコードで、どの程度差があるかを可視化します。
赤線で示しているのが、差が0で予測と実際の値が一致してるということです。
すなわち、点が赤線に近い近いほうが予測精度が高いことが分かります。

plt.scatter(y_train_pred,  y_train_pred - y_train,
            c='steelblue', marker='o', edgecolor='white',
            label='訓練データ')
plt.scatter(y_test_pred,  y_test_pred - y_test,
            c='limegreen', marker='s', edgecolor='white',
            label='テストデータ')
plt.xlabel('予測値')
plt.ylabel('予測と正解との差')
plt.legend(loc='upper left')
plt.hlines(y=0, xmin=-10, xmax=50, color='r', lw=1.5, alpha=0.5)
plt.xlim([-10, 50])
plt.tight_layout()
plt.savefig('lasso_graph.jpg')
plt.show()

出力:

モデルの評価(Lasso回帰)

from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error

print('MSE  train: %.3f, test: %.3f' % (
        mean_squared_error(y_train, y_train_pred),
        mean_squared_error(y_test, y_test_pred)))
print('RMSE train: %.3f,  test: %.3f' %(
        np.sqrt(mean_squared_error(y_train, y_train_pred)),
        np.sqrt(mean_squared_error(y_test, y_test_pred))))
print('R^2  train: %.3f,  test: %.3f' % (
        r2_score(y_train, y_train_pred),
        r2_score(y_test, y_test_pred)))

出力:
MSE train: 22.486, test: 21.915
RMSE train: 4.742, test: 4.681
R^2 train: 0.717, test: 0.779

MSE:小さいほうが当てはまりがよい

RMSE:小さいほうが当てはまり良い

R²:1に近いほうが良い

訓練データ(train)と、テストデータ(test)で上の評価を実施する。

下のコードで、予測とテストの差をヒストグラムで可視化する。

一応、正規分布になっているほうが、いいとされています。

sns.distplot((y_test-y_test_pred),bins=50)
plt.savefig('lasso_residuals.jpg')

Ridge回帰もLasso回帰も、ほとんど結果は分からなかったですね。まあ、両方とも似たような分析方法ですもんね。

以上です。






コメント

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