回帰直線を求める
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()
うまく線が引けました。 サンプルが長すぎて、読み込むのが辛いですが、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つの目的だそうです。
全然高速ではなくなってきましたが、まだまだ続きます。