1. 程式人生 > >機器學習之用Python進行邏輯迴歸分析

機器學習之用Python進行邏輯迴歸分析

前言
迴歸和分類方法是機器學習中經常用到的方法,本文首先介紹這兩種方法的區別和聯絡,然後對分類方法中的邏輯迴歸進行較詳細的說明(包括其基本原理及評估指標),最後結合案例介紹如何利用Python進行邏輯迴歸分析。

邏輯迴歸

一、分類與迴歸

1.1什麼是分類和迴歸
區分迴歸問題和分類問題:

  • 迴歸問題:輸入變數和輸出變數均為連續變數的問題;
  • 分類問題:輸出變數為有限個離散變數的問題。

因此分類及迴歸分別為研究這兩類問題的方法。

1.2兩者區別與聯絡

區別:從三個維度來對比分類和迴歸方法:
在這裡插入圖片描述
聯絡:從prediction角度來看,分類模型和迴歸模型本質相同,分類模型是將回歸模型的輸出離散化,比如:

1、Logistic Regression 和 Linear Regression
Linear Regression:輸出一個標量wx+b,是連續值,用以處理迴歸問題;
Logistic Regression:將標量wx+b通過sigmoid函式對映到(0,1)上,並劃分一個閾值,大於閾值的分為一類,其他歸為另一類,可處理二分分類問題;
對於N分類問題,先得到N組w值不同的wx+b,然後歸一化,比如用softmax函式,最後變成N個類上的概率,可處理多分類問題。

2、Support Vector Regression 和 Support Vector Machine
SVR:輸出wx+b,即某個樣本點到分類面的距離,是連續值,用以處理迴歸問題;
SVM:將該距離通過sign(·)函式對映,距離為正的樣本點為一類,為負的是另一類,故為分類問題。

1.3相應有哪些常用方法

常見的分類方法
邏輯迴歸、決策樹分類、KNN(K-近鄰)分類、貝葉斯分類、人工神經網路、支援向量機(SVM)等

常見的迴歸方法
線性迴歸、多項式迴歸、逐步迴歸等
(常見的聚類方法:K-Means(K均值)聚類等)

二、邏輯迴歸分析

2.1邏輯迴歸
Logistic迴歸主要思想是,根據現有資料對決策邊界建立迴歸方程,然後將回歸方程對映到分類函式上實現分類。

2.2原理介紹
Logistic迴歸的原理可以理解為以下四步:

1、利用迴歸方程表示決策邊界
分類問題的目的是找到決策邊界,因此我們需要找到一個迴歸方程來表示這個決策邊界: g(W,X)=W^X ,其中 W 代表權重向量。
在這裡插入圖片描述

2、利用 Sigmoid 函式對迴歸關係進行對映
在面對二分分類問題時,可以用1和0分別代表一種情況,此時利用 Sigmoid 函式:在這裡插入圖片描述
將回歸方程的結果對映到分類函式上,即用 Sigmoid 函式表示擬合函式,這種函式是 S 型的非線性函式。
在這裡插入圖片描述
3、在得到擬合函式後,利用損失函式來評價模型與實際值之間的差異大小
損失函式:
在這裡插入圖片描述
其中 x{i} 代表資料屬性值, y{i} 代表資料實際的分類結果, h{W}(x{i}) 代表利用擬合函式得到的預測值,可以用下圖表示:
在這裡插入圖片描述
損失函式應滿足三個特點,以y{i}=1 時為例:
遞減: h{W}(x{i}) 越小,則懲罰力度應越大;
導數絕對值遞減:h{W}(x{i}) 越趨近於零,該遞減函式的遞減幅度也應該越小;
定義域在[0,1]內時,變化幅度應較大。
在這裡插入圖片描述
因此利用滿足此條件的邏輯函式作為擬合函式。

4、求出損失函式取得極小值時對應的W ,從而得到擬合函式
損失函式求極值利用梯度下降法,本文不做介紹。

2.3評價指標
常見的分類模型效能指標有準確率(precision)、召回率(recall)、ROC曲線等。

1、混淆矩陣(confusion matrix)
包括分類器預測結果:真正TP(true positive)、真負TN(true negative)、假正FP(false positive)、假負FN(false negative)的數量,其中真正和假負均為正確分類的結果。
在這裡插入圖片描述
2、準確率、真正率及假正率
預測誤差(error,ERR)和準確率(accuracy,ACC)都可以表示誤分類樣本數量的相關資訊, ACC=1-ERR=TN+TP}/{TN+TP+FN+FP} 。

