分类算法-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()

posted @ 2019-09-29 18:38  凌晨四点的洛杉矶  阅读(1115)  评论(1编辑  收藏  举报