1. 程式人生 > >機器學習經典演算法詳解及Python實現--線性迴歸(Linear Regression)演算法

機器學習經典演算法詳解及Python實現--線性迴歸(Linear Regression)演算法

(一)認識迴歸

迴歸是統計學中最有力的工具之一。機器學習監督學習演算法分為分類演算法和迴歸演算法兩種,其實就是根據類別標籤分佈型別為離散型、連續性而定義的。顧名思義,分類演算法用於離散型分佈預測,如前面講過的KNN、決策樹、樸素貝葉斯、adaboost、SVM、Logistic迴歸都是分類演算法;迴歸演算法用於連續型分佈預測,針對的是數值型的樣本,使用迴歸,可以在給定輸入的時候預測出一個數值,這是對分類方法的提升,因為這樣可以預測連續型資料而不僅僅是離散的類別標籤。

迴歸的目的就是建立一個迴歸方程用來預測目標值,迴歸的求解就是求這個迴歸方程的迴歸係數。預測的方法當然十分簡單,迴歸係數乘以輸入值再全部相加就得到了預測值。

1,迴歸的定義

迴歸最簡單的定義是,給出一個點集D,用一個函式去擬合這個點集,並且使得點集與擬合函式間的誤差最小,如果這個函式曲線是一條直線,那就被稱為線性迴歸,如果曲線是一條二次曲線,就被稱為二次迴歸。

2,多元線性迴歸

假定預測值與樣本特徵間的函式關係是線性的,迴歸分析的任務,就在於根據樣本X和Y的觀察值,去估計函式h,尋求變數之間近似的函式關係。定義:


其中,n = 特徵數目;

xj= 每個訓練樣本第j個特徵的值,可以認為是特徵向量中的第j個值。

為了方便,記x0= 1,則多變數線性迴歸可以記為:

 ,(θ、x都表示(n+1,1)維列向量)

Note:注意多元和多次是兩個不同的概念,“多元”指方程有多個引數,“多次”指的是方程中引數的最高次冪。多元線性方程是假設預測值y與樣本所有特徵值符合一個多元一次線性方程。

3,廣義線性迴歸

用廣義的線性函式:

    

wj是係數,w就是這個係數組成的向量,它影響著不同維度的Φj(x)在迴歸函式中的影響度,Φ(x)是可以換成不同的函式,這樣的模型我們認為是廣義線性模型,Φ(x)=x時就是多元線性迴歸模型。

(二)線性迴歸的求解

說到迴歸,常常指的也就是線性迴歸,因此本文闡述的就是多元線性迴歸方程的求解。假設有連續型值標籤(標籤值分佈為Y)的樣本,有X={x1,x2,...,xn}個特徵,迴歸就是求解迴歸係數θ=θ0, θ1,…,θn。那麼,手裡有一些X和對應的Y,怎樣才能找到θ呢? 在迴歸方程裡,求得特徵對應的最佳迴歸係數的方法是最小化誤差的平方和。這裡的誤差是指預測y值和真實y值之間的差值,使用該誤差的簡單累加將使得正差值和負差值相互抵消,所以採用平方誤差(最小二乘法)。平方誤差可以寫做:


至於為何採用最小誤差平方和來求解,其統計學原理可參考“對線性迴歸、邏輯迴歸、各種迴歸的概念學習”的“深入線性迴歸”一節。

在數學上,求解過程就轉化為求一組θ值使求上式取到最小值,那麼求解方法有梯度下降法、Normal Equation等等。梯度下降有如下特點:需要預先選定步長a、需要多次迭代、特徵值需要Scaling(統一到同一個尺度範圍)。因此比較複雜,還有一種不需要迭代的求解方式--Normal Equation,簡單、方便、不需要Feature Scaling。Normal Equation方法中需要計算X的轉置與逆矩陣,計算量很大,因此特徵個數多時計算會很慢,只適用於特徵個數小於100000時使用;當特徵數量大於100000時使用梯度法。另外,當X不可逆時就有嶺迴歸演算法的用武之地了。

下面就概括一下常用的幾種求解演算法。