真正率(TPR)和假正率(FPR)也是很有參考價值的效能指標, TPR=\frac{TP}{AP} 表示預測與實際均為正類別樣本數量 與 實際正樣本數量的比值, FPR=\frac{FP}{AN} 表示預測為正類別實際為負類別樣本數量 與 實際負樣本數量的比值。

3、ROC曲線(receiver operator characteristic)
ROC曲線由變數1-Specificity和Sensitivity繪製,其中橫軸1-Specificity=假正率(FPR)、縱軸Sensitivity=真正率(TPR),ROC曲線的對角線表示隨機猜測,若ROC曲線在對角線下表示分類器效能比隨機猜測還差,ROC曲線下的區域面積(area under the curve,AUC)表示分類模型的效能。

原理:

  1. 給定 m^{+} 個正例和 n^{-} 個反例,根據學習器預測結果對樣例進行排序,然後將分類閾值設定為最大,即所有樣例均預測為反例,此時真正例率和假正例率均為0,即在座標(0,0)處標記一個點。
  2. 然後,將分類閾值依次設為每個樣例的預測值,即依次將每個樣例劃分為正例。
    設前一個標記點座標為 (x,y) ,當前若為真正例,則對應標記點座標為
    在這裡插入圖片描述
    若當前為假正例,則對應標記點座標為
    在這裡插入圖片描述
    然後用線段連線相鄰點即得。

意義:

  • 有助於選擇最佳閾值:ROC曲線越靠近左上角,模型查全率越高,最靠近左上角的ROC曲線上的點是分類錯誤最少的最好閾值,其假正例和假反例總數最少。
  • 可以比較不同學習器的效能:將各個學習器的ROC曲線繪製在同一座標中,直觀比較,越靠近左上角的ROC曲線代表的學習器準確性越高。
  • AUC同時考慮了學習器對於正例和負例的分類能力,在樣本不平衡的情況下,依然能對分類器做出合理評價(如癌症預測)。
    在這裡插入圖片描述

三、邏輯迴歸的Python實現

利用Python中sklearn包進行邏輯迴歸分析。

3.1提出問題
根據已有資料探究“學習時長”與“是否通過考試”之間關係,並建立預測模型。

3.2理解資料

1、匯入包和資料

