本節不僅介紹了Logistic回歸在sklearn中模型應用,還介紹了liblinear、牛頓法、擬牛頓法(DFP算法、BFGS算法、L-BFGS算法)、梯度下降、隨機梯度下降等,正文如下,歡迎圍觀喔~~(我的字跡請大家別吐槽了,已放棄治療,捂臉~`~)
上一篇主要是學習了Logistic回歸(Logistic Regression)算法筆記(一)-Python,用基礎Python實現了Logistic回歸算法。本文將利用scikit-learn中的相關模塊學習Logistic回歸算法的實現
在scikit-learn中,主要是基于LogisticRegression模型來解決Logistic回歸算法,其中,有兩種不同的代價函數(cost function):
L1:
L2:
對于L1、L2兩式子的解釋:每個式子中前面那項是正則化項(Regularizer)(包含w的范數),后面那項是損失函數(loss function),參數C控制了兩者在最終的損失函數中所占的比重。求解w參數的方法根據L1/L2代價函數的不同,也存在不同的求解擬合參數的方法:
1)‘liblinear’->liblinear是一個針對線性分類場景而設計的工具包,支持線性的SVM和Logistic回歸等,但是無法通過定義核函數的方式實現非線性分類。
備注:libSVM是一套完整的SVM模型實現。用戶可以在libSVM中使用核函數來訓練非線性的分類器,當然也能使用更基礎的線性SVM。由于支持核函數的擴展,libSVM理論上具有比liblinear更強的分類能力,能夠處理更為復雜的問題。但是針對線性分類,liblinear無論是在訓練上還是在預測上,都比libSVM高效得多。此外,受限于算法,libSVM往往在樣本量過萬之后速度就比較慢了,如果樣本量再上升一個數量級,那么通常的機器已經無法處理了。但使用liblinear,則完全不需要有這方面的擔憂,即便百萬千萬級別的數據,liblinear也可以輕松搞定,因為liblinear本身就是為了解決較大規模樣本的模型訓練而設計的。關于libSVM和liblinear兩者差異,不妨看看LIBSVM與LIBLINEAR
接下來的一些求解擬合參數的方法需要先了解牛頓法以及相關的知識等,先來簡單介紹一下
牛頓法(Newton's method)又稱為牛頓-拉弗森方法(Newton-Raphson method),它是一種在實數域和復數域上近似求解方程的方法。該方法使用函數f(x)的泰勒級數的前幾項來尋找方程f(x)=0的根。
在最優化的問題中,線性最優化至少可以使用單純行法求解,但對于非線性優化問題,牛頓法提供了一種求解的辦法。假設任務是優化一個目標函數f,求函數f的極大極小問題,可以轉化為求解函數f的導數f'=0的問題,這樣求可以把優化問題看成方程求解問題(f'=0)。剩下的問題就和第一部分提到的牛頓法求解很相似了。如果是高維情況,那么牛頓法的迭代公式見圖3:
圖3中的H表示Hessian矩陣,見圖4
在上面牛頓法公式的得出過程中,其實用到了凸優化的知識,關于凸優化的知識,如果時充裕,建議看(Convex-optimization)凸優化-英文版,這個電子版是免費下載的,贊!
雖然牛頓法比一般的梯度下降法收斂速度快,但是在高維情況下,計算目標函數的二階偏導數的復雜度很大,而且有時候目標函數的海森矩陣無法保持正定,不存在逆矩陣,此時牛頓法將不再能使用。因此,人們提出了擬牛頓法。這個方法的基本思想是:不用二階偏導數而構造出可以近似Hessian矩陣(或Hessian矩陣的逆矩陣)的正定對稱矩陣,進而再逐步優化目標函數。不同的構造方法就產生了不同的擬牛頓法(Quasi-Newton Methods)。
介紹一下擬牛頓條件:
看到了吧,此時已經不需要求解二階倒數啦,B_k+1(x_k+1-x_k)=Δf(x_k+1)-Δf(x_k)(割線方程)。上面提到根據擬牛頓條件,有不同的擬牛頓方法,具體有哪些呢:-》》DFP算法、BFGS算法、L-BFGS算法等。接下來再分別介紹一下,嘿嘿。
DFP算法:該算法是以William C. Davidon、Roger Fletcher、Michael J.D.Powell三人的首字母命名,最初由Davidon于1959年提出,隨后被Fletcher和Powell研究和推廣,是最早的擬牛頓法。
BFGS算法:該算法是以發明者Broyden、Fletcher、Goldfarb和Shanno四人名字的首字母命名的,BFGS算法比DFP算法更優,目前它已經成為求解無約束非線性優化問題最常用的方法之一。BFGS算法已經有較完善的局部收斂理論,對其全局收斂性的研究也取得了重要成果。
L-BFGS(Limited-memory BFGS)算法:考慮到在數據很大時,BFGS中的D_k也會占用很大的空間,因此,L-BFGS對BFGS算法進行近似:不再存儲完整的矩陣D_k,而是存儲計算過程中的向量序列{s_i},{y_i}需要矩陣D_k時,利用向量序列{s_i},{y_i}的計算來代替。而且也不是將向量序列{s_i},{y_i}全部儲存,而是固定存儲最新的n個(n可以根據用戶自己機器的內存來參考)每次計算D_k時,只利用最新的n個向量序列{s_i},{y_i}。
牛頓法和擬牛頓法先介紹到這里,繼續回來sklearn中的Logistic回歸模型。在該模型的計算參數的方法,除了liblinear方法,接著介紹其他的:
2)lbfgs-》L-BFGS算法,如上所述
3)newton-cg-》牛頓法,如上所述
4)sag->Stochastic Average Gradient descent
好吧,又得停下來解釋sag啦,關于梯度下降算法的知識,推薦大家看一篇英文博客An overview of gradient descent optimization algorithms? ,隔空膜拜~~
(1)梯度下降算法(Gradient descent)
梯度:在向量微積分中,標量場的梯度是一個向量場。標量場中某一點的梯度指向在這點標量場增長最快的方向。
圖10-圖12中,關于梯度的介紹,見維基百科-梯度
在一些回歸分析中,為了求解參數,構建了類似如圖13的最優化函數,其中,h_θ(x^i)表示基于算法預估結果,J_θ(θ)表示代價函數,為了求解θ使得J_θ(θ)最小,那么就要不斷對J_θ(θ)求梯度,且滿足圖14的迭代形式,因為每次都是當前的參數減去梯度,所以叫做梯度下降法
梯度下降方法的缺點:每一次迭代,都要使用數據集合中的全部數據,當數據量很大時,計算量非常大,導致計算速度也會很慢。因此,出現了隨機梯度下降法(Stochastic gradient descent,SGD)
隨機梯度下降法SGD:SGD也是利用圖13-14的方式,但是每一次迭代,他不是要利用全部的數據,而是每次迭代只用一個樣本,在樣本量很大的情況下,可能只需要部分樣本就可以求解出最好的參數了。但是也正是因為這樣的隨機,導致SGD的收斂速度要小于梯度下降法的收斂速度,也就是說為了達到同樣的精度,SGD需要的總迭代次數要大于梯度下降。因此出現了Stochastic Average Gradient descent(SAG)這樣的優化算法
隨機平均梯度下降法(Stochastic Average Gradient descent,SAG):
SAG算法在內存中為每個樣本都維護一個舊的梯度y_i,隨機選擇一個樣本i來更新d,并用d來更新參數x。具體來說,更新的項d來自于用新的梯度f^'_i(x)替換d中的舊梯度y_i,這就是
的意思。如此,每次更新的時候僅僅需要計算一個樣本的梯度,而不是所有樣本的梯度。計算開銷與SGD無異,但是內存開銷要大得多。已經證明SAG是一種線性收斂算法,這個速度遠比SGD快。
嗯,在sklearn中求解Logistic回歸中參數的方法基本就是這些,終于可以開始討論Logistic回歸模型了~~呀比~
Logistic回歸模型-LogisticRegression
classsklearn.linear_model.LogisticRegression(penalty='l2',dual=False,tol=0.0001,C=1.0,fit_intercept=True,intercept_scaling=1,class_weight=None,random_state=None,solver='liblinear',max_iter=100,multi_class='ovr',verbose=0,warm_start=False,n_jobs=1)
別暈,馬上是參數分析:
1)penalty->代價函數,默認是上面提到的L2;
2)dual->默認是false。如果是true,則表示使用‘Dual formulation’,這種情況僅僅適合于penalty='l2'且solver用的是liblinear的情況;只要樣本數大于特征數值,最好將dual=false
3)tol->停止條件(Tolerance for stopping criteria)。默認為float,default: 1e-4
4)C->見T圖1-2中的C,C越大,那么表示每個式子中左部分的正則化在整個代價函數中占得比重就更小,默認為1.0,必須是正的浮點數(a positive float)
5)fit_intercept->bool, default: True。 Specifies if a constant (a.k.a. bias or intercept) should be added to the decision function.表示是否添加特征值,與下面的intercept_scaling有關
6)intercept_scaling->float,默認是1.0。intercept_scaling屬性起作用的條件:solver是'liblinear' 并且fit_intercept=true。那么在這種條件下,特征向量X就變為了[X,intercept_scaling],相當于多了一個合成的特征值
7)class_weight->dict or ‘balanced’, default: None. 默認None表示所有的y類別權重一致
8)max_iter->最大迭代次數,默認為100;此值僅僅當solver是“newton-cg,sag,或者lbfgs”
9)solver->{'newton-cg','lbfgs','liblinear','sag'},默認取值是'liblinear'。關于這四種求解參數的方法,他們與代價函數L1,L2之間的試用關系見圖17
解釋:(1)如果數據集比較小,那么利用'liblinear'就可以啦;(2)sag在處理大數據集時速度更快;(3)如果不是二分類,而是多種y類型的區分,那么liblinear就不適合了,只能用剩下的三種了;(4)'newton-cg','lbfgs','sag'這三種solver只可以處理代價函數是L2的情形;(5)在使用 ‘sag’方法時,最好將各個特征的取值利用sklearn.preprocessing先處理為數量級是一個范圍的,比如都為0-1之間的,這樣才能有效的保證sag方法在使用時具有較快的收斂速度。
10)multi_class->str, {‘ovr’, ‘multinomial’}, default: ‘ovr’,這個參數是針對多元分類(二元以上,所以不包括solver='linlinear')。‘ovr’表示binary擬合(大概就是每一類要不是0,要不是 ? ?1);‘multinomial’表示在擬合過程中,the loss minimised is the multinomial loss fit across the entire probability distribution.(非常不熟悉多類分類,所以不清楚這個設置到底啥意思,請大神指點,我也會在以后慢慢了解)
11)verbose->冗余值,非負整數, default: 0。僅僅在solver為linlinear或者lbfgs時,設置該取值
12)warm_start->When set to True, reuse the solution of the previous call to fit as initialization, otherwise, just erase the previous solution. Useless for liblinear solver.
終于可以寫代碼了,好開心 · · ·
栗子:繼續以sklearn的dataset中的iris數據集來計算,取其前兩個特征:
1)準備數據
2)利用數據,訓練Logistic回歸模型
3)在兩個特征值的取值范圍內,構建網格,產生一些介于最值之間的等差數據數組
4)預測網格內的數據
5)繪制邊界
在上圖的繪制中,用到了pcolormesh()函數,它類似于pcolor()函數,也是最坐標點就行著色,但是不同的是:
因為此次分類中,y的取值為0,1,2三類,所以對應的上圖24中有三種顏色。
本來還想再寫一個sklearn中的Logistic回歸的例子,但是限于篇幅,這篇文章太長了,以后深入分析的時候再舉例~`~
好噠,這篇先到這里,希望有點用途,也希望大神們不吝賜教,謝謝大家啦~~