
一、概述
1.1、概念
是一種名為“回歸”的線性分類器,是由線性回歸變化而來的,一種廣泛使用於分類問題中的廣義回歸算法。
1.2、按預測標簽的數據類型分
連續型變量:通過線性回歸方程z,線性回歸使用輸入的特征矩陣X來輸出一組連續型的標簽值y_pred,以完成各種預測連續型變量的任務(比如預測產品銷量,預測股價等等)
離散型變量:通過Sigmoid函數變換,線性回歸方程z變換為g(z),使得模型的值分布在(0,1)之間,且當g(z)接近0時樣本的標簽為類別0,當g(z)接近1時樣本的標簽為類別1,這樣就得到了一個分類模型。

1.3、公式

其中,y(x)就是我們邏輯回歸返回的標簽值。
1.4、本質
y(x)的形似幾率取對數就是線性回歸,對數幾率回歸,就是邏輯回歸。
二、重要概念
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。
損失函數:是一個評估指標,來衡量參數為 的模型擬合訓練集時產生的信息損失的大小,並以此衡量參數的優劣。
損失函數小,模型在訓練集上表現優異,擬合充分,參數優秀。
損失函數大,模型在訓練集上表現差勁,擬合不足,參數糟糕。
我們追求,能夠讓損失函數最小化的參數組合。
注意:沒有”求解參數“需求的模型沒有損失函數,比如KNN,決策樹。

