上手機器學習系列-第3篇(中)-聊聊logistic迴歸

書接上回

在第3篇(上)中,筆者介紹了自己對於logistic迴歸是咋來的這一問題的思考。本文中篇讓我們一起實戰一下。用Python中的機器學習大殺器Scikit-learn來跑一個小任務。未來在下篇中,我們還會繼續帶領大家通讀一遍sklearn的logistic迴歸源代碼。

數據來源

本小節我們直接使用scikit-learn中自帶的二分類數據集,通過以下方式可以導入:

from sklearn.datasets import load_breast_cancer
X,y = load_breast_cancer(return_X_y=True)

這裏return_X_y=True參數是可以直接就把數據集拆成特徵集與標籤集,默認是False,所以我們這裏顯式的指定。

編碼

不管是什麼算法包,只要不是我們自己寫的,都要先研究一下對方接口的文檔,看看人家的使用說明。即使同樣的logistic迴歸算法包,在不同軟件平臺的實現上也是不同的,各有各的數據格式要求。

sklearn中LogisticRegression的使用文檔詳見:
https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_model.LogisticRegression

從官方接口的格式來看,有很多需要配置的參數。不過不要怕,大部分參數都有默認值,我們瞭解了每個參數的意義後,對於不需要顯示給定的參數,省略即可。

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='lbfgs', max_iter=100, multi_class='auto', verbose=0, warm_start=False, n_jobs=None, l1_ratio=None)

下面就直接開始應用logistic迴歸吧:

#導入LogisticRegression算法包
from sklearn.linear_model import LogisticRegression

#對數據進行標準化處理
from sklearn import preprocessing
X_scaled = preprocessing.scale(X)


#拆分訓練集與測試集
#sklearn自帶了train_test_split可以快速將數據進行隨機拆分,可一次性返回多個數據集
from sklearn.model_selection import train_test_split
#下面得到的X_train,X_test分別表示對特徵變量拆分後的訓練集與測試集,Y_train,Y_test代表對標籤變量拆分後的訓練集與測試集
X_train,X_test,Y_train,Y_test = train_test_split(X_scaled,y,test_size=0.2,random_state = 0) #test_ratio指定測試集數據量的佔比,random_state是爲了保證實驗可復現,如果不指定數值,下一次運行隨機拆分的數據未必就是本次的結果了

#好了,現在創建一個logistic迴歸的算法實例,並把它應用到訓練集上進行訓練吧
clf = LogisticRegression(random_state=0).fit(X_train,Y_train)

#當上面這個fit執行完成後,模型就訓練好了,只在到了clf中,我們後面就可以用clf來對未知的數據集進行分類預測了
#clf.predict就可以把上面訓練好的模型應用到測試集上
predict = clf.predict(X_test)

這裏咱們把上述過程再拆解一下:
在這裏插入圖片描述
然後就可以計算準確率嘍,先手工算一下:

right = 0 
for i in range(0,len(predict)):
    if predict[i] == Y_test[i]:
        right += 1
print("分類準確率爲 %f" % (1.0*right/len(Y_test))) #這裏乘以1.0是爲了把數據轉成浮點型

結果得到0.964912,即96.49%的準確率,還不錯。

其實,在sklearn中,也有一個現成的函數可以用於計算準確率:即存在於sklearn.metrics中的accuracy_score,我們也可以直接使用該函數來計算上述模型的準確率,看是否與我們自己手工計算的結果一致:

from sklearn.metrics import accuracy_score
accuracy_score(Y_test,predict)

答案顯示:0.9649122807017544,前6位有效數字都是一樣的,說明結果一致。

更專業的模型結果評估方法

上面我們計算了模型分類的準確率,即預測值=真值的數據量在總測試集數據量中的佔比,別忘了數據本身有真假之分,而對於真、假的準確評估有可能重要性是不同的!例如如果需求是根據人物特徵來預測其是否恐怖分子,那麼誤判一個人,可能就僅僅是多花了成本就預防災難發生,但如果預測錯誤,OH,MY GOD!可能就是又一架被綁架的飛機了。再比如,根據醫學圖像來識別是否存在腫瘤,對於真假的預測準確度也是結果迥異的,權重並不應該相等。這一點也可以聯想到假設檢驗中學到的棄真錯誤、採僞錯誤等說法。

