歡迎轉發與關注。
上一篇我們介紹了線性回歸的概述和最小二乘的介紹,對簡單的一元線性方程模型手推了公式和python代碼的實現。
機器學習之線性回歸模型詳細手推公式與代碼實現(篇一)
今天這一篇來介紹多元線性回歸模型
多元線性回歸模型介紹
在回歸分析中,如果有兩個或兩個以上的自變量,就稱為多元回歸。事實上,一種現象常常是與多個因素相聯繫的,由多個自變量的最優組合共同來預測或估計因變量,比只用一個自變量進行預測或估計更有效,更符合實際。因此多元線性回歸比一元線性回歸的實用意義更大
比如糖尿病人的血糖變化可能受胰島素、糖化血紅蛋白、血清總膽固醇、甘油三酯等多種指標的影響。但很多情況下,由於自變量的單位是不一樣的,需要做標準化處理。比如在消費水平預測模型中,工資水平、受教育程度、職業、地區、家庭負擔等因素都會影響到消費水平,而這些影響因素的單位和量級肯定是不同的,雖然不會影響自變量的重要程度,但是對回歸係數的大小還是有直接影響作用的。標準化回歸係數沒有單位,其值越大,說明該自變量對因變量的影響越大。
數學模型
1.描述因變量 y 如何依賴於自變量 X1,X2,…,Xn 和誤差項ε的方程,稱為多元回歸模型
2.涉及n個自變量的多元回歸模型可表示為
應變量Y可以近似地表示為自變量x1,x2,…,xm的線性函數ω0為常數項ω1,ω2,…,ωm是偏回歸係數,表示在其他變量不變時時候x增加一個或者減少一個單位時候,Y的平均變化量ε是被稱為誤差項的隨機變量,又稱為殘差3.參數 ∶= {1,2,3,…,,}確定了模型的狀態,通過固定參數即可確定此模型的處理邏輯。當輸入節點數 = 1時,數學模型可進一步簡化為最簡單的模型
= +
4.對於某個神經元來說,和的映射關係f。,是未知但確定的。兩點即可確定一條直線,為了估計和的值,我們只需從圖中直線上採樣任意2個數據點就可以表示這條直線。
5.可以看到,只需要觀測兩個不同數據點,就可完美求解單輸入線性模型的參數,對於n輸入的現象模型,只需要採樣n + 1組不同數據點即可,似乎線性模型可以得到完美解決。那麼上述方法存在什麼問題呢?考慮對於任何採樣點,都有可能存在觀測誤差
= + +
6.一旦引入觀測誤差後,即使簡單如線性模型,如果僅採樣兩個數據點,可能會帶來較大估值偏差。如果基於藍色矩形塊的兩個數據點進行估計,則計算出的藍色虛線與真實橙色直線存在較大偏差。為了減少觀測誤差引入的估計偏差,可以通過採樣多組數據樣本集合 =
,然後找出一條「最好」的直線,使得它儘可能地讓所有採樣點到該直線的誤差之和最小
7.由於觀測誤差的存在,當我們採集了多個數據點時,可能不存在一條直 線完美的穿過所有採樣點。退而求其次,我們希望能找到一條比較「好」的位於採樣點中 間的直線。那麼怎麼衡量「好」與「不好」呢?一個很自然的想法就是,求出當前模型的 所有採樣點上的預測值() +與真實值()之間的差的平方和作為總誤差
然後搜索一組參數,使得最小,對應的直線就是我們要尋找的最優直線
梯度下降法介紹
根據上面數學分析,我們確定用梯度下降法來計算多元線性模型,當然還有更多計算方式。
梯度下降法又稱最速下降法,是求解無約束最優化問題的一種最常用的方法,在對損失函數最小化時經常使用。梯度下降法是一種迭代算法。選取適當的初值x(0),不斷迭代,更新x的值,進行目標函數的極小化,直到收斂。由於負梯度方向時使函數值下降最快的方向,在迭代的每一步,以負梯度方向更新x的值,從而達到減少函數值的目的
關於梯度下降算法的直觀理解,我們以一個人下山為例。比如剛開始的初始位置是在紅色的山頂位置,那麼現在的問題是該如何達到藍色的山底呢?按照梯度下降算法的思想,它將按如下操作達到最低點:
第一步,明確自己現在所處的位置第二步,找到相對於該位置而言下降最快的方向第三步, 沿著第二步找到的方向走一小步,到達一個新的位置,此時的位置肯定比原來低第四部, 回到第一步第五步,終止於最低點按照以上五步,最終達到最低點,這就是梯度下降的完整流程。當上圖並不是標準的凸函數,往往不能找到最小值,只能找到局部極小值。所以你可以用不同的初始位置進行梯度下降,來尋找更小的極小值點,當然如果損失函數是凸函數就沒必要了
計算梯度
根據之前介紹的梯度下降算法,我們需要計算出函數在每一個點上的梯度信息
/
/b
需要優化的模型參數是和,因此我們按照下面方式循環更新參數,其中為學習率
學習率(步長)介紹
我們可以通過來控制每一步走的距離,以保證不要走的太快,錯過了最低點(右圖所示),同時也要保證收斂速度不要太慢
所以在選擇大小的時候在梯度下降中是非常重要的,不能太大也不能太小
代碼實現
引入依賴import numpy as npimport matplotlib.pyplot as plt
導入數據points = np.genfromtxt('linear.csv', delimiter=',')points[0,0]# 提取points中的兩列數據,分別作為x,yx = points[:, 0]y = points[:, 1]# 用plt畫出散點圖plt.scatter(x, y)plt.show()效果
定義損失函數# 損失函數是係數的函數,另外還要傳入數據的x,ydefcompute_cost(w, b, points): total_cost = 0 M = len(points)# 逐點計算平方損失誤差,然後求平均數for i in range(M): x = points[i, 0] y = points[i, 1] total_cost += ( y - w * x - b ) ** 2return total_cost/M
定義模型的超參數alpha:學習率num_iter:訓練優化 10次(可以自行設定)alpha = 0.0001initial_w = 0initial_b = 0num_iter = 10
定義核心梯度下降算法函數defgrad_desc(points, initial_w, initial_b, alpha, num_iter): w = initial_w b = initial_b# 定義一個list保存所有的損失函數值,用來顯示下降的過程 cost_list = []for i in range(num_iter): cost_list.append( compute_cost(w, b, points) ) w, b = step_grad_desc( w, b, alpha, points )return [w, b, cost_list]defstep_grad_desc( current_w, current_b, alpha, points ): sum_grad_w = 0 sum_grad_b = 0 M = len(points)# 對每個點,代入公式求和for i in range(M): x = points[i, 0] y = points[i, 1] sum_grad_w += ( current_w * x + current_b - y ) * x sum_grad_b += current_w * x + current_b - y# 用公式求當前梯度 grad_w = 2/M * sum_grad_w grad_b = 2/M * sum_grad_b# 梯度下降,更新當前的w和b updated_w = current_w - alpha * grad_w updated_b = current_b - alpha * grad_breturn updated_w, updated_b
測試:運行梯度下降算法計算最優的w和bw, b, cost_list = grad_desc( points, initial_w, initial_b, alpha, num_iter )print("w is: ", w)print("b is: ", b)cost = compute_cost(w, b, points)print("cost is: ", cost)plt.plot(cost_list)plt.show()效果
w is: xxxxxxxxb is: xxxxxxxxcost is: xxxxxxxx
畫出擬合曲線plt.scatter(x, y)# 針對每一個x,計算出預測的y值pred_y = w * x + bplt.plot(x, pred_y, c='r')plt.show()效果
上述例子比較好地展示了梯度下降算法在求解模型參數上的強大之處。需要注意的 是對於複雜的非線性模型,通過梯度下降算法求解到的和可能是局部極小值而非全局 最小值解,這是由模型函數的非凸性決定的。但是我們在實踐中發現,通過梯度下降算法 求得的數值解,它的性能往往都能優化得很好,可以直接使用求解到的數值解和來近似作為最優解。
思考
首先假設個輸入的數學模型為線性模型之後,只採樣 + 1個數據點就可以估計線性模型的參數和。引入觀測誤差後,通過梯度下降算法,我們可以採樣多組數據點循環優化得到和的數值解。如果我們換一個角度來看待這個問題,它其實可以理解為一組連續值(向量)的預測問題。給定數據集,我們需要從中學習到數據的真實模型,從而預測未見過的樣本的輸出值。在假定模型的類型後,學習過程就變成了搜索模型參數的問題,比如我們假設為線性模型,那麼訓練過程即為搜索線性模型的和參數的過程。訓練完成後,利用學到的模型,對於任意的新輸入,我們就可以使用學習模型輸出值作為真實值的近似。從這個角度來看,它就是一個連續值的預測問題。
未完待續 ……歡迎關注