1,梯度下降法(Gradient Descent)

根據平方誤差,定義該線性迴歸模型的損耗函式(Cost Function)為:   

,(係數是為了方便求導展示)

線性迴歸的損耗函式的值與迴歸係數θ的關係是碗狀的,只有一個最小點。線性迴歸的求解過程如同Logistic迴歸,區別在於學習模型函式hθ(x)不同,梯度法具體求解過程參考“機器學習經典演算法詳解及Python實現---Logistic迴歸(LR)分類器”。

2,Normal Equation(也叫普通最小二乘法)

Normal Equation演算法也叫做普通最小二乘法(ordinary least squares),其特點是:給定輸人矩陣X,如果XTX的逆存在並可以求得的話,就可以直接採用該方法求解。其求解理論也十分簡單:既然是是求最小誤差平方和,另其導數為0即可得出迴歸係數。


矩陣X為(m,n+1)矩陣(m表示樣本數、n表示一個樣本的特徵數),y為(m,1)列向量。 

上述公式中包含XTX, 也就是需要對矩陣求逆,因此這個方程只在逆矩陣存在的時候適用。然而,矩陣的逆可能並不存在,後面“嶺迴歸”會討論處理方法。

3,區域性加權線性迴歸

線性迴歸的一個問題是有可能出現欠擬合現象,因為它求的是具有最小均方誤差的無偏估計。顯而易見,如果模型欠擬合將不能取得最好的預測效果。所以有些方法允許在估計中引人一些偏差,從而降低預測的均方誤差。其中的一個方法是區域性加權線性迴歸(LocallyWeightedLinearRegression, LWLR )。在該演算法中,我們給待預測點附近的每個點賦予一定的權重.於是公式變為:

,W是(m,m)矩陣,m表示樣本數。

LWLR使用 “核”(與支援向量機中的核類似)來對附近的點賦予更高的權重。核的型別可以自由選擇,最常用的核就是高斯核,高斯核對應的權重如下:

,k需要優化選擇.

區域性加權線性迴歸也存在一個問題,即增加了計算量,因為它對每個點做預測時都必須使用整個資料集,而不是計算出迴歸係數得到迴歸方程後代入計算即可。因此該演算法不被推薦。

4,嶺迴歸(ridge regression)和縮減方法

當資料的樣本數比特徵數還少時候,矩陣XTX的逆不能直接計算。即便當樣本數比特徵數多時,XTX 的逆仍有可能無法直接計算,這是因為特徵有可能高度相關。這時可以考慮使用嶺迴歸,因為當XTX 的逆不能計算時,它仍保證能求得迴歸引數。簡單說來,嶺迴歸就是對矩陣XTX進行適當的修正,變為(I是單位矩陣,對角線為1,其他為0)從而使得矩陣非奇異,進而能對式子求逆。在這種情況下,迴歸係數的計算公式將變成:

 

為了使用嶺迴歸和縮減技術,首先需要對特徵做標準化處理,使各特徵值的取值尺度範圍相同,從而保證各特徵值的影響力是相同的。

如何設定 λ 的值?通過選取不同的λ 來重複上述測試過程,最終得到一個使預測誤差最小的λ 。可通過交叉驗證獲取最優值--在測試資料上,使誤差平方和最小。

嶺迴歸最先用來處理特徵數多於樣本數的情況,現在也用於在估計中加人偏差,從而得到更好的估計。事實上,上述公式是在最小平方誤差和公式裡引入了每個特徵的懲罰因子得到,為的是防止過度擬合(過於複雜的模型),在損失函式裡增加一個每個特徵的懲罰因子,這就是線性迴歸的正則化(參考“Coursera公開課筆記: 斯坦福大學機器學習第七課“正則化(Regularization)”)。


Note:θ0是一個常數,x0=1是固定的,那麼θ0不需要懲罰因子,嶺迴歸公式中的I的第一個元素要為0。

