一誊锭、前言
本文從Logistic回歸的原理開始講起,補充了書上省略的數(shù)學推導弥锄。本文可能會略顯枯燥丧靡,理論居多,Sklearn實戰(zhàn)內(nèi)容會放在下一篇文章籽暇。自己慢慢推導完公式温治,還是蠻開心的一件事。
二戒悠、Logistic回歸與梯度上升算法
Logistic回歸是眾多分類算法中的一員熬荆。通常,Logistic回歸用于二分類問題绸狐,例如預測明天是否會下雨卤恳。當然它也可以用于多分類問題累盗,不過為了簡單起見,本文暫先討論二分類問題突琳。首先若债,讓我們來了解一下,什么是Logistic回歸拆融。
1蠢琳、Logistic回歸
假設現(xiàn)在有一些數(shù)據(jù)點,我們利用一條直線對這些點進行擬合(該線稱為最佳擬合直線)镜豹,這個擬合過程就稱作為回歸傲须,如下圖所示:
歸是分類方法,它利用的是Sigmoid函數(shù)閾值在[0,1]這個特性趟脂。Logistic回歸進行分類的主要思想是:根據(jù)現(xiàn)有數(shù)據(jù)對分類邊界線建立回歸公式泰讽,以此進行分類。其實散怖,Logistic本質(zhì)上是一個基于條件概率的判別模型(Discriminative Model)菇绵。
所以要想了解Logistic回歸,我們必須先看一看Sigmoid函數(shù) 镇眷,我們也可以稱它為Logistic函數(shù)咬最。它的公式如下:
z是一個矩陣,θ是參數(shù)列向量(要求解的)欠动,x是樣本列向量(給定的數(shù)據(jù)集)永乌。θ^T表示θ的轉(zhuǎn)置。g(z)函數(shù)實現(xiàn)了任意實數(shù)到[0,1]的映射具伍,這樣我們的數(shù)據(jù)集([x0,x1,...,xn])翅雏,不管是大于1或者小于0,都可以映射到[0,1]區(qū)間進行分類人芽。hθ(x)給出了輸出為1的概率望几。比如當hθ(x)=0.7,那么說明有70%的概率輸出為1萤厅。輸出為0的概率是輸出為1的補集橄抹,也就是30%。
如果我們有合適的參數(shù)列向量θ([θ0,θ1,...θn]^T)惕味,以及樣本列向量x([x0,x1,...,xn])楼誓,那么我們對樣本x分類就可以通過上述公式計算出一個概率,如果這個概率大于0.5名挥,我們就可以說樣本是正樣本疟羹,否則樣本是負樣本。
舉個例子,對于"垃圾郵件判別問題"榄融,對于給定的郵件(樣本)参淫,我們定義非垃圾郵件為正類,垃圾郵件為負類愧杯。我們通過計算出的概率值即可判定郵件是否是垃圾郵件黄刚。
那么問題來了!如何得到合適的參數(shù)向量θ?
根據(jù)sigmoid函數(shù)的特性民效,我們可以做出如下的假設:
式即為在已知樣本x和參數(shù)θ的情況下,樣本x屬性正樣本(y=1)和負樣本(y=0)的條件概率涛救。理想狀態(tài)下畏邢,根據(jù)上述公式,求出各個點的概率均為1检吆,也就是完全分類都正確舒萎。但是考慮到實際情況,樣本點的概率越接近于1蹭沛,其分類效果越好臂寝。比如一個樣本屬于正樣本的概率為0.51,那么我們就可以說明這個樣本屬于正樣本摊灭。另一個樣本屬于正樣本的概率為0.99咆贬,那么我們也可以說明這個樣本屬于正樣本。但是顯然帚呼,第二個樣本概率更高掏缎,更具說服力。我們可以把上述兩個概率公式合二為一:
合并出來的Loss煤杀,我們稱之為損失函數(shù)(Loss Function)眷蜈。當y等于1時,(1-y)項(第二項)為0沈自;當y等于0時酌儒,y項(第一項)為0。為s了簡化問題枯途,我們對整個表達式求對數(shù)忌怎,(將指數(shù)問題對數(shù)化是處理數(shù)學問題常見的方法):
這個損失函數(shù),是對于一個樣本而言的柔袁。給定一個樣本呆躲,我們就可以通過這個損失函數(shù)求出,樣本所屬類別的概率捶索,而這個概率越大越好插掂,所以也就是求解這個損失函數(shù)的最大值。既然概率出來了,那么最大似然估計也該出場了辅甥。假定樣本與樣本之間相互獨立酝润,那么整個樣本集生成的概率即為所有樣本生成概率的乘積,再將公式對數(shù)化璃弄,便可得到如下公式:
其中要销,m為樣本的總數(shù),y(i)表示第i個樣本的類別夏块,x(i)表示第i個樣本疏咐,需要注意的是θ是多維向量,x(i)也是多維向量脐供。
綜上所述浑塞,滿足J(θ)的最大的θ值即是我們需要求解的模型。
怎么求解使J(θ)最大的θ值呢政己?因為是求最大值酌壕,所以我們需要使用梯度上升算法。如果面對的問題是求解使J(θ)最小的θ值歇由,那么我們就需要使用梯度下降算法卵牍。面對我們這個問題,如果使J(θ) := -J(θ)沦泌,那么問題就從求極大值轉(zhuǎn)換成求極小值了糊昙,使用的算法就從梯度上升算法變成了梯度下降算法,它們的思想都是相同的赦肃,學會其一溅蛉,就也會了另一個。本文使用梯度上升算法進行求解他宛。
2船侧、梯度上升算法
說了半天,梯度上升算法又是啥厅各?J(θ)太復雜镜撩,我們先看個簡單的求極大值的例子督禽。一個看了就會想到高中生活的函數(shù):
來吧淘这,做高中題。這個函數(shù)的極值怎么求腾供?顯然這個函數(shù)開口向下憔古,存在極大值遮怜,它的函數(shù)圖像為
求極值,先求函數(shù)的導數(shù):
令導數(shù)為0鸿市,可求出x=2即取得函數(shù)f(x)的極大值锯梁。極大值等于f(2)=4
但是真實環(huán)境中的函數(shù)不會像上面這么簡單即碗,就算求出了函數(shù)的導數(shù),也很難精確計算出函數(shù)的極值陌凳。此時我們就可以用迭代的方法來做剥懒。就像爬坡一樣,一點一點逼近極值合敦。這種尋找最佳擬合參數(shù)的方法初橘,就是最優(yōu)化算法。爬坡這個動作用數(shù)學公式表達即為:
其中充岛,α為步長保檐,也就是學習速率,控制更新的幅度崔梗。效果如下圖所示:
比如從(0,0)開始展东,迭代路徑就是1->2->3->4->...->n,直到求出的x為函數(shù)極大值的近似值炒俱,停止迭代。我們可以編寫Python3代碼爪膊,來實現(xiàn)這一過程:
"""
函數(shù)說明:梯度上升算法測試函數(shù)
求函數(shù)f(x) = -x^2 + 4x的極大值
def Gradient_Ascent_test():
? ? def f_prime(x_old):? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #f(x)的導數(shù)
? ? ? ? return -2 * x_old + 4
? ? x_old = -1? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #初始值权悟,給一個小于x_new的值
? ? x_new = 0? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #梯度上升算法初始值,即從(0,0)開始
? ? alpha = 0.01? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #步長推盛,也就是學習速率峦阁,控制更新的幅度
? ? presision = 0.00000001? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #精度,也就是更新閾值
? ? while abs(x_new - x_old) > presision:
? ? ? ? x_old = x_new
? ? ? ? x_new = x_old + alpha * f_prime(x_old)? ? ? ? ? ? #上面提到的公式
? ? print(x_new)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #打印最終求解的極值近似值
if __name__ == '__main__':
? ? Gradient_Ascent_test()
代碼運行結(jié)果如下:
結(jié)果很顯然耘成,已經(jīng)非常接近我們的真實極值2了榔昔。這一過程,就是梯度上升算法瘪菌。那么同理撒会,J(θ)這個函數(shù)的極值,也可以這么求解师妙。公式可以這么寫:
那么诵肛,現(xiàn)在我只要求出J(θ)的偏導,就可以利用梯度上升算法默穴,求解J(θ)的極大值了怔檩。
那么現(xiàn)在開始求解J(θ)對θ的偏導,求解如下:
知道了蓄诽,梯度上升迭代公式薛训,我們就可以自己編寫代碼,計算最佳擬合參數(shù)了仑氛。