1. 程式人生 > >線性迴歸演算法推導(Linear Regression)

線性迴歸演算法推導(Linear Regression)

 在現實生活中普遍存在著變數之間的關係,有確定的和非確定的。確定關係指的是變數之間可以使用函式關係式表示,還有一種是屬於非確定的(相關),比如人的身高和體重,一樣的身高體重是不一樣的。

線性迴歸:

           1: 函式模型(Model):

                 

           假設有訓練資料

                

          那麼為了方便我們寫成矩陣的形式

                

         2: 損失函式(cost):

                 現在我們需要根據給定的X求解W的值,這裡採用最小二乘法。   

a.最小二乘法:

      

何為最小二乘法,其實很簡單。我們有很多的給定點,這時候我們需要找出一條線去擬合它,那麼我先假設這個線的方程,然後把資料點代入假設的方程得到觀測值,求使得實際值與觀測值相減的平方和最小的引數。對變數求偏導聯立便可求。

              因此損失代價函式為:

            

        3: 演算法(algorithm):

             現在我們的目的就是求解出一個使得代價函式最小的W:

            a.矩陣滿秩可求解時(求導等於0):

                        

b.矩陣不滿秩時(梯度下降):

      梯度下降演算法是一種求區域性最優解的方法,對於F(x),在a點的梯度是F(x)增長最快的方向,那麼它的相反方向則是該點下降最快的方向,具體參考wikipedia

     原理:將函式比作一座山,我們站在某個山坡上,往四周看,從哪個方向向下走一小步,能夠下降的最快;

     注意:當變數之間大小相差很大時,應該先將他們做處理,使得他們的值在同一個範圍,這樣比較準確。

    1)首先對θ賦值,這個值可以是隨機的,也可以讓θ是一個全零的向量。

    2)改變θ的值,使得J(θ)按梯度下降的方向進行減少。

    描述一下梯度減少的過程,對於我們的函式J(θ)求偏導J: 

    Repeat  until convergence:{

     image

    下面是更新的過程,也就是θi會向著梯度最小的方向進行減少。θi表示更新之前的值,-後面的部分表示按梯度方向減少的量,α表示步長,也就是每次按照梯度減少的方向變化多少。

     image 

    }

     假設有資料集D時:

    

       對損失函式求偏導如下:

       

     使用矩陣表示(方便計算)

   

    從概率層面解釋-迴歸模型的目標函式:

          基本上每個模型都會有一個對應的目標函式,可以通過不同的最優化求解方法(梯度下降,牛頓法等等)對這些對應的目標函式進行求解。線性迴歸模型,我們知道實際上是通過多個自變數對自變數進行曲線擬合。我們希望找到一條可以較好擬合的曲線,

   那我們如何判斷一條曲線的擬合程度的好壞。上面講到,我們採用的是最小二乘法(預測值和真實值得誤差的平方和),那為什麼要用這個作為目標函式呢?

         可以從中心極限定理、高斯分佈來分析:

1.中心極限定理:

             設有n個隨機變數,X1,X2,X3,Xn,他們之間相互獨立,並且有相同的數學期望和均值。E(X)=u;D(x)=δ2.令Yn為這n個隨機變數之和。

                 

                Zn為X這幾個變數的規範和。

 2.高斯分佈

           假的給定一個輸入樣本x,我們得到預測值和真實值間的存在的誤差e,那麼他們的關係如下:

         

           而這裡,我們就可以假設e服從標準的高斯分佈。

           為什麼呢?迴歸模型的最終目標是建立自變數x和y之間的關係,我們希望通過x可以較為準確的表示結果y。而在實際應用場景中,很難甚至不可能把導致y結果的所有變數(特徵)都找到,放到迴歸模型裡面。

我們只存放那些認為比較重要的特徵。根據中心極限定理,把那些對結果影響比較小的(假設獨立分佈)之和認為是符合正態分佈是合理的。

             

     那麼x和y的條件概率:

                  

     那麼知道一條樣本的概率,我們就可以通過極大估計求似然函式,優化的目標函式如下:

     

  通過取對數我們可以發現極大似然估計的目標函式和最小平方誤差是一樣。

   在概率模型中,目標函式的極大和極小與極大似然估計是等價的。

        假設隨機變數為Y,和普通變數x存在相關關係,由於Y是隨機變數,對於x的各個確定值,Y有它的分佈(高斯)。

      假設為:

         

     使用極大似然估計可求解。

     我們知道對於下面公式:

         

      y為隨機變數,在c=E(y)時達到最小,這表明以E(y)作為y的近似是最好的。

 

