2. scikit-learn: LinearRegression
機械学習のライブラリの使用方法は、
- 学習データを準備する
- 学習モデルをパラメータを決めて作成する
- 学習モデルに学習データを与えて学習させる
- 学習させたモデルを評価する、または、予測を行う
というプロセスになります。
scikit-learn の線形回帰は LinearRegression を使います。コードは非常に簡単です。
skLR.py
import numpy as np
from sklearn import linear_model
# 学習データの読み込み
(略)
# モデル作成
model = linear_model.LinearRegression()
# 学習(x = 独立変数・説明変数、y = 従属変数・目的変数)
model.fit(x, y)
# 学習したモデルを使って予測
p = model.predict(x)
2.1 学習データの準備
線形回帰(wikipedia) は、複数の x (独立変数・説明変数)を扱えるので、linear_model は ([x1, x2...], y) と、x が配列のデータを学習データとします。
例えば、医療費を推定するのに、年齢、性別、職業、BMI、喫煙... といったデータを独立変数とし、y=医療費、[x1=年齢、x2=性別、x3=職業...] というデータで線形回帰を行えます。
今回は、独立変数が一つなので、([x], y) というデータの組みを与えます。
skLR.py
import numpy as np
from sklearn import linear_model
# csvファイルからリストに読み込む
import csv
def readArrayWithCSV(dataFile):
x = []
y = []
f = open(dataFile, 'r')
reader = csv.reader(f) # csvデータは '1.0, 2.0' という形式
for row in reader:
x.append([float(row[0])]) # x はリストにする
y.append(float(row[1]))
# x=[[1.0], [1.1] ...], y=[2.0, 2.1 ...] の形式
return x,y
# 学習データの準備
dataFile = "sampleLR.csv"
x0,y0 = readArrayWithCSV(dataFile)
# LinearRegression の学習データは numpy.arrayなので変換する
x = np.array(x0)
y = np.array(y0)
2.2 モデルの作成
LinearRegression に学習データを fit() させると、線形回帰は y = a1x1 + a2x2 + ... b の a1, a2 ... と b を算出します。これらは
- model.coef_ = a1, a2 ... の値
- model.intercept_ = b の値
で取得できます。
skLR.py
# モデルの作成
model = linear_model.LinearRegression()
# 学習
model.fit(x, y)
# model parameters
a = model.coef_[0]
b = model.intercept_
2.3 モデルを用いた予測
学習させたモデルに対して predict(x) を行うと、予測値=p を出力します。学習データの x の予測値と理論値のグラフを作って比較してみました。
plotLR.py
import numpy as np
import matplotlib.pyplot as plt
def plotLR(title, x, y, p, at, bt, ap, bp, steps=0):
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
# 青い点が学習データ
ax.scatter(x, y, color='blue')
# 赤い線が学習した線形関数
textP = 'P:x=' + str(round(ap, 4)) + ', y=' + str(round(bp, 4))
ax.plot(x, p, color='red', label=textP)
# 緑の点線が学習データ生成に使った理論値
textT = 'T:x=' + str(at) + ', y=' + str(bt)
lx = np.array([0,10])
ly = at * lx + bt
ax.plot(lx, ly, color='green', linestyle='dashed', label=textT)
ax.set_title(title)
ax.legend(loc=2)
ax.set_xlabel('x')
ax.set_ylabel('y')
if steps > 0:
text = 'steps=' + str(steps)
ax.text(8.5, 0.6, text)
title = title + '_' + str(steps)
#fig.show()
imageFile = title + '.png'
fig.savefig(imageFile)
skLR.py
# model parameters
a = model.coef_[0]
b = model.intercept_
# 予測
p = model.predict(x)
# 出力
from plotLR import plotLR
title = "predLR_with_sklearn"
plotLR(title, x, y, p, 0.4, 0.8, a, b)