這裡通過引入λ來限制了所有誤差平方之和,通過引人該懲罰項,能夠減少不重要的引數,這個技術在統計學中也叫做縮減(shrinkage )。縮減方法可以去掉不重要的引數,因此能更好地理解資料。此外,與簡單的線性迴歸相比,縮減法能取得更好的預測效果,縮減法還可以看做是對一個數據模型的擬合採取了偏差(預測值與真實值差距)、方差(不同預測模型間的差距)折中方案,增加偏差的同時減少方差。偏差方差折中是一個重要的概念,可以幫助我們理解現有模型並做出改進,從而得到更好的模型。嶺迴歸是縮減法的一種,相當於對迴歸係數的大小施加了限制。另一種很好的縮減法是lasso。lasso難以求解,但可以使用計算簡便的逐步線性迴歸方法來求得近似結果。還有一些其他縮減方法,如lasso、LAR、PCA迴歸以及子集選擇等。與嶺迴歸一樣,這些方法不僅可以提高預測精確率,而且可以解釋迴歸係數。

5,迴歸模型效能度量

資料集上計算出的迴歸方程並不一定意味著它是最佳的,可以便用預測值yHat和原始值y的相關性來度量回歸方程的好壞。相關性取值範圍0~1,值越高說明迴歸模型效能越好。

線性迴歸是假設值標籤與特徵值之間的關係是線性的,但有些時候資料間的關係可能會更加複雜,使用線性的模型就難以擬合,就需要引入多項式曲線迴歸(多元多次擬合)或者其他迴歸模型,如迴歸樹。

(三)線性迴歸的Python實現

本線性迴歸的學習包中實現了普通最小二乘和嶺迴歸演算法,因梯度法和Logistic Regression幾乎相同,也沒有特徵數>10000的樣本測試運算速度,所以沒有實現。為了支援多種求解方法、也便於擴充套件其他解法,linearRegress物件採用Dict來儲存相關引數(求解方法為key,迴歸係數和其他相關引數的List為value)。例如嶺迴歸演算法在LRDict中的key=‘ridge’,value=[ws, lamba,xmean,var, ymean]。因為嶺迴歸模型訓練和預測中需要對樣本進行feature scaling,所以才需要儲存xmean,var, ymean。linearRegress物件的屬性如其__init__函式所示:

Source Code:Copy
  1. class linearRegress(object):   
  2.     def __init__(self,LRDict = None,  **args):   
  3.         '''currently support OLS, ridge, LWLR            
  4.         '''  
  5.         obj_list = inspect.stack()[1][-2]   
  6.         self.__name__ = obj_list[0].split('=')[0].strip()   
  7.         if not LRDict:   
  8.             self.LRDict = {}   
  9.         else:   
  10.             self.LRDict = LRDict   
  11.             #to Numpy matraix  
  12.             if 'OLS' in self.LRDict:   
  13.                 self.LRDict['OLS'] = mat(self.LRDict['OLS'])   
  14.             if 'ridge' in self.LRDict:   
  15.                 self.LRDict['ridge'][0] = mat(self.LRDict['ridge'][0])   
  16.                 self.LRDict['ridge'][2] = mat(self.LRDict['ridge'][2])   
  17.                 self.LRDict['ridge'][3] = mat(self.LRDict['ridge'][3])   
  18.                 self.LRDict['ridge'][4] = mat(self.LRDict['ridge'][4])  

線性迴歸模型Python學習包下載地址為:

(四)應用和模型調優

對於需要根據一些特徵的組合來預測一個值(如預測房價、菜價等)且預測值和特徵組合間的關係是線性時既可以採用線性迴歸建立預測模型。通過機器學習演算法建立起一個模型之後就需要在使用中不斷的調優和修正,對於線性迴歸來說,最佳模型就是取得預測偏差和模型方差之間的平衡(高偏差就是欠擬合,高方差就是過擬合)。線性迴歸模型中模型調優和修正的方法包括:

- 獲取更多的訓練樣本 - 解決高方差

- 嘗試使用更少的特徵的集合 - 解決高方差

- 嘗試獲得其他特徵 - 解決高偏差

- 嘗試新增多項組合特徵 - 解決高偏差

- 嘗試減小 λ - 解決高偏差

- 嘗試增加 λ -解決高方差

參考: