以前の記事でscikit-learnを使った「分類」の例を紹介したが、今回は別のデータセットを使って「回帰分析」をやっていく。
回帰は主に物事の予測に用いられる分析手法で「単回帰分析」と「重回帰分析」に分けられる。
一つの変数(説明変数)から、一つの値(目的変数)を予測するものを「単回帰分析」、複数の説明変数から目的変数を予測するものを「重回帰分析」と言う。
今回はscikit-learnを使った「重回帰分析」の簡単な例を紹介する。
コンテンツ
データセットの読み込み
今回もscikit-learnで用意されているデータセットを使用する。
※米国ボストン市郊外、地域別の住宅価格。
from sklearn.datasets import load_boston
import pandas as pd
boston = load_boston()
# データフレームに変換して内容を確認
df = pd.DataFrame(boston.data, columns=boston.feature_names)
df['目的変数(住宅価格)'] = boston.target
df.head()
説明変数の内容は下記表のとおり。
CRIM | 犯罪発生率 |
---|---|
ZN | 住居区画の密集度 |
INDUS | 非小売業の土地割合 |
CHAS | チャールズ川 (1: 川の周辺, 0: それ以外) |
NOX | NOx濃度 |
RM | 平均部屋数 |
AGE | 1940年より前に建てられた物件割合 |
DIS | 5つのボストン市の雇用施設からの重み付き距離 |
RAD | 大きな道路へのアクセスしやすさ |
TAX | $10,000ドルあたりの所得税率 |
PTRATIO | 教師あたりの生徒数 |
B | 黒人の比率 1000(Bk – 0.63)^2 |
LSTAT | 低所得者の割合 |
データの前処理
次に取得したデータセットを説明変数(x)、目的変数(y)に分ける。
y = boston.target
x = boston.data
さらにxとyをそれぞれ訓練用データ、テスト用データに分ける。
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, shuffle=True)
今回はテストデータの割合を20パーセントにしてみた。
モデルに訓練用データを与え学習させる
前処理で用意した訓練用データ(x_train, y_train)を与え、モデルに学習させる。
from sklearn import linear_model
model = linear_model.LinearRegression()
model.fit(x_train, y_train)
学習したモデルの切片と係数を確認してみよう。
# 切片
print(model.intercept_)
# 偏回帰係数(重み)
desc = [
'犯罪発生率', '住居区画の密集度', '非小売業の土地割合',
'チャールズ川 (1: 川の周辺, 0: それ以外)', 'NOx濃度',
'平均部屋数', '1940年より前に建てられた物件割合',
'5つのボストン市の雇用施設からの重み付き距離',
'大きな道路へのアクセスしやすさ', '$10,000ドルあたりの所得税率',
'教師あたりの生徒数', '黒人の比率', '低所得者の割合'
]
df_tmp = pd.DataFrame(model.coef_, index=boston.feature_names, columns=['重み'])
df_tmp['説明'] = desc
df_tmp
係数(重み)を見てみると「CHAS(川の周辺かどうか)」、「平均部屋数」、「大きな道路へのアクセス」の値が高く、住宅価格に大きな影響を与えることが分かる。
テストデータを使ってモデルの精度を評価する
モデルの精度の指標として、決定係数という値がある。
これは1に近いほど分析の精度が高いことを意味する。
score関数にテストデータを渡し、決定係数を確認してみよう。
print(model.score(x_test, y_test))
# 0.7198637341775773
重回帰分析の場合、0.5が精度の目安と言われているので、今回の結果はまずまずと言えるだろう。
実際に10個のテストデータと予測結果を比較したものを見てみよう。
for i in range(10):
print('テストデータ:' + str(y_test[i]))
print('予測結果:' + str(model.predict([x_test[i]])) + '\n')
多少のバラつきはあるが、大きく外すことなく目的変数を求めることができている。