分類算法的評(píng)價(jià)

準(zhǔn)確度陷阱

我們首先看一下這個(gè)例子

癌癥預(yù)測(cè)系統(tǒng)

  • 何為準(zhǔn)確度陷阱?
    對(duì)于極度偏斜的數(shù)據(jù),只使用分類準(zhǔn)確度是遠(yuǎn)遠(yuǎn)不夠的,我們很容易完全沒(méi)法判斷算法的好壞。

混淆矩陣(二分類問(wèn)題)

二分類

精準(zhǔn)率和召回率

  • 精準(zhǔn)率:預(yù)測(cè)為真的情況下預(yù)測(cè)正確的概率
    (例如在癌癥預(yù)測(cè)系統(tǒng)中,精準(zhǔn)率就代表了預(yù)測(cè)癌癥預(yù)測(cè)的成功率)


    精準(zhǔn)率
  • 召回率:真實(shí)發(fā)生我數(shù)據(jù)中我們成功預(yù)測(cè)的概率
    (例如在癌癥預(yù)測(cè)系統(tǒng)中,召回率代表患癌癥總?cè)藬?shù)中我們通過(guò)算法預(yù)測(cè)成功的概率)
    召回率

    現(xiàn)在我們回到開(kāi)頭的那個(gè)問(wèn)題,我們使用精準(zhǔn)率和召回率進(jìn)行分析
    對(duì)比

    我們意識(shí)到準(zhǔn)確率沒(méi)法判斷的作用,而精準(zhǔn)率和召回率可以用來(lái)判斷
    下面進(jìn)行代碼實(shí)現(xiàn)
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#構(gòu)造出一個(gè)極度偏斜的數(shù)據(jù)
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=666)
#實(shí)際上這里size默認(rèn)是0.2
from sklearn.linear_model import LogisticRegression 
log_reg=LogisticRegression()
log_reg.fit(x_train,y_train)
log_reg.score(x_test,y_test)

這里我們發(fā)現(xiàn)準(zhǔn)確度很高,實(shí)際上全部判斷為0也會(huì)很高


高準(zhǔn)確度
y_log_predict=log_reg.predict(x_test)
def TN(y_true,y_predict):
    return np.sum((y_true==0)&(y_predict==0))
def FP(y_true,y_predict):
    return np.sum((y_true==0)&(y_predict==1))
def FN(y_true,y_predict):
    return np.sum((y_true==1)&(y_predict==0))
