毎日テキストマイニング

180日間、毎日テキストマイニングをするブログです

2018/7/15【23日目その2】高速で学ぶ統計学その3

回帰直線を求める

1つ前の投稿でxをいじりましたが、このようにxの値に対して、yはさまざまな値になりますので、yの平均に注目することがあるそうです。これをyの条件付き平均というらしいです。

式にするとこうなるそうです。

yの平均 = a + bx

簡単な1次式ですね。yの平均を予測値、bを回帰係数というらしい。回帰係数とは当てはめられた回帰直線の傾き、だそうでまた意味がわからない。この回帰係数bと切片のaを求めるのに使うのが最小2乗法だそうです。

最小2乗法とは

xの時、yの値はいくつという時に丁度良い線を引く際にそれぞれのyに近い場所に線を引きたいと思いますが、そのyとの距離が最小の線を求めるのが、最小2乗法というらしいです。

つまり、こういう線を引きたい時に、yとの距離を最小にする線を求めるモデルということだと思います。scikit-learnの公式ページにサンプルがありましたので、そのままコピペして確かめてみたいと思います。

import matplotlib.pyplot as plt
from sklearn import datasets, linear_model
from sklearn.metrics import mean_squared_error, r2_score

diabetes_X_train = x[:-20]
diabetes_X_test = x[-20:]

diabetes_y_train = y[:-20]
diabetes_y_test = y[-20:]
regr = linear_model.LinearRegression()
regr.fit(diabetes_X_train, diabetes_y_train)
diabetes_y_pred = regr.predict(diabetes_X_test)
print('Coefficients: \n', regr.coef_)
# The mean squared error
print("Mean squared error: %.2f"
      % mean_squared_error(diabetes_y_test, diabetes_y_pred))
# Explained variance score: 1 is perfect prediction
print('Variance score: %.2f' % r2_score(diabetes_y_test, diabetes_y_pred))
plt.scatter(diabetes_X_test, diabetes_y_test,  color='black')
plt.plot(diabetes_X_test, diabetes_y_pred, color='blue', linewidth=3)

plt.xticks(())
plt.yticks(())

plt.show()

実行結果。

Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.

リシェイプをしろという、エラーがでました。 言われたまま、reshape(-1, 1) というメソッドを使ってみます。

x
0       33
1       73
2     1370
(以下、省略)

これが、

x_reshape = x.reshape(-1, 1)
x_reshape
array([[  33],
       [  73],
       [1370],

こうなりました。どうやらarray配列にしないといけなかったようです。yのreshapeも追加して再実行してみます。

import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets, linear_model
from sklearn.metrics import mean_squared_error, r2_score

x_reshape = x.reshape(-1, 1)
y_reshape = y.reshape(-1, 1)

diabetes_X_train = x_reshape[:-20]
diabetes_X_test = x_reshape[-20:]

diabetes_y_train = y_reshape[:-20]
diabetes_y_test = y_reshape[-20:]

regr = linear_model.LinearRegression()
regr.fit(diabetes_X_train, diabetes_y_train)
diabetes_y_pred = regr.predict(diabetes_X_test)

plt.scatter(diabetes_X_test, diabetes_y_test,  color='black')
plt.plot(diabetes_X_test, diabetes_y_pred, color='blue', linewidth=3)

plt.show()

f:id:rimt:20180716200055p:plain

うまく線が引けました。 サンプルが長すぎて、読み込むのが辛いですが、1行ずつみていきたいと思います。

diabetes_X_train = x_reshape[:-20]
diabetes_X_test = x_reshape[-20:]
  • diabetes_X_train = x_reshape[:-20]

xの配列から始めの20個を学習データとして取得、なぜ[:-20]というわかりずらいす取得の仕方をしているのか謎ですね。

  • diabetes_X_test = x_reshape[-20:]

こっちは、xの配列から終わりの20個を学習データとして取得。

regr = linear_model.LinearRegression()
regr.fit(diabetes_X_train, diabetes_y_train)
diabetes_y_pred = regr.predict(diabetes_X_test)
  • regr = linear_model.LinearRegression()

回帰直線のモデルを取得

  • regr.fit(diabetes_X_train, diabetes_y_train)

fitメソッドでモデルに学習データをfitさせる

  • diabetes_y_pred = regr.predict(diabetes_X_test)

学習したデータをpredictメソッドでx全体に適用させる。

plt.scatter(diabetes_X_test, diabetes_y_test,  color='black')
plt.plot(diabetes_X_test, diabetes_y_pred, color='blue', linewidth=3)

plt.show()
  • plt.scatter(diabetes_X_test, diabetes_y_test, color='black')

xとyの散布図を作る

  • plt.plot(diabetes_X_test, diabetes_y_pred, color='blue', linewidth=3)

線を引く

  • plt.show()

図を出力

だそうです。sikit-learnを使うと、どこで計算をしているのか全くわからないですが、つまりはこういう線を引くのが1つの目的だそうです。

全然高速ではなくなってきましたが、まだまだ続きます。