線性回歸通常是任何機器學習課程的起點。目的是預測輸入變量與目標變量之間的線性關係。
天真的情況是穿過空間原點的直線。在這裡,我們僅限於二維空間,即笛卡爾平面。讓我們從y = mx格式開始逐步發展,然後從y = mx + c回歸開始。
y = mx的簡化方案
在這種情況下,我們知道我們要對通過原點的數據擬合一條線。這是幼稚的情況,可能是一個很好的起點。讓我們開發損失函數並查看其行為。讓我們如下重寫我們的估計。
h(x)是估計函數,J(θ)是損失函數
請注意,我們使用平方誤差除以2m,其中m是我們擁有的數據點數。因此,我們可以將其視為平均值。準確地說,這是均方誤差的一半。當我們得到損失函數的導數時,可以看到除以2的直覺。這有助於我們對損失函數進行更簡化的推導。讓我們考慮以下幾點。
我已經使用y = 5x圖生成了這些點,並增加了噪聲。因此,理想情況下,我們對θ的估計應具有接近於5的值。現在,如果我們針對變化的θ值繪製損耗函數,我們將得到如下所示的結果。
注意,損失函數的最小值接近θ= 5。讓我們看看如何通過計算得出這個特定的最小值。
注意橙色切線及其漸變。它是一個正斜率,這使我們有了一個想法,我們必須朝相反的方向走才能找到一個較低的值。
梯度下降
正如通常所解釋的,梯度下降的思想是僅使用周圍斜坡的知識在未知的地形中下坡。因此,在此示例中,目標是使用斜率的梯度找到要遍歷的方向並確定要移動的步長。
查找遍歷方向
顯然,我們必須朝左走。步長呢?這就是學習率發揮作用的地方。這被稱為。步驟越小,速度越慢。但是,更大的步幅可能會使您錯過最小值(將您從θ= 7步進到θ= 1,這毫無意義)。因此我們可以將θ的變化公式化如下。
θ計算的下一個值和損失函數的導數
由於線性回歸的這種情況與數據無關,因此可以將其用作計算損耗和進行梯度下降的標準方程式。這應該強調一個事實,即我們始終堅持標準損失函數,而沒有自己做任何事情。在python中實現它非常簡單。我們將len(x)用於m並將0.001用作。x和y是訓練數據集或我們要估計的點集。
#損失函數(1/2* len(x)) * sum([(theta* x[i] - y[i])**2 for i in range(len(x))])#Change of thetatheta - 0.0001 * (1/len(x)) * sum([x[i]*(theta*x[i] - y[i]) for i in range(len(x))])
我們可以迭代進行梯度下降,直到達到最小值或直到損失函數低於某個閾值為止。我們還可以決定許多迭代。由於我們保證線性回歸的最小值,因此可以按以下方式實現遞減。
loss = float('inf')theta = 8while True:theta = descend(theta) if loss > loss_function(theta, x, y): loss = loss_function(theta, x, y) else: break
該降序函數返回下一個θ值和loss_function返回在價值的損失θ。我們可以如下顯示梯度遍歷。
下坡以及損失功能
估計值隨每次迭代的變化而下降
完整方案y = mx + c
這是前一種情況的擴展,我們可以如下對估計的方程和損失函數進行建模。
h(x)是估計函數,J(θ1,θ2)是損失函數
以下是我要擬合的一組點。我已經使用函數y = 5 + 3x生成了這個,但是有點雜音。
y = 5 + 3x(有噪聲)
現在我們有了一個包含2個變量的損失函數,我們的損失函數將是一個3D圖,第三個軸對應於損失值。用圖解法,我們可以說明如下。
損失函數的變化。圓的中間是最小損失點。
可以類似地得出我們的梯度下降以得出以下方程組。
梯度下降函數的推導
注意,必須同時更新梯度,以使一個θ值的更新不會影響另一個。在python中,此操作如下所示。
theta1_new = theta1 - 0.01 * (1/len(x)) * sum([theta1 + theta2*x[i] - y[i] for i in range(len(x))])theta2_new = theta2 - 0.01 * (1/len(x)) * sum([x[i]*(theta1 + theta2*x[i] - y[i]) for i in range(len(x))])theta1, theta2 = theta1_new, theta2_new
損失函數如下。我們先前場景的唯一更新是現在有了第二個變量θ2。
(1/2* len(x)) * sum([(theta1 + theta2* x[i] - y[i])**2 for i in range(len(x))])
我已經通過梯度下降更新了迭代,如下所示。除了檢查損失不斷減少的先前方案之外,我還考慮了直接損失的數量,以確保我不會在最小點附近進行很多迭代。
loss = float('inf')theta1 = 10theta2 = -1while True:theta1, theta2 = descend(theta1, theta2) if loss > loss_function(theta1, theta2, x, y) and \ abs(loss - loss_function(theta1, theta2, x, y)) > 0.001: loss = loss_function(theta1, theta2, x, y) else: break
我們可以將損失函數的梯度下降可視化如下。
與損失地形一起運動
當我們的theta值在變化時,我們的回歸擬合與表格中的值很好地吻合。它看起來像下面的樣子。
估計值隨每次迭代的變化而下降
在最終擬合中,我們分別獲得了6.5和2.7的截距和梯度值,考慮到數據中的噪聲,這是合理的。