#1.匯入包
import warnings
import pandas as pd
import numpy as np
from collections import OrderedDict
import matplotlib.pyplot as plt
warnings.filterwarnings('ignore')
#2.建立資料(學習時間與是否通過考試)
dataDict={'學習時間':list(np.arange(0.50,5.50,0.25)),
        '考試成績':[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
dataOrDict=OrderedDict(dataDict)
dataDf=pd.DataFrame(dataOrDict)
dataDf.head()

>>>
       學習時間	考試成績
0	0.50	0
1	0.75	0
2	1.00	0
3	1.25	0
4	1.50	0

2、檢視資料

#檢視資料具體形式
dataDf.head()
#檢視資料型別及缺失情況
dataDf.info()
>>>
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 2 columns):
學習時間    20 non-null float64
考試成績    20 non-null int64
dtypes: float64(1), int64(1)
memory usage: 400.0 bytes

#檢視描述性統計資訊
dataDf.describe()
>>>
        學習時間	 考試成績
count	20.00000 20.000000
mean	2.87500	0.500000
std	1.47902	0.512989
min	0.50000	0.000000
25%	1.68750	0.000000
50%	2.87500	0.500000
75%	4.06250	1.000000
max	5.25000	1.000000

3、繪製散點圖檢視資料分佈情況

#提取特徵和標籤
exam_X=dataDf['學習時間']
exam_y=dataDf['考試成績']
#繪製散點圖
plt.scatter(exam_X,exam_y,color='b',label='考試資料')
plt.legend(loc=2)
plt.xlabel('學習時間')
plt.ylabel('考試成績')
plt.show()

在這裡插入圖片描述
從圖中可以看出當學習時間高於某一閾值時,一般都能夠通過考試,因此我們利用邏輯迴歸方法建立模型。

3.3構建模型

1、拆分訓練集並利用散點圖觀察

#1.拆分訓練集和測試集
from sklearn.cross_validation import train_test_split
exam_X=exam_X.values.reshape(-1,1)
exam_y=exam_y.values.reshape(-1,1)
train_X,test_X,train_y,test_y=train_test_split(exam_X,exam_y,train_size=0.8)
print('訓練集資料大小為',train_X.size,train_y.size)
print('測試集資料大小為',test_X.size,test_y.size)
>>>
訓練集資料大小為 16 16
測試集資料大小為 4 4

#2.散點圖觀察
plt.scatter(train_X,train_y,color='b',label='train data')
plt.scatter(test_X,test_y,color='r',label='test data')
#plt.plot(test_X,pred_y,color='r')
plt.legend(loc=2)
plt.xlabel('Hours')
plt.ylabel('Scores')
plt.show()

在這裡插入圖片描述
2、匯入模型

#3.匯入模型
from sklearn.linear_model import LogisticRegression
modelLR=LogisticRegression()

3、訓練模型

#4.訓練模型
modelLR.fit(train_X,train_y)

3.4模型評估

1、模型評分(即準確率)

modelLR.score(test_X,test_y)
>>>
0.75

2、指定某個點的預測情況

#學習時間確定時,預測為0和1的概率分別為多少?
modelLR.predict_proba(3)
>>>
array([[0.36720478, 0.63279522]])

#學習時間確定時,預測能否通過考試?
modelLR.predict(3)
>>>
array([1])

3、求出邏輯迴歸函式並繪製曲線
邏輯迴歸函式

#先求出迴歸函式y=a+bx,再代入邏輯函式中pred_y=1/(1+np.exp(-y))
b=modelLR.coef_
a=modelLR.intercept_
print('該模型對應的迴歸函式為:1/(1+exp-(%f+%f*x))'%(a,b))
>>>
該模型對應的迴歸函式為:1/(1+exp-(-1.527106+0.690444*x))

邏輯迴歸曲線

#畫出相應的邏輯迴歸曲線
plt.scatter(train_X,train_y,color='b',label='train data')
plt.scatter(test_X,test_y,color='r',label='test data')
plt.plot(test_X,1/(1+np.exp(-(a+b*test_X))),color='r')
plt.plot(exam_X,1/(1+np.exp(-(a+b*exam_X))),color='y')
plt.legend(loc=2)
plt.xlabel('Hours')
plt.ylabel('Scores')
plt.show()

在這裡插入圖片描述
4、得到模型混淆矩陣

from sklearn.metrics import confusion_matrix
#數值處理
pred_y=1/(1+np.exp(-(a+b*test_X)))
pred_y=pd.DataFrame(pred_y)
pred_y=round(pred_y,0).astype(int)
#混淆矩陣
confusion_matrix(test_y.astype(str),pred_y.astype(str))
>>>
array([[1, 1],
       [0, 2]])

從混淆矩陣可以看出:

  • 該模型的準確率ACC為0.75;
  • 真正率TPR和假正率FPR分別為0.50和0.00,說明該模型對負例的甄別能力更強(如果資料量更多,該指標更有說服性,而本案例中資料較少,因此受隨機影響較大)。

5、繪製模型ROC曲線

from sklearn.metrics import roc_curve, auc  ###計算roc和auc
# Compute ROC curve and ROC area for each class
fpr,tpr,threshold = roc_curve(test_y, pred_y) ###計算真正率和假正率
roc_auc = auc(fpr,tpr) ###計算auc的值

plt.figure()
lw = 2
plt.figure(figsize=(10,10))
plt.plot(fpr, tpr, color='r',
         lw=lw, label='ROC curve (area = %0.2f)' % roc_auc) ###假正率為橫座標,真正率為縱座標做曲線
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()

紅線以下部分面積等於0.75,與模型準確率一致
紅線以下部分面積等於0.75,與模型準確率一致

四、總結

  • 理解迴歸與分類的關係:兩者既有區別(三個維度理解),又有聯絡(將回歸方程對映到分類函式);
  • 邏輯迴歸的引數及其含義:準確率(ACC:模型預測準確度)、真正率(TPR:模型將正例分類正確的能力)、假正率(FPR:模型將負例分類正確的能力)、ROC曲線(可以反映模型正確識別正/負例的能力,也可利用AUC反映模型準確度)