机器学习性能度量
我们在进行机器学习时需要衡量机器学习的优劣和本身模型的准确程度比如简单的衡量数据的准确率和错误率但是我们更关心的是模型的泛化能力的指标即基于模型的所选的item相关性以及模型分类指标的好坏。
机器学习度量
error rate(错误率):把分类错误的样本数占样本总数的比例。
accuracy(精确度):分类正确的样本数占样本总数的比例。
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表示样本的真实类别为负最后预测得到的结果也为负
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。
F1-score表示的是precision和recall的调和平均评估指标. 另外还有一个指标即MCC该指标对于不均衡数据集的评估非常有效公式如下
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.从上往下逐个样本计算最后会得到一条光滑的曲线 。
AUC计算 AUCarea under the curve就是ROC曲线下方的面积取值在0.5到1之间因为随机猜测得到额AUC就是0.5。面积如下图所示阴影部分即为AUC面积
IOU和ROI
上面大多数针对分类准确性的性能评估在机器视觉领域同样也有相应的评估指标。 1.IoU (Intersection over Union)交集并集比 2.ROI (region of interest) , 感兴趣区域 在讲这两个概念前不得不聊聊目标检测.如下图
在计算机中传统目标检测方法大致分为如下三步 1.区域选择 为了对目标的位置进行定位。由于目标可能出现在图像的任何位置而且目标的大小、长宽比例也不确定所以最初采用滑动窗口的策略对整幅图像进行遍历而且需要设置不同的尺度不同的长宽比。这种穷举的策略虽然包含了目标所有可能出现的位置但是缺点也是显而易见的时间复杂度太高产生冗余窗口太多这也严重影响后续特征提取和分类的速度和性能。实际上由于受到时间复杂度的问题滑动窗口的长宽比一般都是固定的设置几个所以对于长宽比浮动较大的多类别目标检测即便是滑动窗口遍历也不能得到很好的区域) 2.特征提取 由于目标的形态多样性光照变化多样性背景多样性等因素使得设计一个鲁棒的特征并不是那么容易。然而提取特征的好坏直接影响到分类的准确性。这个阶段常用的特征有SIFT、HOG等。 3.分类器 主要有SVM, Adaboost等。 总结传统目标检测存在的两个主要问题一个是基于滑动窗口的区域选择策略没有针对性时间复杂度高窗口冗余二是手工设计的特征对于多样性的变化并没有很好的鲁棒性。深度学习特别是CNN的出现使得上述第23步可以合并在一起做。 目标检测的训练集图片准备完成后真正的评价函数是IoUIntersection over Union。为什么要用交集与并集的比值呢
上图绿色框是真实感兴趣区域红色框是预测区域这种情况下交集确实是最大的但是红色框并不能准确预测物体位置。因为预测区域总是试图覆盖目标物体而不是正好预测物体位置。这时如果我们能除以一个并集的大小就可以规避这种问题
这样如果我们控制并集不要让并集太大对准确预测是有益的。 下面是wiki上的计算各种指标
实践
宏平均比微平均更合理但也不是说微平均一无是处具体使用哪种评测机制还是要取决于数据集中样本分布 宏平均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()
我们能看到如下图所示图片
关于IoU指标可以参考文献6里面介绍的很详细,其中有些图片也来源于参考文献。
参考文献
《Machine Learning in Action》
- 点赞
- 收藏
- 关注作者
评论(0)