θ表示求解出來的一組參數,m是樣本的個數, yi 是樣本 i 上真實的標簽, yθ(xi)是樣本 i 上,基於參數θ計算出來的邏輯回歸返回值,xi 是樣本 i 各個特征的取值。我們的目標,就是求解出使 J(θ)最小的 θ 取值。注意,在邏輯回歸的本質函數y(x)里,特征矩陣x是自變量,參數是 θ。但在損失函數中,參數θ是損失函數的自變量,x和y都是已知的特征矩陣和標簽,相當於是損失函數的參數。不同的函數中,自變量和參數各有不同,因此大家需要在數學計算中,尤其是求導的時候避免混淆。
三、sklearn中的邏輯回歸
linear_model.LogisticRegression 邏輯回歸分類器(又叫logit回歸,最大熵分類器
linear_model.SGDClassifier 利用梯度下降求解的線性分類器(SVM,邏輯回歸等等)
linear_model.SGDRegressor 利用梯度下降最小化正則化后的損失函數的線性回歸模型
metrics.log_loss 對數損失,又稱邏輯損失或交叉熵損失
metrics.confusion_matrix 混淆矩陣,模型評估指標之一
metrics.roc_auc_score ROC曲線,模型評估指標之一
metrics.accuracy_score 精確性,模型評估指標之一
sklearn.linear_model.LogisticRegression(penalty='l2', C = 1.0)
Logistic: 回歸分類器
coef_:回歸系數
四、重要參數
正則化參數, penalty&C:
正則化: 是用來防止模型過擬合的過程,常用的有L1正則化和L2正則化兩種選項,分別通過在損失函數后加上參數向量 的L1范式和L2范式的倍數來實現。這個增加的范式,被稱為“正則項”,也被稱為"懲罰項"。
penalty: 可以輸入"l1"或"l2"來指定使用哪一種正則化方式,不填寫默認"l2"。
注意,若選擇"l1"正則化,參數solver僅能夠使用求解方式”liblinear"和"saga“,若使用“l2”正則化,參數solver中所有的求解方式都可以使用。
C:C正則化強度的倒數,必須是一個大於0的浮點數,不填寫默認1.0,即默認正則項與損失函數的比值是1:1。C越小,損失函數會越小,模型對損失函數的懲罰越重,正則化的效力越強,參數會逐漸被壓縮得越來越小。
# 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
data.data.shape
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_,查看每個特征所對應的參數
lrl1 = lrl1.fit(X,y)
lrl1.coef_

(lrl1.coef_ != 0).sum(axis=1)
lrl2 = lrl2.fit(X,y)
lrl2.coef_

結論:L1正則化會將參數壓縮為0,L2正則化只會讓參數盡量小,不會取到0。
max_iter:
邏輯回歸的數學目的是求解能夠讓模型最優化,擬合程度最好的參數的值,即求解能夠讓損失函數 最小化的值。對於二元邏輯回歸來說,有多種方法可以用來求解參數 ,最著名的是梯度下降法(Gradient Descent)。

在這個圖像上隨機放一個小球,當我松手,這個小球就會順着這個華麗的平面滾落,直到滾到深藍色的區域——損失函數的最低點。為了嚴格監控這個小球的行為,我讓小球每次滾動的距離有限,不讓他一次性滾到最低點,並且最多只允許它滾動100步,還要記下它每次滾動的方向,直到它滾到圖像上的最低點。
可以看見,小球從高處滑落,在深藍色的區域中來回震盪,最終停留在了圖像凹陷處的某個點上。非常明顯,我們可以觀察到幾個現象:
首先,小球並不是一開始就直向着最低點去的,它先一口氣沖到了藍色區域邊緣,后來又折回來,我們已經規定了小球是多次滾動,所以可見,小球每次滾動的方向都是不同的。
另外,小球在進入深藍色區域后,並沒有直接找到某個點,而是在深藍色區域中來回震盪了數次才停下。這有兩種可能:1) 小球已經滾到了圖像的最低點,所以停下了,2) 由於我設定的步數限制,小球還沒有找到最低點,但也只好在100步的時候停下了。也就是說,小球不一定滾到了圖像的最低處。
小球其實就是一組組的坐標點(θ1,θ2,J) ;小球每次滾動的方向就是那一個坐標點的梯度向量的方向,因為每滾動一步,小球所在的位置都發生變化,坐標點和坐標點對應的梯度向量都發生了變化,所以每次滾動的方向也都不一樣;人為設置的100次滾動限制,就是sklearn中邏輯回歸的參數max_iter,代表着能走的最大步數,即最大迭代次數。
solver:
sklearn為我們提供了多種求解邏輯回歸參數θ 的方法(梯度下降法是其中著名的一種),讓我們可以使用不同的求解器來計算邏輯回歸。求解器的選擇,由參數"solver"控制,共有五種選擇。其中“liblinear”是二分類專用,也是現在的默認求解器。
- liblinear : 坐標下降法
- lbfgs:擬牛頓法的一種,利用損失函數二階導數矩陣(海森矩陣)來迭代優化損失函數。
- newton-cg : 牛頓法的一種,利用損失函數二階導數矩陣(海森矩陣)來迭代優化損失函數。
- sag :隨機平均梯度下降,與普通梯度下降法的區別是每次迭代僅僅用一部分的樣本來計算梯度。
- saga:隨機平均梯度下降的進化,稀疏多項邏輯回歸的首選。
multi_class:
輸入"ovr", "multinomial", "auto"來告知模型,我們要處理的分類問題的類型。默認是"ovr"。
- 'ovr':表示分類問題是二分類,或讓模型使用"一對多"的形式來處理多分類問題。
- 'multinomial':表示處理多分類問題,這種輸入在參數solver是'liblinear'時不可用。
- "auto":表示會根據數據的分類情況和其他參數來確定模型要處理的分類問題的類型。比如說,如果數據是二分
類,或者solver的取值為"liblinear","auto"會默認選擇"ovr"。反之,則會選擇"nultinomial"。
樣本不平衡參數class_weight:
樣本不平衡是指在一組數據集中,標簽的一類天生占有很大的比例,或誤分類的代價很高,即我們想要捕捉出某種特定的分類的時候的狀況。
例如:銀行要判斷“一個新客戶是否會違約”,通常不違約的人vs違約的人會是99:1的比例,真正違約的人其實是非常少的。這種分類狀況下,即便模型什么也不做,全把所有人都當成不會違約的人,正確率也能有99%,這使得模型評估指標變得毫無意義,根本無法達到我們的“要識別出會違約的人”的建模目的。
因此我們要使用參數class_weight對樣本標簽進行一定的均衡,給少量的標簽更多的權重,讓模型更偏向少數類,向捕獲少數類的方向建模。該參數默認None,此模式表示自動給與數據集中的所有標簽相同的權重,即自動1:1。當誤分類的代價很高的時候,我們使用”balanced“模式,我們只是希望對標簽進行均衡的時候,什么都不填就可以解決樣本不均衡問題。
五、案例介紹
5.1、數據描述
(1)699條樣本,共11列數據,第一列用語檢索的id,后9列分別是與腫瘤相關的醫學特征,最后一列表示腫瘤類型的數值。
(2)包含16個缺失值,用”?”標出。
原始數據的下載地址:
https://archive.ics.uci.edu/ml/machine-learning-databases/
5.2、特征選擇:
PCA和SVD一般不用,大多數時候不適用於邏輯回歸。邏輯回歸是由線性回歸演變而來,線性回歸的一個核心目的是通過求解參數來探究特征X與標簽y之間的關系,而邏輯回歸也傳承了這個性質,我們常常希望通過邏輯回歸的結果,來判斷什么樣的特征與分類結果相關,因此我們希望保留特征的原貌。PCA和SVD的降維結果是不可解釋的,因此一旦降維后,我們就無法解釋特征和標簽之間的關系了。
import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report # 構造列標簽名字 column = ['Sample code number','Clump Thickness', 'Uniformity of Cell Size','Uniformity of Cell Shape','Marginal Adhesion', 'Single Epithelial Cell Size','Bare Nuclei','Bland Chromatin','Normal Nucleoli','Mitoses','Class'] # 讀取數據 data = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data", names=column) # print(data.head())
5.3、數據缺失處理,標准化
# 缺失值進行處理 data = data.replace(to_replace='?', value=np.nan) data = data.dropna() # 進行數據的分割 x_train, x_test, y_train, y_test = train_test_split(data[column[1:10]], data[column[10]], test_size=0.25) # 進行標准化處理 std = StandardScaler() x_train = std.fit_transform(x_train) x_test = std.transform(x_test)
5.4、估計器流程
# 邏輯回歸預測 lg = LogisticRegression(C=1.0) lg.fit(x_train, y_train) print(lg.coef_) y_predict = lg.predict(x_test) print("准確率:", lg.score(x_test, y_test)) print("召回率:", classification_report(y_test, y_predict, labels=[2, 4], target_names=["良性", "惡性"]))
完整代碼:
import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report # 構造列標簽名字 column = ['Sample code number','Clump Thickness', 'Uniformity of Cell Size','Uniformity of Cell Shape','Marginal Adhesion', 'Single Epithelial Cell Size','Bare Nuclei','Bland Chromatin','Normal Nucleoli','Mitoses','Class'] # 讀取數據 data = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data", names=column) # print(data.head()) # 缺失值進行處理 data = data.replace(to_replace='?', value=np.nan) data = data.dropna() # 進行數據的分割 x_train, x_test, y_train, y_test = train_test_split(data[column[1:10]], data[column[10]], test_size=0.25) # 進行標准化處理 std = StandardScaler() x_train = std.fit_transform(x_train) x_test = std.transform(x_test) # 邏輯回歸預測 lg = LogisticRegression(C=1.0) lg.fit(x_train, y_train) print(lg.coef_) y_predict = lg.predict(x_test) print("准確率:", lg.score(x_test, y_test)) print("召回率:", classification_report(y_test, y_predict, labels=[2, 4], target_names=["良性", "惡性"]))

