机器学习性能度量

举报
吕小卒子 发表于 2019/09/20 15:20:02 2019/09/20
【摘要】 我们在进行机器学习时需要衡量机器学习的优劣和本身模型的准确程度,比如简单的衡量数据的准确率和错误率,但是我们更关心的是模型的泛化能力的指标,即基于模型的所选的item相关性以及模型分类指标的好坏。机器学习度量error rate(错误率):把分类错误的样本数占样本总数的比例。 ...

我们在进行机器学习时需要衡量机器学习的优劣和本身模型的准确程度比如简单的衡量数据的准确率和错误率但是我们更关心的是模型的泛化能力的指标即基于模型的所选的item相关性以及模型分类指标的好坏。

机器学习度量

  • error rate(错误率):把分类错误的样本数占样本总数的比例。

                                                                image.png

  • accuracy(精确度):分类正确的样本数占样本总数的比例。

                        image.png

  • training error(训练误差):学习器在训练集上的误差。

  • generalization error(泛华误差):在新样本上的误差。

在机器学习中由很多机器学习算法那么如何选择这些算法和模型如何评估这些算法和模型,评估模型的算法和准确率的方式很多我们依次来介绍一下几个常用的指标。TP、TN、FP、FN、Acc、Recall、F1、ROC和ROI

各种机器学习衡量指标

Accuracy、Precision、Recall和F1-Score

混淆矩阵是按照预测分类和实际分类的类别对比,如下图所示:

æ··æ·ç©éµ

如上表所示行表示预测的label值列表示真实label值。TPFPFNTN分别表示如下意思 * TPtrue positive表示样本的真实类别为正最后预测得到的结果也为正 * FPfalse positive表示样本的真实类别为负最后预测得到的结果却为正 * FNfalse negative表示样本的真实类别为正最后预测得到的结果却为负 * TNtrue negative表示样本的真实类别为负最后预测得到的结果也为负

                                                                image.png


  • Accuracy表示预测结果的精确度预测正确的样本数除以总样本数。

  • Precision准确率表示预测结果中预测为正样本的样本中正确预测为正样本的概率

  • Recall召回率表示在原始样本的正样本中最后被正确预测为正样本的概率

  • Specificity常常称作特异性它研究的样本集是原始样本中的负样本表示的是在这些负样本中最后被正确预测为负样本的概率。

在实际当中我们往往希望得到的precision和recall都比较高比如当FN和FP等于0的时候他们的值都等于1。但是它们往往在某种情况下是互斥的。例如有50个正样本50个负样本结果全部预测为正样本那么TP=50,FP=50,TN=0,FN=0,按照上面的公式计算可以得到正样本的recall却为1precision却为0.5.所以需要一种折衷的方式因此就有了F1-score。

image.png

F1-score表示的是precision和recall的调和平均评估指标. 另外还有一个指标即MCC该指标对于不均衡数据集的评估非常有效公式如下

image.png


ROC和AUC

ROCreceiver operating characteristic),平面的横坐标是false positive rate(FPR)假阳率纵坐标是true positive rate(TPR)真阳率。ROC计算过程如下 1.首先每个样本都需要有一个label值并且还需要一个预测的score值取值0到1; 2.然后按这个score对样本由大到小进行排序假设这些数据位于表格中的一列从上到下依次降序; 3.现在从上到下按照样本点的取值进行划分位于分界点上面的我们把它归为预测为正样本位于分界点下面的归为负样本; 4.分别计算出此时的TPRRecall=TP/P和FPR1-SP=FP/N然后在图中绘制FPR, TPR点。 5.从上往下逐个样本计算最后会得到一条光滑的曲线 。

ROC æ²çº¿

AUC计算 AUCarea under the curve就是ROC曲线下方的面积取值在0.5到1之间因为随机猜测得到额AUC就是0.5。面积如下图所示阴影部分即为AUC面积

AUCé¢ç§¯å¾è§£âå¾çæ¥èª(åèæç®5)

IOU和ROI

上面大多数针对分类准确性的性能评估在机器视觉领域同样也有相应的评估指标。 1.IoU (Intersection over Union)交集并集比 2.ROI (region of interest) , 感兴趣区域 在讲这两个概念前不得不聊聊目标检测.如下图

