準(zhǔn)確度陷阱
我們首先看一下這個(gè)例子

- 何為準(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ì)很高

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)率和召回率


利用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)
我們也可以得到相同的答案

指標(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,可以看到,精確率下降而召回率上升
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)

這也再次說(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é)果



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

我們意識(shí)到面積可以作為指標(biāo)(面積最大為1)
from sklearn.metrics import roc_auc_score
roc_auc_score(y_test,decision_scores)
ROC可以用于比較模型的優(yōu)劣,我們會(huì)選面積更大的模型






