線性迴歸(Linear Regression),亦稱爲直線迴歸,即用直線表示的迴歸,與曲線迴歸相對。若因變量Y對自變量X1、X2…、Xm的迴歸方程是線性方程,即μy=β0 +β1X1 +β2X2 +…βmXm,其中β0是常數項,βi是自變量Xi的迴歸係數,M爲任何天然數。這時就稱Y對X1、X2、…、Xm的迴歸爲線性迴歸。git
簡單迴歸:算法
只有一個自變量的線性迴歸稱爲簡單迴歸,以下面示例:數組
X表示某商品的數量,Y表示這些不一樣數量商品的總價格dom
x=[0, 1, 2, 3, 4, 5]函數
y=[0, 17, 45, 55, 85, 99]測試
二維座標中繪圖以下圖:優化
如今當商品數量 X = 6時,估計商品總價是多少?spa
咱們能夠很明顯的看到,商品總價隨商品的數量上升而上升,這是一個典型的線性迴歸。3d
由於只有一個自變量X,咱們假設線性迴歸模型: Y = a * X + bcode
咱們須要求出最合適的a,b值,使得直線:Y = a * X + b 與上圖的趨勢相擬合,這時候才能去預測不一樣商品數量X下的總價Y。
最小二乘法:
爲了求出最合適的a b ,咱們引入最小二乘法。
最小二乘法,亦稱最小二乘法估計。由樣本觀測值估計整體參數的一種經常使用方法。它用於從n對觀測數據(x1,y1),(x2,y2),……,(xn,yn)肯定x與y之間對應關係y=f(x)的一種最佳估計,使得觀測值與估計值之差(即誤差)的平方和 H爲最小。
最小二乘法能儘可能消除偶然偏差的影響,從而由一組觀測數據求出最可靠、最可能出現的結果。
由上圖咱們能夠很明顯的看出直線Y = a * X + b過原點,即 b = 0
咱們嘗試不一樣的a值 獲得的結果以下:
a = 19 時 H = 154
a = 20 時 H = 85
a = 21 時 H = 126
圖像分別以下:
咱們能夠粗略得出結論 a = 20,b = 0 時,線性模型 Y = 20 * X 與樣本數據擬合的比較好。
因此當商品數量 X = 6 時,咱們能夠粗略估計總價Y = 20 * 6 = 120
多元迴歸:
大於一個自變量的線性迴歸叫作多元迴歸。
上面的例子只是一個自變量,處理起來比較簡單,可是若自變量有不少,假設自變量有m個,爲 [ x1,x2,x3,x4.....xm ]
這時候咱們假設的迴歸係數(即權重)也須要有m個,即咱們假設的線性模型是 Y = X0 + X1*W1 + X2*W2 + X3*W3 + ....... + Xm*Wm
爲了計算方便,咱們去W0 = 1
這樣:Y = X0*W0 + X1*W1 + X2*W2 + X3*W3 + ....... + Xm*Wm
寫成向量形式:
W = [W0,W1 , W2 ,W3 , .... ,Wm]
X = [ X0, X1 , X2 , X3 , .... , Xm]
Y = WT * X (WT爲向量W的轉置)
觀測值與估計值之差(即誤差)的平方和:
爲了方便後面計算,咱們在H的左邊乘上二分之一,即:
上面公式中 n 表示訓練樣本的數目,m 表示每條訓練樣本 的特徵(自變量)個數,上標表示屬於第 j 個 樣本,下標表示第 i 個特徵(自變量值),
表示第 j 個樣本總價觀測值
如今H是關於W0,W1,W2....Wm的函數,咱們須要經過合適的方法求出最適合的W值,才能得出一個比較好的線性迴歸方程。與簡單迴歸相比,這裏咱們很難經過觀察與嘗試不一樣的w值來求解,咱們須要採用最優化算法。
梯度算法:
常見的最優化算法有梯度降低法(Gradient Descent)、牛頓法和擬牛頓法(Newton's method & Quasi-Newton Methods)、共軛梯度法(Conjugate Gradient)、 啓發式優化方法等,本文詳細介紹梯度算法。
明確下咱們如今的目標:咱們須要經過梯度算法求出---當在H取得最小的狀況下,W0 ,W1 ,W2 ,W3 , ....... ,Wm的值,從而寫出迴歸方程。
梯度算法分爲梯度上升算法 和 梯度降低算法。梯度降低算法的基本思想是:要找到某函數的最小值,最好的方法是沿着該函數的梯度方向探尋,梯度上升則相反。對於一個有兩個未知數x,y的函數f(x,y),梯度表示爲:
對於Z = f(x,y),使用梯度降低算法的意味着 沿X軸方向移動,沿Y的方向移動
,函數f(x,y)必需要在待計算的點上有定義而且可微。
能夠通俗理解爲:
用梯度降低法找出最小H
咱們前面看到:
H是關於W = [W0 ,W1 ,W2 ,W3 , ....... ,Wm]的函數,H的梯度以下:
這個時候對於每個Wi的梯度:
咱們假設每次沿着梯度方向更新的步長爲 α,因此W的值更新公式可寫爲:
因此梯度降低算法的僞代碼以下:
每一個迴歸係數(即每一個W值)的每一個值都爲1
重複R次:
計算整個數據集的梯度
使用 更新迴歸係數W
實例:
用梯度降低 算法求下面商品數據的線性迴歸方程
咱們假設線性迴歸模型爲總價Y = a + b * X1 + c * X2 (X1 X2 分別表示商品1,2的數量)
咱們須要求出迴歸係數W = [ a, b, c]
梯度降低算法以下:
1 import numpy as np 2 3 def grad_desc(train_data, train_labels): 4 """梯度降低""" 5 data_mat = np.matrix(train_data) 6 label_mat = np.matrix(train_labels).transpose() 7 n = np.shape(data_mat)[1] 8 # 步長 9 alpha = 0.001 10 # 最大循環次數 11 max_cycles = 100 12 # 初始化迴歸係數weights 13 weights = np.ones((n, 1)) 14 for index in range(max_cycles): 15 h = data_mat * weights-label_mat 16 weights = weights - alpha * data_mat.transpose() * h 17 # 返回壓平的係數數組 18 return np.asarray(weights).flatten()
咱們用上面算法獲得的迴歸係數爲
使用 更新迴歸係數W
修改後的算法以下:
1 import numpy as np 2 3 def advanced_random_grad_desc(train_data, train_labels): 4 """隨機梯度降低改進""" 5 data_mat = np.asarray(train_data) 6 label_mat = np.asarray(train_labels) 7 m, n = np.shape(data_mat) 8 # 步長 9 alpha = 0.001 10 # 初始化迴歸係數weights 11 weights = np.ones(n) 12 max_cycles = 500 13 for j in range(max_cycles): 14 data_index = list(range(m)) 15 for i in range(m): 16 random_index = int(np.random.uniform(0, len(data_index))) 17 h = sum(data_mat[random_index] * weights)-label_mat[random_index] 18 weights = weights - alpha * h * data_mat[random_index] 19 del data_index[random_index] 20 return weights
計算獲得的迴歸係數爲:
咱們能夠獲得線性迴歸方程爲:
Y = 1.27 + 4.31 * X1 + 5.28 * X2
寫在後面的話:
本文的完整代碼已上傳:https://gitee.com/beiyan/machine_learning/tree/master/gradient
隨機梯度降低(上升)算法使用很是普遍,效果也很是好,後續文章將使用梯度算法來解決一些問題。不例外,梯度算法也是有缺點的,如靠近極小值時收斂速度減慢、直線搜索時可能會產生一些問題、可能會「之字形」地降低等,另外降低或上升步長的選擇也會影響最後獲得的迴歸係數,咱們能夠經過改變一些參數來測試迴歸的效果。