線性迴歸推導和總結

1. 線性模型的基本形式

我們將形式為f(x)=w1x1 +w2x2+...+wnxn+b的方程式稱作線性方程。對於這個方程式,只要能求出w1、w2...wn和b,並代入x1、x2...xn,則可以求出對應的f(x)的值。

以上是線性方程式的描述,將此方程式轉移到機器學習中的線性模型,描述如下:

由給定的n個特徵值組成的特徵集示例x=(x1;x2;...;xn),其中xi是x在第i個特徵上的取值,線性迴歸模型的目標是通過學得w1、w2...wn和b,來準確預測f(x)的值。例如,銀行根據一個人的年齡x1、工作收入x2、是否有房子x3來預測給這個人的貸款額度,假設此時的w1為0.3,w2為0.3,w3為0.4,b為1則有f(x)=0.3*x1+0.3*x2+0.4*x3+1。在這裡wi即為相應特徵的權重。

f(x)=w1x1 +w2x2+...+wnxn+b即成為線性模型,其中的b稱為偏置項。此時,如果令w0為1,令x0為b,對該式進行整合,則一般用向量形式表示如下:

f(x) = wTx

2. 線性迴歸

    通常在說線性迴歸之前,總是要搞清楚“分類”和“迴歸”這兩個概念,這也是機器學習中很重要的概念。簡單來講,“分類”和“迴歸”都是預測目標值的過程,但是“分類”預測的是離散型變數,而“迴歸”預測的是連續型變數。還是用銀行貸款的例子來說:銀行是否給某人貸款,這是個“分類”問題,結果只有貸和不貸兩種(離散型變數);銀行給某個人貸多少錢,這是個“迴歸”問題,因為建立的模型f(x)=w1x1+w2x2+...+wnxn+b得到的是一條直線(直線上的所有點都是連續的),給這個人貸款的額度就是這個直線上的一個點。

通俗來講,線性迴歸就是找出一條直線,能夠最大限度的擬合所有給定的特徵值點(樣本點)。如下圖所示,其中的所有藍色小圓點即給定的多個樣本點示例,那條藍色直線就是經過線性迴歸擬合所有樣本點得到的預測線。這麼說來,線性迴歸和數學裡邊講的給定一條直線上的幾個點(理解為樣本點),要求你求出該直線方程的題是一樣一樣的。這裡的方程式稱為“迴歸方程”,要求的引數稱為“迴歸引數”。

但是,通常根據樣本點直接求解迴歸方程中的引數往往是難以求出的,此時就需要轉換思路。可以這樣來想,“預測值”之所以稱之為“預測值”,是因為和真實值之間總是有誤差存在的。那麼,只要我們能將誤差的最小值求出來,不就可以做到誤差值和真實值之間的“無限接近”了嗎?就好比張三從銀行只能貸款5000塊,但是銀行通過預測模型預測張三能貸款5100塊;李四實際能從銀行貸款10000塊,但是銀行通過預測模型預測李四能貸款9990塊。絕大多數情況下,銀行可能多給,也可能少給,這樣的小誤差是可以接受的。

設定y為真實值,f(x)為預測值,e為誤差值,則有如下公式:

y = f(x)+e

對於任意一個x(其中包括x1,x2...xn),總有其對應的y值。此時,線性迴歸的問題就變成了求解最小誤差值的問題。

 

3. 誤差值e最小化的求解

1)先說清楚一個概念:高斯分佈。

高斯分佈也稱為正態分佈,其概率密度函式如下:

其中, 、( >0)為常數,x的取值範圍為:負無窮到正無窮。即表示x服從引數 、 的正態分佈或高斯分佈。正態分佈的的曲線圖類似於“鐘形”,如下圖(來源於互動百科)所示:

那麼,高斯分佈和線性迴歸的誤差e有什麼關係呢?

因為誤差e(每個樣本會產生一個ei)是獨立並且具有相同的分佈,並且服從均值為0方差為w2的高斯分佈。-----請注意,這裡是一種機器學習中的假設,實際中可能並不存在完完全全的獨立和同分佈。這種假設沒有嚴密的數學邏輯來證明,但是採用該模型得出的結論卻是正確的。

還是採用銀行貸款的例子來進行解釋:

獨立的解釋:任何一個來銀行貸款的人之間是獨立而沒有關係的,這裡的沒有關係是指銀行是否貸款給張三,這和李四沒有關係。