ç®æ æ£æµ

在计算机中传统目标检测方法大致分为如下三步 1.区域选择 为了对目标的位置进行定位。由于目标可能出现在图像的任何位置而且目标的大小、长宽比例也不确定所以最初采用滑动窗口的策略对整幅图像进行遍历而且需要设置不同的尺度不同的长宽比。这种穷举的策略虽然包含了目标所有可能出现的位置但是缺点也是显而易见的时间复杂度太高产生冗余窗口太多这也严重影响后续特征提取和分类的速度和性能。实际上由于受到时间复杂度的问题滑动窗口的长宽比一般都是固定的设置几个所以对于长宽比浮动较大的多类别目标检测即便是滑动窗口遍历也不能得到很好的区域) 2.特征提取 由于目标的形态多样性光照变化多样性背景多样性等因素使得设计一个鲁棒的特征并不是那么容易。然而提取特征的好坏直接影响到分类的准确性。这个阶段常用的特征有SIFT、HOG等。 3.分类器 主要有SVM, Adaboost等。 总结传统目标检测存在的两个主要问题一个是基于滑动窗口的区域选择策略没有针对性时间复杂度高窗口冗余二是手工设计的特征对于多样性的变化并没有很好的鲁棒性。深度学习特别是CNN的出现使得上述第23步可以合并在一起做。 目标检测的训练集图片准备完成后真正的评价函数是IoUIntersection over Union。为什么要用交集与并集的比值呢

æ¥èªï¼https://www.pyimagesearch.com/2016/11/07/intersection-over-union-iou-for-object-detection/

上图绿色框是真实感兴趣区域红色框是预测区域这种情况下交集确实是最大的但是红色框并不能准确预测物体位置。因为预测区域总是试图覆盖目标物体而不是正好预测物体位置。这时如果我们能除以一个并集的大小就可以规避这种问题

æ¥èªï¼https://www.pyimagesearch.com/2016/11/07/intersection-over-union-iou-for-object-detection/

这样如果我们控制并集不要让并集太大对准确预测是有益的。 下面是wiki上的计算各种指标

AUC ROC


实践

宏平均比微平均更合理但也不是说微平均一无是处具体使用哪种评测机制还是要取决于数据集中样本分布 宏平均Macro-averaging是先对每一个类统计指标值然后在对所有类求算术平均值。 微平均Micro-averaging是对数据集中的每一个实例不分类别进行统计建立全局混淆矩阵然后计算相应指标。

import numpy as np
from sklearn.metrics import accuracy_score
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from sklearn.metrics import cohen_kappa_score
from sklearn.metrics import roc_auc_score
from sklearn.metrics import roc_curve

#import data
y_pred = [0, 2, 1, 3,1,1,1,3,2]
y_true = [0, 1, 1, 3,1,2,1,3,3]
print("accuracy==",accuracy_score(y_pred=y_pred,y_true=y_true))
print("accuracy size==",accuracy_score(y_pred=y_pred,y_true=y_true,normalize=False))
accuracy== 0.6666666666666666
accuracy size== 6

#计算精准率和召回率宏平均比微平均更合理但也不是说微平均一无是处具体使用哪种评测机制还是要取决于数据集中样本分布。
# 宏平均Macro-averaging是先对每一个类统计指标值然后在对所有类求算术平均值。 
# 微平均Micro-averaging是对数据集中的每一个实例不分类别进行统计建立全局混淆矩阵然后计算相应指标。
#print("precision==",precision_score(y_pred=y_pred,y_true=y_true))只针对于二元分类
print("micro precision==",precision_score(y_pred=y_pred,y_true=y_true,average='micro'))
print("macro precision==",precision_score(y_pred=y_pred,y_true=y_true,average='macro'))
micro precision== 0.6666666666666666
macro precision== 0.6875