C:\Anaconda3\python.exe "C:\Program Files\JetBrains\PyCharm 2019.1.1\helpers\pydev\pydevconsole.py" --mode=client --port=53808 import sys; print('Python %s on %s' % (sys.version, sys.platform)) sys.path.extend(['C:\\app\\PycharmProjects', 'C:/app/PycharmProjects']) Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] Type 'copyright', 'credits' or 'license' for more information IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help. PyDev console: using IPython 7.12.0 Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32 runfile('C:/app/PycharmProjects/ArtificialIntelligence/test.py', wdir='C:/app/PycharmProjects/ArtificialIntelligence') [[1.29014513 0.02841081 0.63541132 0.51761702 0.40995793 1.36777915 1.06877681 0.55433123 0.98039778]] 准確率: 0.9707602339181286 召回率: precision recall f1-score support 良性 0.97 0.98 0.98 111 惡性 0.97 0.95 0.96 60 accuracy 0.97 171 macro avg 0.97 0.97 0.97 171 weighted avg 0.97 0.97 0.97 171
六、總結
應用:
廣告點擊率預測、電商購物搭配推薦、股價預測、產品銷量預測
優點:
- 線性回歸的數據要求:正態分布,消除多重共線性,現實數據無法滿足;邏輯回歸不需要對數據進行處理
- 對線性關系的擬合效果好
- 邏輯回歸計算速度快
- 返回的分類結果不是固定的0和1,而是以小數形式呈現的類概率數字
- 抗噪音能力強
缺點:當特征空間很大時,邏輯回歸的性能不是很好
(看硬件能力)