同分布解釋:任何一個人都來我們模型假定的這家銀行貸款,遵守同樣的規則(現實中走後門託人找關係的情況這裡不考慮)。

高斯分佈在此情況下的解釋:對於每個貸款人,銀行可能多給也可能少給,但是大多數情況下上下浮動不會太大,只有極小情況下浮動較大,這些符合正常情況。

則,此時對於誤差e,代入高斯分佈的公式得x的概率密度函式:

p(x) =   (1)

又可以從y=f(x)+e推出e=y-f(x)=y-wTx,代入上式可得:

p(y|x;w) =     (2)

2)似然函式

以下是浙大《概率論與數理統計》一書中關於似然函式的定義:

對於線性迴歸而言,樣本值x(x1,x2,x3,...,xn)是已知的,此時需要計算在已知的樣本值上取得的最大概率L()值時的值,在本文中就是計算w的值(w為權重向量)。此時的似然函式如下:

對以上似然函式簡單解釋為:什麼樣的引數w,和已知的樣本資料X(x1,x2,...,xn)組合後,恰好是真實值。其實也就是似然函式取得最大值。則,問題轉換為求L(w)的最大值。

觀察L(w),發現是一堆資料相乘的操作,對於相乘的操作求其最大值是比較困難的。此時,將其轉換為對數來求解:

又由於對數運算的性質:logA*B=logA+logB,此時該表示式可轉換為如下:

此時,問題轉換為讓對數似然函式越大越好(對數似然函式越大==>似然函式越大)。分析以上展開後的logL(w)式子,可知為恆正的一個數,後邊的也是一個恆正的數,為了使得logL(w)越大,則需要越小,又因為是個恆正的常數,則轉化為

越小越好。

2)最小二乘法

由2)中可得,當前的求解物件已經轉換為求的最小值。令,該式即為最小二乘法的公式。用矩陣表示即為:

在該式中需要求解什麼樣的w使得J(w)最小。許多介紹線性迴歸的文章一上來就直接進入最小二乘法的使用,讓人很摸不著頭腦???這個公式是怎麼推匯出來的呢???本文給出了最小二乘法公式的推導過程。

對J(w)關於w求導如下:

至此,導數已經求出。J(w)取得最小值的地方一定是在其對w求偏導為0時的w處取得。

令此即我w矩陣的值。

值得注意的是,上式中包含,因此這個方程只在逆矩陣存在時適用,也就是說直接使用此公式要求必須是滿秩的。實際進行線性迴歸求解時,往往會遇到大量的特徵值,它們的個數比樣本點數還多,此時X就不再是滿秩矩陣了,進行求逆就會出現錯誤。這種情況下要進行線性迴歸求解,需要用到諸如嶺迴歸、lasso法、前向逐步迴歸等方法。不在本文範圍內介紹。

以下是執行《機器學習實戰》中線性迴歸的相關程式碼示例:

from numpy import *
import matplotlib.pyplot as plt
 
def loadDataSet(fileName):
    numFeat = len(open(fileName).readline().split('\t'))-1
    dataMat = [];
    labelMat = [];
    fr = open(fileName)
    for line in fr.readlines():
        lineArr = []
        curLine = line.strip().split('\t')
        for i in range(numFeat):
            lineArr.append(float(curLine[i]))
        dataMat.append(lineArr)
        labelMat.append(float(curLine[-1]))
    return dataMat, labelMat
 
def standRegres(xArr, yArr):
    xMat = mat(xArr)
    yMat = mat(yArr).T
    xTx = xMat.T*xMat
    if linalg.det(xTx) == 0.0: #判斷行列式是否為0,此處就是判斷是否可求逆
        print("This matrix is singular, cannot do inverse")
        return
    ws = xTx.I*(xMat.T*yMat)
    return ws
def main():
    xArr, yArr = loadDataSet('ex0.txt')
    print(xArr[0:2])
    ws = standRegres(xArr, yArr)
    print(ws)
    xMat = mat(xArr)
    yMat = mat(yArr)
    yHat = xMat * ws
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(xMat[:,1].flatten().A[0], yMat.T[:, 0].flatten().A[0])
    
    xCopy=xMat.copy()
    xCopy.sort(0)
    yHat=xCopy*ws
    ax.plot(xCopy[:,1], yHat)
    plt.show()
if __name__ == '__main__':
    main()

執行結果如下:

前文的那張展示線性迴歸擬合樣本點的圖就來自於這個例子,在這個程式碼示例中,是直接將前邊求出的w的公式代入進行計算的。