def TP(y_true,y_predict):
    return np.sum((y_true==1)&(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 precesion_score(y_true,y_predict):
    tp=TP(y_true,y_predict)
    fp=FP(y_true,y_predict)
    try:
        return tp/(tp+fp)#異常檢測(cè),正如前面的例子,唯一的異常便是分母為零的情況
    except:
        return 0
def recall_score(y_true,y_predict):
    tp=TP(y_true,y_predict)
    fn=FN(y_true,y_predict)
    try:
        return tp/(tp+fn)
    except:
        return 0

我們分別可以得到其精準(zhǔn)率和召回率


精準(zhǔn)率

召回率
利用sklearn中的函數(shù)實(shí)現(xiàn)
#sklearn中的
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test,y_log_predict)
from sklearn.metrics import precision_score
precesion_score(y_test,y_log_predict)
from sklearn.metrics import recall_score
recall_score(y_test,y_log_predict)

我們也可以得到相同的答案


sklearn實(shí)現(xiàn)

指標(biāo)的選擇

我們同時(shí)擁有精準(zhǔn)率和召回率兩個(gè)指標(biāo),那么我們依據(jù)哪一個(gè)去判斷呢?

  • 有時(shí)候我們會(huì)注重精準(zhǔn)率,如股票預(yù)測(cè),我們更加關(guān)系預(yù)測(cè)的數(shù)據(jù)中正確的概率
  • 有時(shí)候我們會(huì)注重召回率,如病人診斷,我們更加關(guān)心實(shí)際數(shù)據(jù)中成功預(yù)測(cè)概率
  • 二者兼顧:F1 Score,是二者的調(diào)和平均值


    F1 Score

    對(duì)前面的代碼進(jìn)行一次總結(jié)同時(shí)使用F1Score

def f1_score(precesion,recall):
    try:
        return 2*precesion*recall/(precesion+recall)
    except:
        return 0
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#構(gòu)造出一個(gè)極度偏斜的數(shù)據(jù)
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=666)
#實(shí)際上這里size默認(rèn)是0.2
from sklearn.linear_model import LogisticRegression 
log_reg=LogisticRegression()
log_reg.fit(x_train,y_train)
y_log_predict=log_reg.predict(x_test)
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test,y_log_predict)
from sklearn.metrics import precision_score
precesion_score(y_test,y_log_predict)
from sklearn.metrics import recall_score
recall_score(y_test,y_log_predict)
from sklearn.metrics import f1_score
f1_score(y_test,y_log_predict)
  • 我們實(shí)際中會(huì)發(fā)現(xiàn)精準(zhǔn)率和召回率之間互相矛盾,不可能同時(shí)較高,這時(shí)我們要做出取舍選擇。
  • 我們回顧一下邏輯回歸中的決策邊界,我們可以通過(guò)改變常數(shù)項(xiàng)來(lái)移動(dòng)這根線


    決策邊界

    移動(dòng)

    如圖,改變常數(shù)(即閾值)我們會(huì)相應(yīng)的改變精準(zhǔn)率和召回率
    下面我們?cè)谇笆龃a中繼續(xù)實(shí)現(xiàn)這個(gè)部分

decision_scores=log_reg.decision_function(x_test)#返回一個(gè)向量,元素為score值
y_predict2=np.array(decision_scores>=5,dtype='int')#這里選定閾值為5,之前閾值為0
confusion_matrix(y_test,y_predict2)
precision_score(y_test,y_predict2)
recall_score(y_test,y_predict2)

我們可以看到,精準(zhǔn)率上升而召回率下降


閾值為5

我們將閾值改為-5,可以看到,精確率下降而召回率上升

y_predict3=np.array(decision_scores>=-5,dtype='int')
confusion_matrix(y_test,y_predict3)
precision_score(y_test,y_predict3)
recall_score(y_test,y_predict3)
閾值-5

這也再次說(shuō)明了,這兩者是相互制約的,一者上升一者下降,不會(huì)出現(xiàn)理想的兩者都上升的理想局面。
可以通過(guò)可視化的方式來(lái)看到這一特性


精確率和召回率

我們也可以使用sklearn找到Precesion-Recall曲線

from sklearn.metrics import precision_recall_curve
precesions,recalls,thresholds=precision_recall_curve(y_test,decision_scores)
precesions.shape
recalls.shape
thresholds.shape#少一個(gè)元素
import matplotlib.pyplot as plt
plt.plot(thresholds,precesions[:-1])#去掉一個(gè)值
plt.plot(thresholds,recalls[:-1])
plt.show
plt.plot(precesions,recalls)
plt.show

對(duì)應(yīng)于代碼我們有如下結(jié)果


向量大小

曲線1

曲線2

ROC曲線——描述TPR和FPR之間的關(guān)系

  • TPR=Recall(True Positive Rate)
  • FPR(False Positive Rate)


    TPR&FPR

    兩者同時(shí)增加減少
    這里僅使用sklearn演示roc

from sklearn.metrics import roc_curve
fprs,tprs,thresholds = roc_curve(y_test,decision_scores)
plt.plot(fprs,tprs)
plt.show
FTP、TPR

我們意識(shí)到面積可以作為指標(biāo)(面積最大為1)

from sklearn.metrics import roc_auc_score
roc_auc_score(y_test,decision_scores)

ROC可以用于比較模型的優(yōu)劣,我們會(huì)選面積更大的模型

?著作權(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)容