事實上,在企業實際工作中,很多人會經常提到模型的“準確率”(注意這裏的準確率不同於上文)、“覆蓋率或者召回率”,比如在風控領域,如果我們建立模型來識別存在金融詐騙的賬號,那麼準確率往往是說在我們識別爲壞人的集合中,有多少是真正的壞人;覆蓋率是說大盤中(全量賬號中)有多少壞人,我們的模型可以抓到其中多少人。

對於二分類來說,我們可以得到下面這樣一個數據結果,很多書上叫做“混淆矩陣”:
在這裏插入圖片描述
這裏的P其實就對應了我們上文提到了預測爲真的結果中,有多少是事實上也爲真的比例;R對應了覆蓋率。直觀想來,要想提升準確率,有可能預測爲真的集合越小越好,例如我只預測3個賬號爲存在欺詐的壞人,那極有可能全是對的(大不了是我人肉挖出來的賬號嘛!),那麼P就是100%了。但R呢,可能現實在有1萬個壞人的賬號,但你只找到了3個,那查全率R就是萬分之三。反過來,如果我的賬號集合總量是10萬,我無腦地把所有賬號全部分類爲壞人,那麼查全率就是100%了嘛,因爲所有的壞人全都被我誤別出來了;但P呢,就只有10%了。所以在實操中這兩個指標往往是有一些衝突的。但邏輯上,這兩個值也有可能同時達到100%,例如我精準地把所有壞人找了出來,不冤枉一個好人。

一般地,可以用一個綜合性的指標來進行衡量,這裏就輪到F1-Score出場了。

就像一個和事佬一樣,F1就是把查準率與查全率進行了綜合;而且還可以用不同的權重來綜合。
在這裏插入圖片描述
如果我們使用同一個模型在多個數據集上進行訓練(這種場景往往發生在需要對比多個模型,可以在不同規模的數據集上進行效果評估),那麼就會得到多個混淆矩陣,這時可以通過求平均值的方式得到一個綜合的模型評估,而兩種
不同求平均值的方式的就分別得到了macro-F1、micro-F1。其中macro-F1是分別針對每個混淆矩陣求P,R,然後最終求一個P的平均值,R的平均值,再拿來計算F1;micro-F1則是對不同混淆矩陣對應的元素求平均值,最均得到一個平均值的混淆矩陣,再用該矩陣來計算F1。目前在學術論文中,micro-F1使用更多。

使用sklearn可以如下這樣計算:

from sklearn.metrics import f1_score
print("Micro-F1: %f" % f1_score(Y_test,predict, average='micro'))
print("Macro-F1: %f" % f1_score(Y_test,predict, average='macro'))

另外還有一個常用的就是AUC(表示ROC曲線下的面積), 代碼可以這樣寫:

import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc
fpr, tpr, thresholds = roc_curve(Y_test,y_prob[:,1])  #這裏y_prob[:,1]這樣寫是因爲y_prob預測的結果其實是兩列,第一列是每個樣本分類爲0的概率,第二列是分類爲1的概率
roc_auc  = auc(fpr, tpr)  #auc爲Roc曲線下的面積
print("ROC 曲線下面積: %f" % roc_auc)
#開始畫ROC曲線
import matplotlib.pyplot as plt
plt.plot(fpr, tpr, 'b',label='AUC = %0.3f'% roc_auc)
plt.legend(loc='lower right')
plt.plot([0,1],[0,1],'r--')
plt.xlabel('False Positive Rate') #橫座標是fpr
plt.ylabel('True Positive Rate')  #縱座標是tpr
plt.show()

在這裏插入圖片描述

小結

至此我們用一個簡單的案例初步跑了一個logistic迴歸,以及模型評估的過程,也知道了怎麼去調用sklearn中的包。再下一次,我們會實際去讀一下sklearn中logistic迴歸的源代碼,看看底層是怎樣實現的。敬請繼續關注本人公衆號後續推送文章。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章