【初心者でも簡単】Pythonのscikit-learnで重回帰分析

Python
この記事は約9分で読めます。

Pythonのscikit-learnライブラリを使って重回帰モデルを作成する方法をご紹介します。今回はモデルによる予測の考え方についても少し触れています。

なお、重回帰分析の概要が知りたい方は「【Rで実践】初心者でもできる重回帰分析」をご参照ください。

スポンサーリンク

データセットの準備

データセットはscikit-learnライブラリに付属している「ボストン市の住宅価格データ」を使います。

import pandas as pd #データ加工に便利な機能が詰まったパッケージ
from sklearn.datasets import load_boston #ボストンデータを読み込むためのパッケージ

# ボストン市の住宅価格データの読み込み
dataset = load_boston()
# データフレームに変換
df = pd.DataFrame(dataset.data, columns=dataset.feature_names)#説明変数
df['MEDV_PRICE'] = dataset.target #目的変数を追加
df.head()

pandasはデータを加工するのに便利な機能をたくさん持っているライブラリです。

load_bosutonで読み込んだデータをpandasによってデータフレームに変換します。データフレームとは行列型のデータのことです。行列にすることで、特定の行と列に対してデータの抽出や加工ができるようになります。head()メソッドにより、データフレームの先頭5行を表示することができます。

ここで、左端の行番号に注目してください。0から始まっていることが分かります。

Pythonの行番号や列番号は0から始まることに注意です。(ちなみにデータ分析系言語のRでは1から始まります。)

データフレームの構造(何行何列か)は次のようにshapeを使用することで確認できます。

df.shape #データフレームの構造を確認
(506, 14)

上のコードを実行すると、(506, 14)が出力されます。これは、データフレームdfが506行、14列であることを意味しています。

スポンサーリンク

データの可視化

Pythonで可視化するにはmatplotlibライブラリが便利です。

目的変数の分布

目的変数の住宅価格の分布をヒストグラムで確認してみましょう。matplotlibでヒストグラムを作成するコード例は次の通りです。

#価格のヒストグラム
import matplotlib.pyplot as plt #matplotlibのインポート
plt.hist(dataset.target) #目的変数(住宅価格)のヒストグラム作成

plt.xlabel('Price in $1,000s') #横軸のラベル指定
plt.ylabel('Number of houses') #縦軸のラベル指定
plt.grid() #グリッドの表示

ヒストグラムから20[千ドル]近辺のデータが最も多いことが読み取れます。

相関分析

続いて、目的変数と説明変数の散布図を作成し、相関関係を確認していきます。

まずは変数すべての組み合わせの相関係数を確認するために、相関行列を作成します。

目的変数と説明変数の相関を確認しやすくするために、目的変数「MEDV_PRICE」を先頭列に移動してから、相関行列を作成します。

#目的変数MEDV_PRICEを先頭列に移動(別にやらなくても問題ないです)
cols = df.columns.tolist()
cols = cols[-1:] + cols[:-1]
df = df[cols]

#相関行列
df.corr()

相関行列の結果から、MEDV_PRICEに対する相関係数が大きいのはRM、LSTATだということが分かります。これらの相関関係を散布図で可視化してみましょう。

MEDV_PRICE VS.  RM (相関係数:0.69536)

# RM(平均部屋数)とMEDV_PRICE(住宅価格)の散布図
plt.scatter(df['RM'], df['MEDV_PRICE'])

plt.xlabel('Average number of rooms [RM]') # X軸
plt.ylabel('Median Prices')
plt.grid()

散布図からRMが高いほど、MEDV_PRICEが高いことが読み取れます。

MEDV_PRICE VS. LSTAT (相関係数:-0.737663)

# LSTAT(給与の低い仕事に従事する人口の割合)と住宅価格の散布図
plt.scatter(df['LSTAT'], df['MEDV_PRICE'])

plt.xlabel('Average number of rooms [LSTAT]') # X軸
plt.ylabel('Median Prices')
plt.grid()

散布図からLSTATが高いほど、MEDV_PRICEが低いことが読み取れます。

