機器學習“傻瓜式”理解(13)混淆矩陣(評價分類結果)

之前的章節我們介紹了多種機器學習算法:
KNN->用於解決分類問題
線性迴歸->用於解決迴歸問題
邏輯迴歸->既可以解決分類問題,又可以解決迴歸問題
。。。
總體來說,我們機器學習的算法要解決的問題分爲兩大類,分別爲:分類問題和迴歸問題。
從之前的內容來看,我們通過衆多的機器學習算法得到的模型需要進行評估。
評價迴歸問題:MSE,MAE,RMSE,R^2(目前學習爲止最好的評價算法)
評價分類問題:分類準確度(accuracy_score)
經驗之談,評價分類問題要比評價迴歸問題要複雜的多。
小引子:
我們搭建一個新冠肺炎檢測系統,輸如我們想要測試的人的數據進行檢測,來根據得到的結果判斷此人是否得了新冠肺炎。假設我們通過學習得到的模型預測的準確度爲99.9%,
並且得有新冠肺炎的概率爲0.1%,那麼我們就算系統什麼都不做,還是會有99.9%的預測準確度。
通過分析原因我們便得到,對於極度偏斜的數據(Skewed data),只使用分類準確度的方法來評估是遠遠不夠的。

極度偏斜的數據:不同類型之間的樣本的數量相差特別大,假設新冠肺炎感染概率1:10000

面對這種極度偏斜的數據,即使系統什麼都不做,也可以達到十分大的準確度,此時我們可以通過混淆矩陣來進行進一步的分析。
對於各種概念,通過一張圖進行相關介紹分析:
在這裏插入圖片描述
混淆矩陣代碼實現:

'''Confusion Matrix'''
def TN(y_true,y_predict):
    '''check'''
    assert len(y_true) == len(y_predict)
    return np.sum((y_true==0) & (y_predict==0))

def TP(y_true,y_predict):
    '''check'''
    assert len(y_true) == len(y_predict)
    return np.sum((y_true==1) & (y_predict==1))

def FN(y_true,y_predict):
    '''check'''
    assert len(y_true) == len(y_predict)
    return np.sum((y_true==1) & (y_predict==0))

def FP(y_true,y_predict):
    '''check'''
    assert len(y_true) == len(y_predict)
    return np.sum((y_true==0) & (y_predict==1))

def confusion_matrix(y_true,y_predict):
    return np.array([
        [TN(y_true,y_predict),FP(y_true,y_predict)],
        [FN(y_true,y_predict),TP(y_true,y_predict)]
    ])

def Precision(y_true,y_predict):
    tp = TP(y_true,y_predict)
    fp = FP(y_true,y_predict)
    try:
        return tp / (tp+fp)
    except:
        return 0.0

def Recall(y_true,y_predict):
    fn = FN(y_true,y_predict)
    tp = TP(y_true,y_predict)
    try:
        return tp / (tp + fn)
    except:
        return 0.0

評價分類結果的另外一種方式:F1 Score
在進行模型預測的過程中,通常會遇到下面的問題,例如我們需要單獨考慮模型的精準率或者召回率,還可能出現我們需要同時考慮精準率和召回率兩種指標,由此便產生了新的評價分類方式:F1_Score
在這裏插入圖片描述
F1指的是精準率和召回率的調和平均值。

評價分類結果的另一種方式:P-R曲線
上面我們談到的是我們可以通過精準率和召回率進行評價分類的結果,然而我們也可以通過調整閾值(threshold)來調整精準率和召回率的比重。
閾值越大,精準率提高,召回率降低。
閾值越小,精準率降低,召回率提高。
精準率和召回率是相互制約相互矛盾的兩個變量,不能同時增高。
根據前面所講到的精準率和召回率的定義,我們可以通過下面的幾個案例進行相關分析:
假設我們所關注的事件還是爲1
1.thershold = 0
在這裏插入圖片描述
精準率:4/5 = 0.8
召回率:4/6 = 0.67

2.threshold > 0
在這裏插入圖片描述
精準率:2/2 = 1
召回率:2/6 = 0.33

3.threshold < 0
在這裏插入圖片描述
精準率:6/8 = 0.75
召回率:6/6 = 1
代碼演示

#實例:調整閾值大小,進行調整精準率和召回率
import numpy as np
# 導入數據
from sklearn import datasets

# 導入模式數字集
digits = datasets.load_digits()
X = digits.data
y = digits.target.copy()

# 爲了更好的實驗效果,將數據更改成極度偏斜的數據,解決二分類問題
y[digits.target == 9] = 1
y[digits.target !=9] = 0

# 劃分訓練數據集和測試數據集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state = 666)

# 進行邏輯迴歸預測
from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression()
log_reg.fit(X_train,y_train)

# 1.閾值threshold = 0
y_predict_1 = log_reg.predict(X_test)

# 得到混淆矩陣
from sklearn.metrics import confusion_matrix
con_m = confusion_matrix(y_test,y_predict_1)
print(con_m)

# 計算精準率
from sklearn.metrics import precision_score
p_s = precision_score(y_test,y_predict_1)
print(p_s)

# 計算召回率
from sklearn.metrics import recall_score
r_s  = recall_score(y_test,y_predict_1)
print(r_s)


運行結果:
在這裏插入圖片描述

# 更改閾值
# 思路:基於決策函數decision_function方法,改變score的值,不在通過predict方法
# 閾值threshold = 5
decision_score = log_reg.dicision_function(X_test)

y_predict_5 = np.array(decision_score >= 5,dtype='int')
# decision_score >= -5便是將閾值更改爲-5
con_m_5 = confusion_matrix(y_test,y_predict_5)
# 混淆矩陣:array([[404,   1],
#                 [ 21,  24]], dtype=int64)

precision_score(y_test,y_predict_5)
# 精準率:0.96
recall_score(y_test,y_predict_5)
# 召回率:0.5333333333333333

P-R曲線
代碼部分只是通過for循環或者通過scikit也可以得出,不在此處演示,只講解P-R曲線。
如圖所示:
在這裏插入圖片描述
①這是兩條P-R曲線
②圖中曲線開始急劇下降的點便是精準率和召回率平衡的點。
③與座標軸面積越大的模型越優。
④p-r曲線對於選擇算法,超參數等等十分有好處,但是一般用的是roc曲線。

評價分類結果的另一種方式:ROC曲線
ROC(Receiver Operation Characteristic Curve)
通過一張圖來詳細的理清roc的種種概念。
在這裏插入圖片描述
封裝代碼:

def TPR(y_true,y_predict):
    fn = FN(y_true,y_predict)
    tp = TP(y_true,y_predict)

    try:
        return tp / (tp + fn)
    except:
        return 0.0

def FPR(y_true,y_predict):
    fp = FP(y_true, y_predict)
    tn = TN(y_true, y_predict)
    try:
        return fp / (fp + tn)
    except:
        return 0.0

混淆矩陣解決多分類問題
在具體介紹之前,首先介紹一種極其重要的思想:
在機器學習的過程中,我們不可避免的會出現很多的問題,但是這些問題並不一定全都來源於算法本身,我們要學會從樣本數據的層面分析出現的問題,理解數據特徵。

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