分類算法-2.精准率和召回率曲線


精准率和召回率是兩個不同的評價指標,很多時候它們之間存在着差異,具體在使用的時候如何解讀精准率和召回率,應該視具體使用場景而定

有些場景,人們可能更注重精准率,如股票預測系統,我們定義股票升為1,股票降為0,我們更關心的是未來升的股票的比例,而在另外一些場景中,人們更加注重召回率,如癌症預測系統,定義健康為1,患病為0,我們更關心癌症患者檢查的遺漏情況。

F1 Score

F1 Score 兼顧精准率和召回率,它是兩者的調和平均值

\[\frac{1}{F1} = \frac{1}{2}(\frac{1}{Precision} + \frac{1}{recall}) \]

\[F1 = \frac{2\cdot precision\cdot recall}{precision+recall} \]

定義F1 Score

def f1_score(precision,recall):
    try:
        return 2*precision*recall/(precision+recall)
    except:
        return 0

由上看出,F1 Score更偏向於分數小的那個指標

Precision-Pecall的平衡

精准率和召回率是兩個互相矛盾的目標,提高一個指標,另一個指標就會不可避免的下降。如何達到兩者之間的一個平衡呢?

回憶邏輯回歸算法的原理:將一個結果發生的概率大於0.5,就把它分類為1,發生的概率小於0.5,就把它分類為0,決策邊界為:\(\theta ^T \cdot X_b = 0\)

這條直線或曲線決定了分類的結果,平移決策邊界,使\(\theta ^T \cdot X_b\)不等於0而是一個閾值:\(\theta ^T \cdot X_b = threshold\)


圓形代表分類結果為0,五角星代表分類結果為1,由上圖可以看出,精准率和召回率是兩個互相矛盾的指標,隨着閾值的逐漸增大,召回率逐漸降低,精准率逐漸增大。


編程實現不同閥值下的預測結果及混淆矩陣

from sklearn.linear_model import LogisticRegression

# 數據使用前一節處理后的手寫識別數據集
log_reg = LogisticRegression()
log_reg.fit(x_train,y_train)

求每個測試數據在邏輯回歸算法中的score值:

decision_score = log_reg.decision_function(x_test)

不同閥值下預測的結果

y_predict_1 = numpy.array(decision_score>=-5,dtype='int')
y_predict_2 = numpy.array(decision_score>=0,dtype='int')
y_predict_3 = numpy.array(decision_score>=5,dtype='int')

查看不同閾值下的混淆矩陣:

精准率-召回率曲線

求出0.1步長下,閾值在[min,max]區間下的精准率和召回率,查看其曲線特征:

threshold_scores = numpy.arange(numpy.min(decision_score),numpy.max(decision_score),0.1)

precision_scores = []
recall_scores = []

# 求出每個分類閾值下的預測值、精准率和召回率
for score in threshold_scores:
    y_predict = numpy.array(decision_score>=score,dtype='int')
    precision_scores.append(precision_score(y_test,y_predict))
    recall_scores.append(recall_score(y_test,y_predict))

畫出精准率和召回率隨閾值變化的曲線

plt.plot(threshold_scores,precision_scores)
plt.plot(threshold_scores,recall_scores)
plt.show()

畫出精准率-召回率曲線

plt.plot(precision_scores,recall_scores)
plt.show()

sklearn中的精准率-召回率曲線

from sklearn.metrics import precision_recall_curve

precisions,recalls,thresholds = precision_recall_curve(y_test,decision_score)

# sklearn中最后一個精准率為1,召回率為0,沒有對應的threshold
plt.plot(thresholds,precisions[:-1])
plt.plot(thresholds,recalls[:-1])
plt.show()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM