知識(shí)背景
關(guān)于邏輯回歸的幾個(gè)問(wèn)題
邏輯回歸相比線(xiàn)性回歸,有何異同?
邏輯回歸和線(xiàn)性回歸最大的不同點(diǎn)是邏輯回歸解決的是分類(lèi)問(wèn)題,而線(xiàn)性回歸解決的是回歸問(wèn)題。
邏輯回歸又可以認(rèn)為是廣義線(xiàn)性回歸的一種特殊形式,其特殊之處在于目標(biāo)(label/target)的取值服從二元分布。
所謂邏輯回歸是一種特殊的廣義線(xiàn)性回歸,我們可以通過(guò)狹義線(xiàn)性回歸到邏輯回歸的轉(zhuǎn)化過(guò)程來(lái)理解。
狹義線(xiàn)性回歸的表達(dá)式可表示為:
如果我們希望這個(gè)模型可以對(duì)二分類(lèi)任務(wù)做出預(yù)測(cè),即滿(mǎn)足0,1分布,那么希望預(yù)測(cè)出來(lái)的值經(jīng)過(guò)某種轉(zhuǎn)換后可以分布在0,1兩個(gè)值附近。
sigmoid函數(shù)可以做這樣的轉(zhuǎn)換,sigmoid函數(shù)的表達(dá)式為:
令:
則:
可以看出,狹義線(xiàn)性回歸采用y作為預(yù)測(cè)結(jié)果,邏輯回歸則采用作為預(yù)測(cè)結(jié)果。
邏輯回歸還可以表示為:
通過(guò)以上步驟推演,我們知道邏輯回歸就是在線(xiàn)性回歸的基礎(chǔ)上,再做一個(gè)sigmoid計(jì)算。所以它們都可以用相同的方法,比如梯度下降來(lái)求解參數(shù)。
回歸問(wèn)題常用的性能度量指標(biāo)
- 點(diǎn)對(duì)點(diǎn)誤差
- MSE(Mean Square Error)均方誤差 -- 預(yù)測(cè)數(shù)據(jù)和原始數(shù)據(jù)對(duì)應(yīng)誤差的平方和的均值
- RMSE(Root Mean Square Error)-- 觀測(cè)值與真實(shí)偏差的平方和與觀測(cè)次數(shù)n比值的平方根,用來(lái)衡量觀測(cè)值同真值之間的偏差
- MAE(Mean Absolute Error)-- 計(jì)算模型輸出與真實(shí)值之間的平均絕對(duì)誤差
- 帶歸一化的誤差求解方法
- MAPE(Mean Absolute Percentage Error)-- 不僅考慮預(yù)測(cè)值與真實(shí)值誤差,還考慮誤差與真實(shí)值之間的比例
- MASE(Mean Absolute Scaled Error)-- 平均平方百分比誤差
- 點(diǎn)對(duì)面誤差
- R-Square決定系數(shù)(coefficient of determination)
分類(lèi)問(wèn)題常用的性能度量指標(biāo)
-
準(zhǔn)確率:
所有預(yù)測(cè)正確的樣本與所有樣本的比例
-
精確率:
預(yù)測(cè)為正的樣本中有多少是真正的正樣本
-
召回率:
樣本中的正例有多少被預(yù)測(cè)正確了
-
F1值:
精確率和召回率的調(diào)和值
-
AUC(Area Under Curve):
ROC曲線(xiàn)下的面積,ROC曲線(xiàn)是通過(guò)取不同的閾值來(lái)分別計(jì)算在每個(gè)閾值下,F(xiàn)PR(False Positive Rate)和TPR(True Positive Rate)的值來(lái)繪制的。
邏輯回歸處理多標(biāo)簽分類(lèi)問(wèn)題時(shí),一般怎么做?
如果y不是在[0,1]中取值,而是在k個(gè)類(lèi)別中取值,這時(shí)問(wèn)題就變成一個(gè)多分類(lèi)問(wèn)題。有兩種方式可以處理該問(wèn)題:
- 當(dāng)K個(gè)類(lèi)別不是互斥的時(shí)候,即存在樣本可能屬于多個(gè)標(biāo)簽的情況,我們可以訓(xùn)練k個(gè)二分類(lèi)的邏輯回歸分類(lèi)器。第i個(gè)分類(lèi)器用以區(qū)分樣本是否可以歸為第i類(lèi),訓(xùn)練分類(lèi)器時(shí)需要把標(biāo)簽重新整理為“第i類(lèi)標(biāo)簽”和“非第i類(lèi)標(biāo)簽”兩類(lèi)。通過(guò)這樣的方法,我們就可以解決每個(gè)樣本可能擁有多個(gè)標(biāo)簽的情況。
- 當(dāng)K個(gè)類(lèi)別互斥的時(shí)候,即每個(gè)樣本只屬于一個(gè)標(biāo)簽,可以假設(shè)每個(gè)樣本屬于不同標(biāo)簽的概率服從于幾何分布,使用多項(xiàng)式邏輯回歸(Softmax Regression)來(lái)進(jìn)行分類(lèi)。
通過(guò)幾個(gè)問(wèn)題了解了邏輯回歸后,接著就上代碼來(lái)體驗(yàn)一番吧
本文將使用sklearn和著名的鳶尾花數(shù)據(jù)集來(lái)用邏輯回歸做分類(lèi)預(yù)測(cè)
學(xué)習(xí)目標(biāo)
- 了解邏輯回歸理論
- 掌握sklearn中LogisticsRegression的基本用法
Step 1:讀取數(shù)據(jù)
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
#load data
from sklearn.datasets import load_iris
data = load_iris() # 數(shù)據(jù)特征
iris_labels = data.target # 數(shù)據(jù)標(biāo)簽
iris_names = data.target_names #iris分類(lèi)對(duì)應(yīng)的名字
iris_features = pd.DataFrame(data=data.data, columns=data.feature_names)
查看數(shù)據(jù)基本信息,大致了解一下特征和標(biāo)簽
# 查看數(shù)據(jù)基本信息
iris_features.info()
print(iris_features.head())
print(iris_names)
結(jié)果如下:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150 entries, 0 to 149
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 sepal length (cm) 150 non-null float64
1 sepal width (cm) 150 non-null float64
2 petal length (cm) 150 non-null float64
3 petal width (cm) 150 non-null float64
dtypes: float64(4)
memory usage: 4.8 KB
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2
['setosa' 'versicolor' 'virginica']
如上基本信息我們了解到:
- 一共有150個(gè)樣本
- 每個(gè)樣本有4個(gè)特征,都是float型。
sepal length,sepal width,petal length和petal width分別代表花萼和花瓣的長(zhǎng)寬。通過(guò)外觀的長(zhǎng)寬大小來(lái)判斷植物的種類(lèi),也很符合人的學(xué)習(xí)習(xí)慣。 - 一共有3個(gè)標(biāo)簽:
setosa,versicolor,virginica,分別代表3種花,在數(shù)據(jù)中表示為0, 1, 2.
再看看數(shù)據(jù)集中3類(lèi)樣本分別占的比例:
pd.Series(iris_labels).value_counts()
結(jié)果發(fā)現(xiàn):
2 50
1 50
0 50
一共150個(gè)樣本,3種花每種分別50個(gè),分布還是很平均的嘛。
Step 2:數(shù)據(jù)可視化
一圖勝千言,通過(guò)可視化的方法能更快更直觀地了解數(shù)據(jù),找到數(shù)據(jù)的特征,能讓數(shù)據(jù)的學(xué)習(xí)和訓(xùn)練達(dá)到事半功倍的效果。
# 準(zhǔn)備數(shù)據(jù),為了不影響原數(shù)據(jù),我們用原數(shù)據(jù)集的拷貝來(lái)畫(huà)圖
iris_all = iris_features.copy()
iris_all['label'] = iris_labels
# 查看數(shù)據(jù)分布
sns.pairplot(data=iris_all, diag_kind='hist', hue='label')
plt.show()

