実践機械学習システム

いくつかの章を勉強してみる。基本的には、本に書いてあるものの再現。本のPDFは公開されてる。

http://sanghv.com/download/Soft/Building%20Machine%20Learning%20Systems%20with%20Python%20%5BEpub%20&%20PDF%5D/Building%20Machine%20Learning%20Systems%20with%20Python%20-%20Richert,%20Coelho.pdf

7章 回帰レコメンド

以下は、sklearnの中のボストンの物件価格のデータを使った予測問題。データのダウンロードと、プロット。

In [1]:
from sklearn.datasets import load_boston
boston = load_boston()
%matplotlib inline
from matplotlib import pyplot as plt
plt.scatter(boston.data[:,5],boston.target,color='r')
Out[1]:
<matplotlib.collections.PathCollection at 0x10e35dc10>

そして次に予測。各エリアの家の値段の中央値がboston data のインデックスの5の場所に入っている。まずは1つの変数を使った線形予測。青い線で予測のラインを描いた。

In [2]:
import numpy as np
x = boston.data[:,5]
x = np.array([[v] for v in x])
y = boston.target
slope,_,_,_ = np.linalg.lstsq(x,y)
plt.scatter(boston.data[:,5],boston.target,color='r')
plt.plot(boston.data[:,5],slope*x)
Out[2]:
[<matplotlib.lines.Line2D at 0x10e2c4510>]

一応、残差とか傾きも見ておく

In [3]:
(slope),total_error,_,_ = np.linalg.lstsq(x,y)
rmse = np.sqrt(total_error[0]/len(x))
rmse
Out[3]:
7.6426850930874881
In [4]:
slope
Out[4]:
array([ 3.6533504])

で、次に切片入れる。(図に緑の線が入っちゃったの不明)

In [5]:
x = boston.data[:,5]
x = np.array([[v,1] for v in x])
y = boston.target
(slope,bias),_,_,_ = np.linalg.lstsq(x,y)
plt.scatter(boston.data[:,5],boston.target,color='r')
plt.plot(boston.data[:,5],slope*x+bias)
Out[5]:
[<matplotlib.lines.Line2D at 0x10e3f21d0>,
 <matplotlib.lines.Line2D at 0x10e4a87d0>]

そんでもって、残差と傾きと切片もみとく

In [6]:
(slope,bias),total_error,_,_ = np.linalg.lstsq(x,y)
rmse = np.sqrt(total_error[0]/len(x))
rmse
Out[6]:
6.6030713892225625
In [7]:
slope
Out[7]:
9.1021089811803098
In [8]:
bias
Out[8]:
-34.670620776438568

7.1.1 多次元回帰

そして今度は、最小二乗法をつかったモデル。残差が小さくなったよーという感じ

In [9]:
x = boston.data
x = np.array([np.concatenate((v,[1])) for v in boston.data])
y = boston.target
_slope, total_error,_,_ = np.linalg.lstsq(x,y)
rmse = np.sqrt(total_error[0]/len(x))
rmse
Out[9]:
4.6795063006355182

7.1.2 クロスバリデーション

In [10]:
from sklearn.linear_model import LinearRegression
lr = LinearRegression(fit_intercept=True)
In [11]:
lr.fit(x,y)
p = map(lr.predict,x)
In [12]:
e = p - y
total_error = np.sum(e*e)
rmse_train = np.sqrt(total_error/len(p))
print('RMSE on training:{}'.format(rmse_train))
RMSE on training:272.676208251
In [13]:
from sklearn.cross_validation import KFold
kf = KFold(len(x),n_folds=10)
err = 0
for train,test in kf:
    lr.fit(x[train],y[train])
    p = map(lr.predict,x[test])
    e = p-y[test]
    err += np.sum(e*e)
rmse_10cv = np.sqrt(err/len(x))
print('RMSE on 10-fold CV:() {}'.format(rmse_10cv))
RMSE on 10-fold CV:() 65.462120348

7.2 罰則付き回帰

最小二乗法に罰則項をつけて予測モデルがデータに当てはまりすぎて汎化誤差が大きくなるのを防ぐ方法。リッジ回帰、Lasso、その2つを組み合わせたのがElastic Net. 本の例はElastic Net。

In [14]:
from sklearn.linear_model import ElasticNet
en = ElasticNet(fit_intercept=True,alpha=0.5)
In [15]:
en.fit(x,y)
p = map(en.predict,x)
In [16]:
e = p - y
total_error = np.sum(e*e)
rmse_train = np.sqrt(total_error/len(p))
print('RMSE on training:{}'.format(rmse_train))
RMSE on training:265.216367303
In [17]:
from sklearn.cross_validation import KFold
kf = KFold(len(x),n_folds=10)
err = 0
for train,test in kf:
    en.fit(x[train],y[train])
    p = map(en.predict,x[test])
    e = p - y[test]
    err += np.sum(e*e)
rmse_10cv = np.sqrt(err/len(x))
print('RMSE on 10-fold CV:() {}'.format(rmse_10cv))
RMSE on 10-fold CV:() 63.3644044508

本にあるみたいな図を作りたいなと思ったけど、それはまた今度

In [14]:
 
In [ ]: