1. 程式人生 > >機器學習實踐(十五)—sklearn之分類演算法-邏輯迴歸、精確率、召回率、ROC、AUC

機器學習實踐(十五)—sklearn之分類演算法-邏輯迴歸、精確率、召回率、ROC、AUC

邏輯迴歸雖然名字中帶有迴歸兩字,但它實際是一個分類演算法。

一、邏輯迴歸的應用場景

  • 廣告點選率
  • 是否為垃圾郵件
  • 是否患病
  • 金融詐騙
  • 虛假賬號

看到上面的例子,我們可以發現其中的特點,那就是都屬於兩個類別之間的判斷。

邏輯迴歸就是解決二分類問題的利器

二、邏輯迴歸的原理

  • 輸入

    邏輯迴歸的輸入其實就是線性迴歸

    即:
    h θ

    ( x ) = θ T x
    h_\theta(x)=\theta^Tx

  • 啟用函式(sigmoid)

    邏輯迴歸的本質就是把輸入到線性迴歸產生的結果再輸入到啟用函式中然後輸出。

    即:
    g ( h

    θ ( x ) ) = g ( θ T x ) = 1 1 + e θ T x g(h_\theta(x)) = g(\theta^Tx) = \frac{1}{1+e^{-\theta^Tx}}
    輸出的結果為:[0,1]區間中的一個概率值,預設的閾值為 0.5。

    如:假設有兩個類別A,B,並且我們認為閾值為0.5,輸出結果超過閾值則預測為 A 類。那麼現在有一個樣本的輸入到邏輯迴歸輸出結果 0.6,這個概率值超過 0.5,意味著我們訓練或者預測的結果就是A類別。那麼反之,如果得出結果為 0.3 那麼,訓練或者預測結果就為B類別。

三、損失以及優化

那麼如何去衡量邏輯迴歸的預測結果與真實結果的差異呢?

  • 損失

    邏輯迴歸的損失,稱之為對數似然損失,公式如下:
    C o s t ( h θ ( x ) , y ) = y l o g ( h θ ( x ) ) ( 1 y ) l o g ( 1 h θ ( x ) ) Cost(h_\theta(x),y) = -ylog(h_\theta(x)) - (1-y)log(1-h_\theta(x))
    上式為針對單條資料的損失函式,

    那麼,我們能夠得出總的損失函式,公式如下:
    i = 1 m y ( i ) l o g ( h θ ( x ( i ) ) ) + ( 1 y ( i ) ) l o g ( 1 h θ ( x ( i ) ) \sum_{i=1}^{m} y^{(i)}log(h_\theta(x^{(i)})) + (1-y^{(i)})log(1-h_\theta(x^{(i)})

  • 優化

    我們同樣可以使用梯度下降優化演算法,去減少損失函式的值。

    這樣去更新邏輯迴歸前面對應演算法的權重引數,提升原本屬於1類別的概率,降低原本是0類別的概率。

四、邏輯迴歸API

  • sklearn.linear_model.LogisticRegression(solver=‘liblinear’, penalty=‘l2’, C = 1.0)
    • solver
      • 優化求解方式(預設開源的liblinear庫實現,內部使用了座標軸下降法來迭代優化損失函式)
      • 預設使用的是 sag,即根據資料集自動選擇,隨機平均梯度下降
    • penalty
      • 正則化的種類
      • 預設為 L2
    • C
      • 正則化力度
  • 使用 SGDClassifier 實現邏輯迴歸 API,SGDClassifier(loss=“log”, penalty=" ")
    • SGDClassifier實現了一個普通的隨機梯度下降學習,也可以通過設定average=True,實現隨機平均梯度下降。
    • loss,設定 log ,即邏輯迴歸中的對數損失函式

五、案例:癌症分類預測-良/惡性乳腺癌腫瘤預測

  • 資料介紹

    原始資料的下載地址:https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/

    下載資料:breast-cancer-wisconsin.data

  • 資料描述

    • 699條樣本,共11列資料,第一列用語檢索的id,後9列分別是與腫瘤

    相關的醫學特徵,最後一列表示腫瘤型別的數值。

    • 包含16個缺失值,用 ”?” 標出。
  • 步驟分析

    • 缺失值處理
    • 標準化處理
    • 邏輯迴歸預測
  • 完整程式碼

    import pandas as pd
    import numpy as np
    from sklearn.linear_model import LogisticRegression
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    
    # 獲取資料並新增欄位名
    column_name = ['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']
    cancer=pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data",names=column_name)
    cancer.head()
    
    # 缺失值處理
    cancer=cancer.replace(to_replace="?",value=np.nan)
    cancer=cancer.dropna()
    
    # 資料集劃分
    # 1> 提取特徵資料與目標資料
    x=cancer.iloc[:,1:-2]
    y=cancer.iloc[:,-1]
    # 2> 劃分資料集
    x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)
    
    # 標準化處理
    transfer=StandardScaler()
    x_train=transfer.fit_transform(x_train)
    x_test=transfer.transform(x_test)
    
    # 模型訓練
    # 建立一個邏輯迴歸估計器
    estimator=LogisticRegression()
    # 訓練模型,進行機器學習
    estimator.fit(x_train,y_train)
    # 得到模型,列印模型迴歸係數,即權重值
    print("logist迴歸係數為:\n",estimator.coef_)
    
    # 模型評估
    # 方法1:真實值與預測值比對
    y_predict=estimator.predict(x_test)
    print("預測值為:\n",y_predict)
    print("真實值與預測值比對:\n",y_predict==y_test)
    # 方法2:計算準確率
    print("直接計算準確率為:\n",estimator.score(x_test,y_test))
    

六、二分類 - 模型評估 - 精確率、召回率 與 F 1 s c o r e F_1-score

  • 混淆矩陣

    在分類任務下,預測結果與正確標記之間存在四種不同的組合,構成混淆矩陣(適用於多分類)

    預測為正例 預測為假例
    真實為正例 真正例(TP) 偽反例(FN)
    真實為假例 偽正例(FP) 真反例(TN)
  • 精確率

    \frac{真正例}{預測為正例}

  • 召回率 - (查得全,對正樣本的區分能力)

    \frac{真正例}{真實為正例}

  • F 1 s c o r e F_1 - score - (反映了模型的穩健型)

    F 1 = 2 T P 2 T P + F P + F N F_1 = \frac{2TP}{2TP+FP+FN}

  • 分類評估報告 - API

    sklearn.metrics.classification_report(y_true, y_pred, labels=[], target_names=None )

    • y_true
      • 真實目標值
    • y_pred
      • 估計器預測值
    • labels
      • 指定類別對應的數字
    • target_names
      • 目標類別名稱
    • return
      • 每個類別精確率、召回率、 F 1 F_1 係數以及該類佔樣本數

    如:classification_report(y_test, lr.predict(x_test), labels=[2, 4], target_names=['良性', '惡性'])

七、二分類 - 模型評估 - ROC曲線與AUC指標

  • 如何衡量樣本不均衡下的評估?

​ 假設這樣一個情況,如果99個樣本癌症,1個樣本非癌症,不管怎樣我全都預測正例(預設癌症為正例),準確率就為99%但是這樣效果並不好,這就是樣本不均衡下的評估問題。

  • TPR

    T P R = T P T P + F N TPR = \frac{TP}{TP + FN}

    真實為真時預測為真 佔 真實為真的 比例

  • FPR

    F P R = F P F P + T N FPR = \frac{FP}{FP + TN}

    真實為假時預測為真 佔 真實為假的 比例

  • ROC曲線

    ROC 曲線的橫軸就是FPR,縱軸就是TPR

  • AUC指標

    • AUC 的概率意義是隨機取一對正負樣本,正樣本得分大於負樣本的概率
    • AUC 的最小值為0.5,最大值為1,取值越高越好
    • AUC=1,完美分類器,採用這個預測模型時,不管設定什麼閾值都能得出完美預測。絕大多數預測的場合,不存在完美分類器。
    • 0.5<AUC<1,優於隨機猜測。這個分類器(模型)妥善設定閾值的話,能有預測價值。
  • AUC - API

    from sklearn.metrics import roc_auc_score

    • sklearn.metrics.roc_auc_score(y_true, y_score)
      • 計算ROC曲線面積,即AUC值
      • y_true
        • 每個樣本的真實類別,必須為0(反例),1(正例)標記
      • y_score
        • 預測得分,可以是正類的估計概率、置信值或者分類器方法的返回值
      • return
        • AUC值
  • 關於AUC

    • AUC只能用來評價二分類
    • AUC非常適合評價樣本不平衡中的分類器效能

八、案例 - 精確率、召回率、AUC值

# 接上面的腫瘤預測程式碼

#列印精確率、召回率、F1 係數以及該類佔樣本數
print("精確率與召回率為:\n",classification_report(y_test,y_predict,labels=[2,4],target_names=["良性","惡性"]))

###模型評估
#ROC曲線與AUC值
# 把輸出的 2 4 轉換為 0 或 1
y_test=np.where(y_test>2,1,0)  # 大於2就變為1,否則變為0
print("AUC值:\n",roc_auc_score(y_test,y_predict))