從圖中可以看出:
- petal width和petal length的區(qū)分能力比較好
- 藍(lán)色的這個(gè)類(lèi)別主要集中在左下,集中在petal width和petal length的值比較小的部分,說(shuō)明這個(gè)種類(lèi)的花瓣又窄又短
通過(guò)箱線(xiàn)圖來(lái)查看一下各個(gè)特征的數(shù)據(jù)分布:
# 從箱線(xiàn)圖查看各個(gè)特征數(shù)據(jù)分布
for col in iris_features.columns:
sns.boxplot(x='label', y = col, saturation=0.5, palette = 'pastel', data=iris_all)
plt.title(col)
plt.show()




通過(guò)數(shù)據(jù)分布也能明顯看出來(lái),petal length 和 petal width 的數(shù)據(jù)在各類(lèi)別內(nèi)集中,且在各類(lèi)別間有較明顯的區(qū)分度。
選取前三個(gè)特征繪制三維散點(diǎn)圖:
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
iris_all_class0 = iris_all[iris_all['label']==0].values
iris_all_class1 = iris_all[iris_all['label']==1].values
iris_all_class2 = iris_all[iris_all['label']==2].values
ax.scatter(iris_all_class0[:,0], iris_all_class0[:,1], iris_all_class0[:,2], label='setosa')
ax.scatter(iris_all_class1[:,0], iris_all_class1[:,1], iris_all_class1[:,2], label='versicolor')
ax.scatter(iris_all_class2[:,0], iris_all_class2[:,1], iris_all_class2[:,2], label='virginica')
ax.set_xlabel('sepal length')
ax.set_ylabel('sepal width')
ax.set_zlabel('petal length')
plt.legend()
plt.show()