以上のことから、今回の重回帰モデル作成では相関が高いRMとLSTATを説明変数に設定します。

スポンサーリンク

データの分割

今回は予測を行うのでデータセットを訓練データとテストデータに分割し、テストデータで予測モデルの汎化性能を確認していきます。汎化性能とは未知のデータ(訓練に使用していないデータ)に対する予測精度の良さです。

データを分割をする前にNumpyライブラリで配列を作成しておきます。Numpyで作成した配列は機械学習ライブラリのscikit-learnとの親和性が高いです。

import numpy as np

# 説明変数X:平均部屋数、給与の低い仕事に従事する人口の割合|目的変数y:住宅価格
X = df.loc[:,["RM","LSTAT"]] #RM列とLSTAT列のみを抽出
y = df["MEDV_PRICE"]
# 配列の作成
X = np.array(X).reshape(-1, 2)#-1を使用すると、元の要素数に合わせて自動で適切な値が設定されます。
y = np.array(y).reshape(-1, 1)

scikit-learnライブラリのtrain_test_splitメソッドを使用すれば、簡単にデータを訓練データとテストデータに分割できます。今回は訓練データとテストデータを7:3の割合で分割します。

# 訓練データ:テストデータ=7:3に分割
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
スポンサーリンク

重回帰モデルの作成

データの準備ができたのでいよいよ重回帰モデルの作成です。重回帰モデルはscikit-learnライブラリのLinearRegressionメソッドで作成できます。

# モデルの学習
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train, y_train) #訓練データで学習(最小二乗法でパラメータを決定)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)
スポンサーリンク

モデルの評価

上で作成した重回帰モデルに対して、訓練データとテストデータのそれぞれで予測精度を評価していきます。今回は、平均二乗誤差(MSE)と決定係数の2つ指標で予測精度を評価します。

テスト時の予測精度が訓練時に比べて、悪化している場合は汎化性能(未知のデータに対する予測精度)が悪い可能性があり、注意が必要です。このような現象を過学習(オーバーフィッティング)と呼びます。過学習の対策としては、学習時のサンプル数を増やしたり、説明変数の数を削減するなどの方法があります。

平均二乗誤差

平均二乗誤差(MSE:Mean Squared Error)は、実際の値と予測値の差の2乗を平均した値です。値が大きいほど誤差の多いモデルという解釈とします。

平均二乗誤差は次のようにmean_squared_errorメソッドで計算できます。

# 平均二乗誤差による予測精度算出
from sklearn.metrics import mean_squared_error
y_test_pred = model.predict(X_test) #テストデータを用いて目的変数を予測
y_train_pred = model.predict(X_train) #訓練データに対する目的変数を予測
print('MSE train data: ', mean_squared_error(y_train, y_train_pred))
print('MSE test data: ', mean_squared_error(y_test, y_test_pred)
MSE train data:  29.587560001195797
MSE test data:  32.72507169281496

テストデータに対するMSEが、訓練時よりも若干高くなっていますが、この程度の差なら汎化性能に問題ないと判断しても良いでしょう。

決定係数

決定係数(R2)とは、モデルの当てはまりの良さを0~1で表す指標で、1に近いほど当てはまりが良いとされます。決定係数は次のようにr2_scoreメソッドで計算できます。

# 決定係数による予測精度算出
from sklearn.metrics import r2_score
print('r^2 train data: ', r2_score(y_train, y_train_pred))
print('r^2 test data: ', r2_score(y_test, y_test_pred))
r^2 train data:  0.6509440237430768
r^2 test data:  0.6069792285352371

テストデータに対する決定係数は約0.6ということで、悪くはないといったところです。まだまだモデル改良の余地がありそうですが、今回はここまで!

最後までお読みいただきありがとうございます。

今後も初学者の方でも始めやすいデータ分析手法について取り上げていきたいと思います!

本記事に関するご指摘、ご質問がございましたら、Twitterにてお気軽にメッセージをください。

Twitterアカウント:@data_nava

Twitterでも統計学、機械学習について発信しておりますので、フォローいただけると嬉しいです!

コメント

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