線性迴歸的數學原理以及代碼實現

線性迴歸的數學原理以及代碼實現

首先要說的是線性模型想要得到的是一個線性組合。狹義的線性迴歸是想要把所有的點(或者叫特徵)用一條直線來擬合,也就是圖像上的點要儘可能地落到直線上。而廣義的線性迴歸就不一定非要是直線了,例如在邏輯迴歸中用的就是一條對數機率的曲線,也就是圖像上的點要儘可能的落到那條曲線上面。

在這篇文章中主要對線性迴歸作討論:
首先呈上線性模型

f(x)=wTx+b

【優點】

每個x前面的w,也就是係數很直觀,他們就是權重係數,當我們擬合出一個模型的時候,對於每一個x我們都能通過w知道它到底重要不重要。

【缺點】

線性模型,顧名思義,他只對線性的數據點擬合的好,而現實中存在着大量的非線性特徵,擬合效果就大打折扣了。


線性迴歸是用梯度下降法對最小二乘誤差進行優化

我們既然已經確定了任務是找到這樣一條直線,f(x)=wTx+b ,使得這條直線能很好地擬合我們的樣本點。那我們最理想的情況就是所有的樣本點都在這條直線上,Perfect!也就是說,在這個時候,所有樣本點到直線的距離爲0,同時他們的距離之和也肯定爲0了。

但是總歸要回到現實中來,不可能有那麼完美的例子,那我們只能力求他們的距離之和接近0了。或者再退一步,接近不了0也行,距離之和越小總還是越好的吧!那麼就有了下面的數學表述:

yi 代表第i個點的真實值;
f(xi) 代表通過模型(函數f )的預測值,也就是我們的直線;
於是就有了距離的表達式:

distance=(yif(xi))2

這裏用到了平方,是一種數學的技巧,爲了達成下面兩個目的:
+ 距離有正有負,我們這個加和的思想可不是爲了抵消正負值的,所以我們必須要去掉他們的符號
+ 去掉符號也可以用絕對值,但是平方之後有一個放大的效應:如果距離不是很大,平方之後就還好,如果距離很大,平方之後就會被放的更大。(這裏可以想象一下y=x2 的函數圖像,x越大,y就跟着變得更大)

【簡單講兩句】:
上面這個距離表達式,學名叫做“歐式距離”,是計算距離的一種常用的數學方法,今後在機器學習其他算法中也會經常遇到。

我們繼續之前的思路,就是要最小化這個距離值,由於直線由w和b決定,那麼我們需要優化的參數就是w和b,換成數學語言,就是:

我們希望要距離平方和最小化的方法,稱爲最小二乘法

如果從損失函數(loss function)的角度看,這個叫做“平方損失”。如果我們用J(θ) 來表達損失函數,然後再做下面幾個數學變換:
+ 令J(θ)=12(yif(xi))2

argmin(w,b)i=1mJ(θ)=
argmin(w,b)i=1m12(yif(xi))2

在這裏前面有了一個1/2的操作,純粹了爲了數學上的方便,反正在最小化的計算中,數倍的縮放沒有什麼影響


線性迴歸是殘差高斯分佈的最大似然估計

殘差
殘差就是預測值和真實值之間的差,也就是上面的 (yif(xi)) 這一項。

我們通常認爲線性迴歸的殘差應該滿足均值爲0,方差爲 σ2 的正態分佈的假設。誤差爲0最好,越往兩邊走應該越少。

正態分佈x概率表達式:
p(x)=12πσexp[x22σ2]

上式中的x即是線性迴歸的誤差/殘差,那麼就把x替換成 (yif(xi)) 得到;

p((yif(xi)),(w,b))=12πσexp[(yif(xi))22σ2]

接下來,我們想要達成,或者說最大限度地達成我們之間關於殘差的假設,我們就必須讓這個概率最大,也就是用極大似然法來求解,也就是最大化樣本中每一個點分佈的乘積。

L(w,b)=i=1m12πσexp[(yif(xi))22σ2]

由於連乘計算難度大,我們兩邊都取對數,這樣就變成連加:

l(w,b)=i=1mlog12πσexp[(yif(xi))22σ2]

進一步化簡:

l(w,b)=mlog12πσ1σ212i=1m(yif(xi))2

去掉一些常數項,得到我們要最大化的目標:

12i=1m(yif(xi))2

殊途同歸啊!


下面開始求解:
+ 向量化w、x和y,在這裏統統用大寫字母表示向量
+ 把b吸入向量w中,他們兩個組合其他就是我們的參數 θ

向量化的表達方式可以讓我們在接下來的運算中取消加和符號,看上去更加簡便一些

argmin12(YθX)2

J(θ) 經過向量運算得到:

12(YθX)T(YθX)
=12(YTθTXT)(YθX)
=12(θTXTXθθTXTYYTXθYTY)

結果對 θ 求偏導:

【矩陣求偏導】

ABB=ATYTXθ

ATBA=BθTXTY

ATBAA=2ABθTXTXθ

J(θ)θ=12(2XTXθXTYXTY0)=(XTXθXTY)

令偏導等於0:

XTXθXTY=0
這裏暫時默認XTX 是可逆的

得出參數 θ=(XTX)1XTY 我們利用計算出來的參數,可以直接寫出線性迴歸的代碼來:

import numpy as np

def train(X,y):
    """訓練數據"""
    # 如果X^T·X是可逆的話:
    if np.linalg.det(X.T * X) != 0:
    # 計算參數theta
        theta =  ((X.T.dot(X).I).dot.(X.T).dot(y))
        return theta

def test(x,theta):
    """擬合數據"""
    return x.T.dot(theta)

*在本篇文章中涉及但是沒有深入的概念會在後續的文章中陸續講解,包括但不限於:
+ 極大似然法及其概率背景
+ 正則化

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