三維散點(diǎn)圖更清晰地看到了類(lèi)別的區(qū)分。
Step 3:邏輯回歸二分類(lèi)訓(xùn)練
先用邏輯回歸進(jìn)行二分類(lèi)訓(xùn)練,訓(xùn)練出一個(gè)區(qū)分0、1標(biāo)簽的分類(lèi)器。
# 分割數(shù)據(jù)集和訓(xùn)練集
from sklearn.model_selection import train_test_split
# 先選取類(lèi)別為0和1的數(shù)據(jù),進(jìn)行二分類(lèi)訓(xùn)練
iris_features_part = iris_all[iris_all['label']<2]
iris_labels_part = iris_features_part.pop('label').tolist()
x_train, x_test, y_train, y_test = train_test_split(iris_features_part, iris_labels_part, test_size=0.3, random_state=2020)
參數(shù)解釋?zhuān)?/p>
- test_size: test數(shù)據(jù)占的比例,例如0.3表示test數(shù)據(jù)占30%,train數(shù)據(jù)占70%
- random_state: 隨機(jī)數(shù)種子,代表該組隨機(jī)數(shù)的編號(hào),在重復(fù)實(shí)驗(yàn)中能保證每次得到的隨機(jī)數(shù)是相同的。當(dāng)為None時(shí),每次得到的結(jié)果就會(huì)是隨機(jī)的。
分好數(shù)據(jù)集,就可以用邏輯回歸模型來(lái)訓(xùn)練了
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression(random_state=0, solver='lbfgs')
clf.fit(x_train, y_train)
參數(shù)solver代表邏輯回歸損失函數(shù)的優(yōu)化方法,分別有4種方法,官方文檔建議如下:
- ‘liblinear’:Small dataset or L1 penalty
- ‘lbfgs’、‘newton-cg’ or ‘sag’:Multinomial loss or large dataset
- ‘sag’:Very Large dataset
根據(jù)數(shù)據(jù)集的情況,我們選擇了‘lbfgs’,這是擬牛頓法的一種,利用損失函數(shù)二階導(dǎo)數(shù)矩陣即海森矩陣來(lái)迭代優(yōu)化損失函數(shù)。
# 在測(cè)試集和訓(xùn)練集上預(yù)測(cè)
train_pred = clf.predict(x_train)
test_pred = clf.predict(x_test)
# 預(yù)測(cè)結(jié)果檢驗(yàn)
from sklearn import metrics
print('The accuracy in train data: ', metrics.accuracy_score(y_train, train_pred))
print('The accuracy in test data: ', metrics.accuracy_score(y_test, test_pred))
結(jié)果如下:
The accuracy in train data: 1.0
The accuracy in test data: 1.0
都達(dá)到了100%的準(zhǔn)確率,就是這么秀~~
查看在測(cè)試集上的混淆矩陣:
confusion_matrix_result = metrics.confusion_matrix(test_pred, y_test)
plt.figure(figsize=(10, 8))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Wistia_r')
plt.xlabel('Predict labels')
plt.ylabel('Actual labels')
plt.show()

