回帰分析とは③

こんにちは!EMです^^

 

今回も引き続き、回帰分析について理解していきますよ~!

ここでは少し、回帰分析についてよく出てくる言葉についてふれていきます。

 
予測
 

線形回帰の方程式があるなら、与えられたxの値に対して

データを予測するできます!予測というMLっぽいキーワードが出てきました。

 

コスト関数

回帰分析に関する課題は、その問いに対して「最適化」を目指すという事です。

その為にはコスト関数(予測値と実際の値の間の誤差)を最小化していく事を

ゴールにします。

線形回帰問題のよく見かけるコスト関数(J)として

平均二乗誤差(MSE)があります。

 

 

f:id:tennisfashionista:20210121023304p:plain

予測は係数と独立変数から求める事が出来ます。

f:id:tennisfashionista:20210121022639p:plain

線形回帰係数の解は、コスト関数を最小化する解です。

 

最急降下法(Gradient Descent

OLS線形回帰の問題には closed form solution(閉形式の解)がありますが

大抵のコスト関数を最小化にする問題に関しては

閉形式の分析的な解決法がありません。

その代わり数値的に推定していく為には、反復アルゴリズムに頼る必要があります。

この最適化アルゴリズムを最急降下法と呼びます。

 

概念的に最小化とは、コスト関数のグラフで1番低い点を見つけることです。

もしあなたが丘の高い場所に立っていて、下りの階段を下りていく事で

1番低い場所(最小点)を見つけることができますよね。

階段が常に下り坂である限り、丘のふもとにかならず到着します。

 

「各階段を下り坂にする」というのを数学的に言えば

「導関数」の方向、またはすべての点で線に接するタンジェント(tangent)です。

複数の変数がある場合、一般的に導関数は「勾配」と呼ばれ

各変数に関する偏導関数によって決まります。

デカルト座標のx、y、zでは、次のとおりです。

 

f:id:tennisfashionista:20210122000755p:plain

文系出身の人には、頭がいたくなりそうな、新しい記号がでてきましたね~。

▽はnablaと言われ、ベクトル計算を行う時に使われるそうです。

▽はシンプルに勾配を表しているみたいですね。

詳しくはWikipediaを見てみて下さい。

Nabla symbol - Wikipedia

 

コスト関数Jの勾配は、常にJの勾配が0に等しい最小点に向かって

表面に接する点を指します。

 

どの時点からでも、小さなステップを踏むことで、最小値に向かって繰り返し

「歩く」ようなイメージですね。

f:id:tennisfashionista:20210122235317p:plain

 

ステップサイズ(学習率)が大きすぎると、最小値を見逃して反対側にいってしまう

可能性があります。

逆にステップサイズが小さすぎると、解を得るまでに

非常に長い時間がかかる場合があります。

 

 

Gradient Descent for OLS linear regression

 

さて、コスト関数で出てきた数式をもう一度みてみましょう。

f:id:tennisfashionista:20210123000220p:plain

2つのパラメータ(β0とβ1)を持つ線形回帰コスト関数Jの勾配は

連鎖律を使って求められます。

 

f:id:tennisfashionista:20210123000927p:plain

 

最急降下法を使用すると、どんなコスト関数でも数値的に解く事が出来ます。

最初は仮説をたてた状態で始めて、誤差と勾配を計算します。

次に、勾配の方向に「歩く」事を繰り返し、エラーを再計算していきます。

許容範囲内の解におさまるまで実行し続けます。

 

ぜひご自身の端末でも試してみて下さいね!

ヒントはこちら↓

 

x = np.random.normal(size = 100)
y = 3 * x + np.random.normal(scale = 3, size = 100) + 2

N = len(x)
cost_history = []

num_iterations = 500
learning_rate = 0.01

beta_0 = 0
beta_1 = 0

for each_iteration in range(num_iterations):
    

    beta_0_deriv = 0
    beta_1_deriv = 0

    for i in range(N):
        # Calculate partial derivatives
        # -2x(y - (beta_1*x + beta_0))
        beta_1_deriv += -2*x[i] * (y[i] - (beta_1*x[i] + beta_0))

        # -2(y - (beta_1*x + beta_0))
        beta_0_deriv += -2*(y[i] - (beta_1*x[i] + beta_0))

    # We subtract because the derivatives point in direction of steepest ascent
    beta_1 -= (beta_1_deriv / N) * learning_rate
    beta_0 -= (beta_0_deriv / N) * learning_rate
    
    
    #Calculate cost for auditing purposes
    total_error = 0.0
    for i in range(N):
        total_error += (y[i] - (beta_1*x[i] + beta_0))**2
    cost = total_error / N
    cost_history.append(cost)

    # Log Progress
    if each_iteration % 10 == 0:
        print ("iter={:d}    beta_1={:.2f}    beta_0={:.4f}    cost={:.2}".
        format(each_iteration, beta_1, beta_0, cost))

print ('beta_0: '+ str(beta_0))
print ('beta_1: '+ str(beta_1))

plt.scatter(x,y)
plt.plot(x, beta_1*x + beta_0)

 

エクササイズ

 

上記のコードを関数に変換していきましょう!

 

def gradient_descent_linear_regression (X_valsy_vals):
    
    # fill in function code here:
    
    
    return Betas # a tuple of beta_0, beta_1
 
 

 

 

 少し長くなりましたが、じっくり一つ一つ理解していきましょう!

 

 

ちなみに皆様に朗報です!

私今まで知らなかったんですが、CodeCampさんが無料で5回分無料レッスンを

されているらしいです、、、!

私が他のオンラインスクールで機械学習のコースを受講した際は

グループレッスンで約2倍のお値段を払ったので

完全マンツーマンでこのお値段は超良心的だなと思います。。。

 

 

 

ぜひ気になる方は無料体験もされてるみたいなので、一度WEBサイトを見てみてくださいね。

データ分析は時代が変化しても、必ず重宝される分野だと思っているので

プロから基礎を学ぶのは、本当に超効率的な自己投資だと思います。

 

 

 

それではまた次回~!^^