Numpyだけでロジスティック回帰分析テスト。アクセルorブレーキ?
Numpyだけでロジスティック回帰分析。その8。
動作確認。説明的なものは無し。
実行環境
Androidスマホ
termux
Python3.8
JupyterNotebook
- Pythonライブラリ
- Numpy
実験手順
- 2値分類用に実験データをつくる。
目的変数を- アクセル=1
- ブレーキ=0とおく。
説明変数で加速度をプラスとマイナスで適当な整数値に生成
- 回帰係数をNumpyで出し、回帰多項式をつくる。
- テストデータを回帰多項式に代入して予測値を算出する。
- 予測値をシグモイド関数に代入し、アクセルorブレーキのどちらが踏まれたかを確率で出す。
実験スタート
import numpy as np # アクセル時の加速度をランダム生成 x_accel = np.random.randint(1,6,20) x_accel
array([4, 5, 3, 4, 2, 4, 3, 2, 2, 4, 4, 1, 1, 4, 3, 1, 3, 1, 4, 5])
# アクセル時の目的変数1 y_accel = np.ones(20) y_accel
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1.])
# ブレーキ時の加速度をランダム生成 x_brake = np.random.randint(-10,-1,20) x_brake
array([ -4, -4, -3, -10, -8, -5, -9, -6, -4, -8, -5, -10, -7,
-5, -5, -3, -2, -8, -10, -7])
# ブレーキ時の目的変数0 y_brake = np.zeros(20) y_brake
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0.])
# 説明変数を結合し列に変換 x = np.concatenate((x_accel,x_brake)).reshape(-1,1) # 目的変数を結合 y = np.concatenate((y_accel, y_brake)).reshape(-1,1) # x,yを横に結合して行列化 data = np.hstack([x,y]) # 上下方向でシャッフル np.random.shuffle(data) # 上5行だけ表示 data[:5, :]
array([[ 2., 1.],
[-8., 0.],
[ 3., 1.],
[-7., 0.],
[ 4., 1.]])
作ったデータの上5行を表示した。
左側が説明変数の加速度の列、右側が目的変数のアクセルorブレーキの値の列。
互いを分離。
# 説明変数抽出 X = data[:,0] # 説明変数抽出 Y = data[:,1]
説明変数X,目的変数Yが完全した。
単回帰分析をする。
# 回帰係数算出関数定義 def get_lstsq_solution(x, y): import numpy as np # 回帰係数算出 coef = np.poly1d(np.polyfit(X, Y, deg=1)) return coef
# 回帰係数算出関数に代入
coef = get_lstsq_solution(X, Y)
coef
poly1d([0.09225883, 0.64530766])
係数が出たので多項式を作って、適当な加速度を与えると予測値が返される。
# 予測値算出関数定義 def predict_p_func(test_data, coef): predict_value = coef[0] * test_data + coef[1] return predict_value
# テストデータの代入 test_data = 7 predict_value = predict_p_func(test_data, coef) predict_value
4.6094124171309
加速度7を与えて2.ナントカが返されるということは、目的変数の0と1のどっちを指してるのかと言えば、たぶん1だろう。
# シグモイド関数定義 def sigmoid(predict_y_value): import numpy as np return 1 / (1 + np.exp(- predict_y_value))
p = sigmoid(predict_value) p
0.9901405099796867
シグモイド関数が返すこの値は何なのか。
sigmoid(0)
0.5
sigmoid(1)
0.7310585786300049
1に近い方が高い値を返してくるのかな。
テストデータで別の値を入れてみる。
test_data = -1
p = sigmoid(predict_p_func(test_data,coef))
p
0.36515734762021723
0.5を下回る数字だから0と判断しているということか?
加速度マイナス1でゼロ、ブレーキが踏まれたという判断は正しい。
おわりに
実は目的変数の設定で、アクセルとブレーキの値の0と1を最初は逆にしていた。
その時シグモイド関数は逆の予測を返してきた。
ダミー変数に過ぎない0か1をどのように設定するかで答えが変わるってどういうことなんだ…
以上テスト終了。成功だか失敗だかわからん。
0か1でハッキリしてッ!