Step 4:三種分類(lèi)上的邏輯回歸模型訓(xùn)練
和二分類(lèi)任務(wù)下的方法相似,這次來(lái)進(jìn)行多分類(lèi)訓(xùn)練。從文章開(kāi)頭的幾個(gè)問(wèn)題可知,這個(gè)多分類(lèi)問(wèn)題屬于互斥的多分類(lèi)問(wèn)題,即每個(gè)樣本只能屬于一個(gè)分類(lèi),我們使用多項(xiàng)式邏輯回歸模型就可以了。
# 分割測(cè)試集和訓(xùn)練集(20%/80%)
x_train, x_test, y_train, y_test = train_test_split(iris_features, iris_labels, test_size=0.2, random_state=2020)
clf = LogisticRegression(random_state=0, solver='lbfgs')
clf.fit(x_train, y_train)
預(yù)測(cè):
# 在訓(xùn)練集和測(cè)試集上預(yù)測(cè)
train_pred = clf.predict(x_train)
test_pred = clf.predict(x_test)
print('The accuracy in train data: ', metrics.accuracy_score(y_train, train_pred))
print('The accuracy in test data: ', metrics.accuracy_score(y_test, test_pred))
confusion_matrix_result = metrics.confusion_matrix(test_pred, y_test)
plt.figure(figsize=(10, 8))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Wistia_r')
plt.xlabel('Predict labels')
plt.ylabel('Actual labels')
plt.show()
在三分類(lèi)問(wèn)題上的預(yù)測(cè)結(jié)果稍微有點(diǎn)偏差:
The accuracy in train data: 0.9833333333333333
The accuracy in test data: 0.8666666666666667

從圖中能看出來(lái),在1和2這兩個(gè)類(lèi)別下分別有兩個(gè)預(yù)測(cè)錯(cuò)誤。我們?cè)谥暗臄?shù)據(jù)可視化中也可以看出來(lái),橙色和綠色兩個(gè)類(lèi)別的分解有點(diǎn)模糊,這和我們之前的認(rèn)識(shí)是相符合的。
總結(jié)
邏輯回歸雖然叫“回歸”,但實(shí)際上是一種分類(lèi)算法。由線(xiàn)性回歸經(jīng)過(guò)sigmoid函數(shù)變換而來(lái),所以預(yù)測(cè)值在0~1之間,通常用來(lái)解決二分類(lèi)問(wèn)題。
剛才用邏輯回歸解決了二分類(lèi)問(wèn)題和多分類(lèi)問(wèn)題,這里的多分類(lèi)問(wèn)題是通過(guò)多項(xiàng)式損失函數(shù)優(yōu)化來(lái)完成的,還可以將多個(gè)二分類(lèi)邏輯回歸模型組合來(lái)實(shí)現(xiàn)多分類(lèi)。
END