机器学习:分类模型性能评估(Accurary Precision Recall F1分数 PR ROC)

本文详细介绍了机器学习中常用的评估指标,如精准率、召回率、F1分数和ROC/AUC曲线,以及它们在衡量分类模型性能时的应用,特别强调了在类别不平衡问题中的适用性。通过实例演示了如何使用鸢尾花数据集计算这些指标并绘制PR曲线和ROC曲线。
摘要由CSDN通过智能技术生成

1.分类模型评估指标—精准率、召回率、ROC曲线

所有事情都需要评估好坏,尤其是量化的评估指标

机器学习有很多评估的指标。有了这些指标我们就横向的比较哪些模型的表现更好。我们先从整体上来看看主流的评估指标都有哪些:

准确率 – Accuracy      精确率(差准率)- Precision

召回率(查全率)- Recall   F1分数    ROC曲线      AUC曲线

为了方便理解对分类问题进行图解

我们有10张照片,5张男性、5张女性。如下图

一个判断性别的机器学习模型,当我们使用它来判断“是否为男性”时,会出现4种情况

男性为正样本,女性为负样本 

1.实际为男性,预测为男性 TP – True Positive

2.实际为女性,错误地预测为男性 FP – False Positive

3.实际为男性,错误地预测为女性 FN – False Negative

4.实际为女性,预测为女性 TN – True Negative

1.1 准确率-Accuracy

预测正确的结果占总样本的百分比,公式如下:

Accuracy=(TP+TN)/(TP+TN+FP+FN)

1.2 精确率(差准率)- Precision

所有被预测为正的样本中实际为正的样本的概率,公式如下:实际为正的样本中被预测为正样本的概率,其公式如下

Precision =TP/(TP+FP)

1.3 召回率(查全率)- Recall

实际为正的样本中被预测为正样本的概率,其公式如下

Recall=TP/(TP+FN)

召回率越高,代表实际坏用户被预测出来的概率越高

1.4 PR曲线

如果我们把精确率(Precision)和召回率(Recall)之间的关系用图来表达,就是下面的PR曲线

PR曲线:PR曲线是一个用于评估二元分类问题的工具。它绘制了模型预测的精确度(Precision)和召回率(Recall)之间的关系。曲线的x轴表示Recall,y轴表示Precision。理想的PR曲线应该尽可能地接近右上角,这意味着模型在保持高召回率的同时,也能保持高精确度。

1.5 F1分数

为了综合两者的表现,在两者之间找一个平衡点,就出现了一个 F1分数。

F1=\left ( 2\times Precision\times Recall \right )/\left (Precision+Recall\right )

1.6 ROC曲线

ROC(Receiver Operating Characteristic)曲线,又称接受者操作特征曲线。该曲线最早应用于雷达信号检测领域,用于区分信号与噪声。后来人们将其用于评价模型的预测能力,ROC 曲线是基于混淆矩阵得出的。

ROC 曲线中的主要两个指标就是真正率假正率, 上面也解释了这么选择的好处所在。其中横坐标为假正率(FPR),纵坐标为真正率(TPR),下面就是一个标准的 ROC 曲线图。

真正率(TPR) = 灵敏度 = TP/(TP+FN)

假正率(FPR) = 1- 特异度 = FP/(FP+TN)

参考一文看懂机器学习指标:准确率、精准率、召回率、F1、ROC曲线、AUC曲线  

2.实现

对鸢尾花的分类进行评估

文件鸢尾花分类

链接:https://pan.baidu.com/s/11lHWBdgBlzm9H7iBYlFxJQ 
提取码:6666


# 绘制P-R曲线(精确率-召回率曲线)
print(__doc__)
# 绘制P-R曲线(精确率-召回率曲线)

# plt:绘图
import matplotlib.pyplot as plt
# np:处理矩阵运算
import numpy as np
# svm:支持向量机
# datasets:数据集模块 后续使用该模块导入"鸢尾花数据集"
from sklearn import svm, datasets
# precision_recall_curve:精确率-召回率曲线
from sklearn.metrics import precision_recall_curve
# average_precision_score:根据预测分数计算平均精度(AP)
from sklearn.metrics import average_precision_score
# train_test_split:训练集与测试集的拆分模块
from sklearn.model_selection import train_test_split
# label_binarize:标签的二处理
from sklearn.preprocessing import label_binarize
# OneVsRestClassifier:一对其余 每次将某一类作为正类 其余作为负类
from sklearn.multiclass import OneVsRestClassifier
# 导入鸢尾花数据集
iris = datasets.load_iris()
# x为数据集的样本特征矩阵 150*4
x = iris.data 
# y是类别标签矩阵 150*1
y = iris.target
y
[[1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [1 0 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]]
# Add noisy features 增加了800维的噪声特征
random_state = np.random.RandomState(0)
n_samples, n_features = x.shape
# n_samples=150  n_features=4
(150, 4)
# 在150×4的矩阵后增加了150*800的矩阵
x = np.c_[x, random_state.randn(n_samples, 200*n_features)]

# 进行训练集与测试集的拆分 比例为0.5
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size=.5,random_state = random_state)

# 构建分类器 进行二类问题的转化
classifier = OneVsRestClassifier(svm.SVC(kernel='linear',probability=True,random_state=random_state))
# 利用训练集进行拟合 并将测试集传入获取对测试集中y值的预测
y_score = classifier.fit(x_train,y_train).decision_function(x_test)


# 将y_score这个预测值与每个样本的真实值进行比较
precision = dict()
recall = dict()
average_precision = dict()
for i in range(n_classes):
    #下划线是返回的阈值。作为一个名称:此时“_”作为临时性的名称使用。
    #表示分配了一个特定的名称,但是并不会在后面再次用到该名称。
    precision[i], recall[i],_ = precision_recall_curve(y_test[:,i],y_score[:,i])
    average_precision[i] = average_precision_score(y_test[:,i],y_score[:,i])
    # 切片 第i个类的分类结果性能

# Compute micro-average curve and area. ravel()将多维数组降为一维
precision['micro'],recall['micro'],_ = precision_recall_curve(y_test.ravel(),y_score.ravel())

average_precision['micro'] = average_precision_score(y_test, y_score, average='micro')

plt.clf()# 清楚当前图像窗口
plt.plot(recall['micro'],precision['micro'],label='micro-average Precision-recall curve (area ={0:0.2f})'.format(average_precision['micro']))

for i in range(n_classes):
    plt.plot(recall[i], precision[i], label='Precision recall curve of class {0} (area = {1:0.2f})'.format(i,average_precision[i]))

#调整刻度范围 
plt.xlim([0.0,1.0])
plt.ylim([0.0,1.05])
# 横纵坐标
plt.xlabel('Recall',fontsize=16)
plt.ylabel('Precision',fontsize=16)
# 图像名称 图例
plt.title('Extension of Precision-Recall curve to multi-class',fontsize=16)
plt.legend(loc="lower right")
plt.show()

3.小结

模型的精确度和召回率互相制约,P-R曲线越向右上凸,表示模型性能越好。

这里特指负样本数量远大于正样本时,在这类问题中,我们往往更关注正样本是否被正确分类,即TP的值。PR曲线更适合度量类别不平衡问题中:

因为在PR曲线中TPR和FPR的计算都会关注TP,PR曲线对正样本更敏感。
而ROC曲线正样本和负样本一视同仁,在类别不平衡时ROC曲线往往会给出一个乐观的结果。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值