よちよちpython

独習 python/Qpython/Pydroid3/termux

Numpyだけでロジスティック回帰分析テスト。アクセルorブレーキ?

Numpyだけでロジスティック回帰分析。その8。
動作確認。説明的なものは無し。



実行環境


Androidスマホ
termux
Python3.8
JupyterNotebook

実験手順


  1. 2値分類用に実験データをつくる。
    目的変数を
    • アクセル=1
    • ブレーキ=0とおく。

      説明変数で加速度をプラスとマイナスで適当な整数値に生成

  2. 回帰係数をNumpyで出し、回帰多項式をつくる。

  3. テストデータを回帰多項式に代入して予測値を算出する。

  4. 予測値をシグモイド関数に代入し、アクセル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でハッキリしてッ!