一、什么是邏輯回歸?
一種名為“回歸”的線性分類器,其本質是由線性回歸變化而來的,一種廣泛使用於分類問題中的廣義回歸算法
- 面試高危問題:Sigmoid函數的公式和性質
Sigmoid函數是一個S型的函數,當自變量z趨近正無窮時,因變量g(z)趨近於1,而當z趨近負無窮時,g(z)趨近 於0,它能夠將任何實數映射到(0,1)區間,使其可用於將任意值函數轉換為更適合二分類的函數。 因為這個性質,Sigmoid函數也被當作是歸一化的一種方法,與我們之前學過的MinMaxSclaer同理,是屬於 數據預處理中的“縮放”功能,可以將數據壓縮到[0,1]之內。區別在於,MinMaxScaler歸一化之后,是可以取 到0和1的(大值歸一化后就是1,小值歸一化后就是0),但Sigmoid函數只是無限趨近於0和1。
二、為什么需要邏輯回歸?
線性回歸對數據的要求很嚴格,比如標簽必須滿足正態分布,特征之間的多重共線性需要消除等等,而現實中很多真實情景的數據無法滿足這些要求,因此線性回歸在很多現實情境的應用效果有限。邏輯回歸是由線性回歸變化而來,因此它對數據也有一些要求,而我們之前已經學過了強大的分類模型決策樹和隨機森林,它們的分類效力很 強,並且不需要對數據做任何預處理。
邏輯回歸的優點:
- 1. 邏輯回歸對線性關系的擬合效果好到喪心病狂,特征與標簽之間的線性關系極強的數據,比如金融領域中的 信用卡欺詐,評分卡制作,電商中的營銷預測等等相關的數據,都是邏輯回歸的強項。雖然現在有了梯度提 升樹GDBT,比邏輯回歸效果更好,也被許多數據咨詢公司啟用,但邏輯回歸在金融領域,尤其是銀行業中的 統治地位依然不可動搖(相對的,邏輯回歸在非線性數據的效果很多時候比瞎猜還不如,所以如果你已經知 道數據之間的聯系是非線性的,千萬不要迷信邏輯回歸)
- 2. 邏輯回歸計算快:對於線性數據,邏輯回歸的擬合和計算都非常快,計算效率優於SVM和隨機森林,親測表 示在大型數據上尤其能夠看得出區別
- 3. 邏輯回歸返回的分類結果不是固定的0,1,而是以小數形式呈現的類概率數字:我們因此可以把邏輯回歸返 回的結果當成連續型數據來利用。比如在評分卡制作時,我們不僅需要判斷客戶是否會違約,還需要給出確 定的”信用分“,而這個信用分的計算就需要使用類概率計算出的對數幾率,而決策樹和隨機森林這樣的分類 器,可以產出分類結果,卻無法幫助我們計算分數(當然,在sklearn中,決策樹也可以產生概率,使用接口 predict_proba調用就好,但一般來說,正常的決策樹沒有這個功能)
- 4.邏輯回歸還有抗噪能力強的優點。福布斯雜志在討論邏輯回歸的優點時,甚至有着“技術上來說,佳模型 的AUC面積低於0.8時,邏輯回歸非常明顯優於樹模型”的說法。並且,邏輯回歸在小數據集上表現更好,在大型的 數據集上,樹模型有着更好的表現。
由此,我們已經了解了邏輯回歸的本質,它是一個返回對數幾率的,在線性數據上表現優異的分類器,它主要被應用在金融領域。其數學目的是求解能夠讓模型最優化的參數 的值,並基於參數 和特征矩陣計算出邏輯回歸的結果 y(x)。
注意:雖然我們熟悉的邏輯回歸通常被用於處理二分類問題,但邏輯回歸也可以做多分類
三、sklearn實現邏輯回歸
class sklearn.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=’warn’, max_iter=100, multi_class=’warn’, verbose=0, warm_start=False, n_jobs=None)
1.損失函數
我們使用”損失函數“這個評估指標,來衡量參數 的優劣,即這一組參數能否使模型在訓練集上表現優異。 如果用一組參數建模后,模型在訓練集上表現良好,那我們就說模型表現的規律與訓練集數據的規律一致,擬合過 程中的損失很小,損失函數的值很小,這一組參數就優秀;相反,如果模型在訓練集上表現糟糕,損失函數就會很 大,模型就訓練不足,效果較差,這一組參數也就比較差。即是說,我們在求解參數 時,追求損失函數小,讓模型在訓練數據上的擬合效果優,即預測准確率盡量靠近100%。
邏輯回歸的損失函數是由大似然法來推導出來的,具體結果可以寫作
2.正則化 重要參數penalty & C
正則化是用來防止模型過擬合的過程,常用的有L1正則化和L2正則化兩種選項,分別通過在損失函數后加上參數向量theta的L1范式和L2范式的倍數來實現。這個增加的范式,被稱為“正則項”,也被稱為"懲罰項"。損失函數改變,基 於損失函數的優化來求解的參數取值必然改變,我們以此來調節模型擬合的程度。其中L1范數表現為參數向量中 的每個參數的絕對值之和,L2范數表現為參數向量中的每個參數的平方和的開方值。
其中J(theta)是我們之前提過的損失函數,C是用來控制正則化程度的超參數,n是方程中特征的總數,也是方程中參 數的總數,j代表每個參數。在這里,J要大於等於1,是因為我們的參數向量theta 中,第一個參數是theta0 ,是我們的截 距,它通常是不參與正則化的。
L1正則化和L2正則化雖然都可以控制過擬合,但它們的效果並不相同。當正則化強度逐漸增大(即C逐漸變小), 參數 的取值會逐漸變小,但L1正則化會將參數壓縮為0,L2正則化只會讓參數盡量小,不會取到0。 在L1正則化在逐漸加強的過程中,攜帶信息量小的、對模型貢獻不大的特征的參數,會比攜帶大量信息的、對模型 有巨大貢獻的特征的參數更快地變成0,所以L1正則化本質是一個特征選擇的過程,掌管了參數的“稀疏性”。L1正 則化越強,參數向量中就越多的參數為0,參數就越稀疏,選出來的特征就越少,以此來防止過擬合。因此,如果 特征量很大,數據維度很高,我們會傾向於使用L1正則化。由於L1正則化的這個性質,邏輯回歸的特征選擇可以由 Embedded嵌入法來完成。
相對的,L2正則化在加強的過程中,會盡量讓每個特征對模型都有一些小的貢獻,但攜帶信息少,對模型貢獻不大 的特征的參數會非常接近於0。通常來說,如果我們的主要目的只是為了防止過擬合,選擇L2正則化就足夠了。但 是如果選擇L2正則化后還是過擬合,模型在未知數據集上的效果表現很差,就可以考慮L1正則化。 而兩種正則化下C的取值,都可以通過學習曲線來進行調整。
建立兩個邏輯回歸,L1正則化和L2正則化的差別就一目了然了
舉例:在乳腺癌數據集上用LR實現二分類,查看L1、L2正則化的效果
from sklearn.linear_model import LogisticRegression as LR from sklearn.datasets import load_breast_cancer import numpy as np import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score data = load_breast_cancer() X=data.data y=data.target |
![]()
|
#實例化LR模型 lrl1=LR(penalty='l1',solver='liblinear',C=0.5,max_iter=1000) lrl2=LR(penalty='l2',solver='liblinear',C=0.5,max_iter=1000) |
|
#邏輯回歸的重要屬性coef_ theta,查看每個特征所對應的參數 lrl1=lrl1.fit(X,y) |
|
lrl1.coef_ |
![]()
|
(lrl1.coef_!=0).sum(axis=1)#不為0的特征的個數 |
![]()
|
lrl2=lrl2.fit(X,y) |
|
lrl2.coef_ |
![]()
|
l1 = [] l2 = [] l1test = [] l2test = [] Xtrain,Xtest,Ytrain,Ytest = train_test_split(X,y,test_size=0.3,random_state=20) for i in np.linspace(0.05,1,19): lrl1=LR(penalty='l1',solver='liblinear',C=i,max_iter=1000) lrl2=LR(penalty='l2',solver='liblinear',C=i,max_iter=1000) lrl1=lrl1.fit(Xtrain,Ytrain) l1.append(accuracy_score(lrl1.predict(Xtrain),Ytrain)) l1test.append(accuracy_score(lrl1.predict(Xtest),Ytest)) lrl2=lrl2.fit(Xtrain,Ytrain) l2.append(accuracy_score(lrl2.predict(Xtrain),Ytrain)) l2test.append(accuracy_score(lrl2.predict(Xtest),Ytest)) graph=[l1,l2,l1test,l2test] color=['green','black','lightgreen','gray'] label=['L1','L2','L1test','L2test'] plt.figure(figsize=(6,6)) for i in range(len(graph)): plt.plot(np.linspace(0.05,1,19),graph[i],color[i],label=label[i]) plt.legend(loc=4)#圖例的位置在哪里?4表示,右下角 plt.show() |
![]()
|
可見,至少在我們的乳腺癌數據集下,兩種正則化的結果區別不大。但隨着C的逐漸變大,正則化的強度越來越小,模型在訓練集和測試集上的表現都呈上升趨勢,直到C=0.8左右,訓練集上的表現依然在走高,但模型在未知 數據集上的表現開始下跌,這時候就是出現了過擬合。我們可以認為,C設定為0.9會比較好。在實際使用時,基本 就默認使用l2正則化,如果感覺到模型的效果不好,那就換L1試試看