#print("recall==",recall_score(y_pred=y_pred,y_true=y_true))只针对于二元分类
print("micro recall==",recall_score(y_pred=y_pred,y_true=y_true,average='micro'))
print("macro recall==",recall_score(y_pred=y_pred,y_true=y_true,average='macro'))
micro recall== 0.6666666666666666
macro recall== 0.6041666666666666
#计算f1_score
#print("f1_score==",f1_score(y_pred=y_pred,y_true=y_true))
print("weighted f1_score==",f1_score(y_pred=y_pred,y_true=y_true,average="weighted"))
print("micro f1_score==",f1_score(y_pred=y_pred,y_true=y_true,average="micro"))
print("macro f1_score==",f1_score(y_pred=y_pred,y_true=y_true,average="macro"))
weighted f1_score== 0.7111111111111111
micro f1_score== 0.6666666666666666
macro f1_score== 0.6375
#查看混淆矩阵
print(confusion_matrix(y_pred=y_pred,y_true=y_true))
[[1 0 0 0]
 [0 3 1 0]
 [0 1 0 0]
 [0 0 1 2]]
#查看混淆矩阵报告
print(classification_report(y_pred=y_pred,y_true=y_true))
	           precision    recall  f1-score   support

          0       1.00      1.00      1.00         1
          1       0.75      0.75      0.75         4
          2       0.00      0.00      0.00         1
          3       1.00      0.67      0.80         3

avg / total       0.78      0.67      0.71         9
#可以通过kappa检验两个数据之间的相似性kappa score是一个介于(-1, 1)之间的数. score>0.8意味着好的分类0或更低意味着不好。
cohen_kappa_score(y1=y_pred,y2=y_true)
0.5178571428571428

我们下面看一下多分类的ROC和AUC指标和可视化下面的例子来自于sklearn。

import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle

from sklearn import svm, datasets
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
from scipy import interp

# Import some data to play with
iris = datasets.load_iris()
X = iris.data
y = iris.target

# Binarize the output
y = label_binarize(y, classes=[0, 1, 2])
n_classes = y.shape[1]

# Add noisy features to make the problem harder
random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
X = np.c_[X, random_state.randn(n_samples, 200 * n_features)]

# shuffle and split training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.5,
                                                    random_state=0)

# Learn to predict each class against the other
classifier = OneVsRestClassifier(svm.SVC(kernel='linear', probability=True,
                                 random_state=random_state))
y_score = classifier.fit(X_train, y_train).decision_function(X_test)

# Compute ROC curve and ROC area for each class
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
    fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_score[:, i])
    roc_auc[i] = auc(fpr[i], tpr[i])

# Compute micro-average ROC curve and ROC area
fpr["micro"], tpr["micro"], _ = roc_curve(y_test.ravel(), y_score.ravel())
roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])

# Compute macro-average ROC curve and ROC area

# First aggregate all false positive rates
all_fpr = np.unique(np.concatenate([fpr[i] for i in range(n_classes)]))

# Then interpolate all ROC curves at this points
mean_tpr = np.zeros_like(all_fpr)
for i in range(n_classes):
    mean_tpr += interp(all_fpr, fpr[i], tpr[i])

# Finally average it and compute AUC
mean_tpr /= n_classes

fpr["macro"] = all_fpr
tpr["macro"] = mean_tpr
roc_auc["macro"] = auc(fpr["macro"], tpr["macro"])

# Plot all ROC curves
plt.figure()
plt.plot(fpr["micro"], tpr["micro"],
         label='micro-average ROC curve (area = {0:0.2f})'
               ''.format(roc_auc["micro"]),
         color='deeppink', linestyle=':', linewidth=4)

plt.plot(fpr["macro"], tpr["macro"],
         label='macro-average ROC curve (area = {0:0.2f})'
               ''.format(roc_auc["macro"]),
         color='navy', linestyle=':', linewidth=4)

colors = cycle(['aqua', 'darkorange', 'cornflowerblue'])
for i, color in zip(range(n_classes), colors):
    plt.plot(fpr[i], tpr[i], color=color, lw=lw,
             label='ROC curve of class {0} (area = {1:0.2f})'
             ''.format(i, roc_auc[i]))

plt.plot([0, 1], [0, 1], 'k--', lw=lw)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Some extension of Receiver operating characteristic to multi-class')
plt.legend(loc="lower right")
plt.show()

我们能看到如下图所示图片 

å¤åç±»ROCåAUCå¯è§å

关于IoU指标可以参考文献6里面介绍的很详细,其中有些图片也来源于参考文献。

参考文献



【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。