python實現線性迴歸之梯度下降法,梯度下降詳解

線性迴歸的有關概念已在筆者相關文章中進行介紹。本篇內容將介紹梯度下降(BGD)相關內容。

1.梯度下降

梯度下降常用於機器學習中求解符合最小損失函數的模型的參數值,梯度下降也是BP神經網絡的核心,本文將介紹批量梯度下降法(BGD)。

如上圖所示,梯度下降的過程便是沿梯度方向,按照一定的步伐求解極小(大)值。這裏舉一個簡單的例子,假如你在一座山上,你怎樣才能最安全最快速地下山,這裏有兩個條件,一是安全下山,二是快速下山。答案便是沿着較爲陡峭(梯度)的地方,且容易落腳(步伐大小,即學習率)的地方一步一步地下山。

梯度,也就是“山”的斜度,在上圖中,便是每個點處的斜率,即導數。下面給出梯度下降的數學公式:

                                                                               ΘΘ\theta _{i+1}=\theta_{i}+\alpha \frac{\partial J(\theta )}{\partial \theta }

上式中,\theta _{i+1}便是下一步,\theta _{i}是當前所處的位置,\alpha是步伐大小(學習率),\frac{\partial J(\theta )}{\partial \theta }爲梯度,也就是J(\theta )\theta的偏導數。

另外,上式中的J(\theta )爲損失函數,也就是描述結果準確程度的函數,在這裏,我們定義損失函數爲:

                                                                         J(\theta )=\frac{1}{2m}\sum_{i=0}^{m}(h_{\theta }(x^{i})-y^{i})^2

理論上,當損失函數取最小值0時,便爲最優的結果。對於上述J(\theta ),其實還有其他的損失函數也能很好地發揮作用,但是平方誤差損失函數是解決迴歸問題最常用的手段。

在上式中,h_{\theta }(x^{i})表示當前\theta與矩陣X的點乘。如:

                                                                         \theta =\begin{bmatrix} 1 & 2\\ 6 & 9\\ 5 &7 \end{bmatrix}X=\begin{bmatrix} 2 & 3& 8\\ 5& 2& 7 \end{bmatrix}

則                                                                 h_{\theta }(x^{i})=\begin{bmatrix}12 & 7& 22\\ 57&36 & 111\\ 45& 29& 89\end{bmatrix}

在上式中,y^{i}是我們的實際數據。

J(\theta )求偏導,得:

                                                                       \frac{\partial J(\theta )}{\partial \theta }=\frac{1}{m}\sum_{i=1}^{m}(h_{\theta }(x^{i})-y^{i})x^{i}

即最終表達式爲:

                                                                  \theta _{i+1}=\theta_{i}+\alpha(\frac{1}{m}\sum_{i=1}^{m}(h_{\theta }(x^{i})-y^{i})x^{i})

按照上式,便可求出最終參數\theta

關於學習率\alpha的說明:如果學習率太小,會導致學習時間變長,消耗資源變大。如果學習率太大,可能會越過最低(高)點,誤差變大,甚至導致函數無法收斂。

2.python實現

一元參數測試:

import numpy as np

X = mat([1, 2, 3]).reshape(3, 1)  # x爲1,2,3
Y = mat([5, 10, 15]).reshape(3, 1)  # y爲5,10,15
theta = 1 #初始爲1
alpha = 0.1 # 學習率爲0.1
for i in range(100):
    theta = theta + np.sum(alpha * (Y - dot(X, theta)) * X.reshape(1, 3))/3 # 公式實現
print(theta)

由代碼的初始數據可知,方程應爲y=5x,下面我們測試theta是否爲5:

測試結果正確。

實戰:

同樣,這裏準備了最小二乘法的測試數據,待下面測試結束後,讀者可檢查結果是否與最小二乘法的結果一致。

數據示例截圖如下:

上述數據爲某一商品的銷售量與售價、服務投資和其它投資的對應關係,即我們要求出:

                                                                 X=\begin{bmatrix} 3.5 & 1.4 & 0.2\\ 3.0 & 1.4& 0.2\\ 3.2 & 1.3& 0.2\\ ...& ...& ... \end{bmatrix},Y=\begin{bmatrix} 5.1\\ 4.9\\ 4.7\\ ... \end{bmatrix},\theta =\begin{bmatrix} \theta _{0}\\ \theta_{1}\\ \theta_{2}\\ ... \end{bmatrix}

Y=X\theta中,矩陣\theta

代碼如下:

import numpy as np
import pandas as pd
from numpy import dot


dataset = pd.read_csv('C:\\Users\\57105\\Desktop\\data.csv')  # 讀入數據
X = dataset.iloc[:, 2: 5]  # x爲所有行,2到4列
Y = dataset.iloc[:, 1]  # y爲所有行,第1列
theta = np.array([1.0, 1.0, 1.0]).reshape(3, 1)  # theta初始值
alpha = 0.1  # 學習率
temp = theta
X0 = X.iloc[:, 0].values.reshape(60, 1)
X1 = X.iloc[:, 1].values.reshape(60, 1)
X2 = X.iloc[:, 2].values.reshape(60, 1)
Y = Y.values.reshape(60, 1)
for i in range(1000):  # 這裏特別注意,在完成一次循環後,整體更新theta
    temp[0] = theta[0] + alpha * np.sum((Y - dot(X, theta)) * X0) / 60.0
    temp[1] = theta[1] + alpha * np.sum((Y - dot(X, theta)) * X1) / 60.0
    temp[2] = theta[2] + alpha * np.sum((Y - dot(X, theta)) * X2) / 60.0
    theta = temp
print(theta)

測試結果:

\theta =\begin{bmatrix} 1.157\\ 0.780\\ -0.586 \end{bmatrix},結果與最小二乘法幾乎一致,如想再精確,可調整學習率。即y=1.157x_{1}+0.78x_{2}-0.586x_{3},該回歸方程反應了商品銷售量與售價、服務投資和其它投資的關係。

上述便爲梯度下降的相關內容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章