Task 01|基于邏輯回歸的分類(lèi)預(yù)測(cè)

知識(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á)式可表示為:
y = w*x+b

如果我們希望這個(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á)式為:

\delta(z) = \frac {1}{1+e^{-z}}

令:y=\delta(z)

則:\log\frac{y}{1-y}=z=w*x+b

可以看出,狹義線(xiàn)性回歸采用y作為預(yù)測(cè)結(jié)果,邏輯回歸則采用\log\frac{y}{1-y}作為預(yù)測(cè)結(jié)果。

邏輯回歸還可以表示為:
y=sigmoid(w*x+b)

通過(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è)正確的樣本與所有樣本的比例
    Accuracy=\frac{TP+TN}{TP+FN+TN+FP}

  • 精確率:

    預(yù)測(cè)為正的樣本中有多少是真正的正樣本
    Precision=\frac{TP}{TP+FP}

  • 召回率:

    樣本中的正例有多少被預(yù)測(cè)正確了
    Recall=\frac{TP}{TP+FN}

  • F1值:

    精確率和召回率的調(diào)和值
    F1=2*\frac{Precision*Recall}{Precision+Recall}

  • 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']

如上基本信息我們了解到:

  1. 一共有150個(gè)樣本
  2. 每個(gè)樣本有4個(gè)特征,都是float型。sepal length, sepal width, petal lengthpetal width分別代表花萼和花瓣的長(zhǎng)寬。通過(guò)外觀的長(zhǎng)寬大小來(lái)判斷植物的種類(lèi),也很符合人的學(xué)習(xí)習(xí)慣。
  3. 一共有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()
特征與標(biāo)簽組合的散點(diǎn)圖

從圖中可以看出:

  • 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()
petal length (cm)
petal width (cm)
sepal length (cm)
sepal width (cm)

通過(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)圖

三維散點(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()
二分類(lèi)混淆矩陣

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)混淆矩陣

從圖中能看出來(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容