分类评价指标


1.概念

  • 二分类:一个目标的标签只有两种之一(例如:0或1,对应的one-hot标签为[1,0]或[0,1])。对于这种问题,一般可以采用softmax或者logistic回归来完成,分别采用cross-entropy和mse损失函数来进行网络训练,分别输出概率分布和单个的sigmoid预测值(0,1)。
  • 多分类:一个目标的标签是几种之一(如:0,1,2…)

2.评价指标

① 准确率(accuracy)和错误率(error rate)

accuracy = (TP+TN)/ (P+N)或者accuracy = (TP+TN)/ (T+F)
error rate = (FP+FN) / (P+N)或者(FP+FN) / (T+F)
accuracy = 1 - error rate
可见 :准确率、错误率是对分类器在整体数据上的评价指标。

② 精确率(precision)

precision=TP /(TP+FP)
可见 :精确率是对分类器在预测为阳性的数据上的评价指标。

③ 召回率(recall)/真阳率(true positive rate)/灵敏度(sensitivity)

recall = TPR = sensitivity = TP/(TP+FN)
可见 :召回率/真阳率/灵敏度是对分类器在整个阳性数据上的评价指标。

④ F1-measure

F1-measure = 2 * (recall * precision / (recall + precision))
包含两种:micro和macro(对于多类别分类问题, 注意 区别于多标签分类问题)

  • micro
    计算出所有类别总的precision和recall,然后计算F1-measure
  • macro
    计算出每一个类的precison和recall后计算F1-measure,最后将F1-measure平均
    可见 :F1-measure是对两个矛盾指标precision和recall的一种调和。

⑤ 假阳率(false positive rate)

FPR=FP / (FP+TN)
可见 :假阳率是对分类器在整个阴性数据上的评价指标,针对的是假阳。

⑥ 特异度(specificity)

specificity = 1- FPR
可见 :特异度是对分类器在整个阴性数据上的评价指标,针对的是真阴。

⑦ ROC曲线(receiver operation curve)和AUC(area under curve)

作用:灵敏度与特异度的综合指标
横坐标:FPR/1-specificity
纵坐标:TPR/sensitivity/recall
AUC是ROC右下角的面积,越大,表示分类器的性能越好
包含两种:micro和macro(对于多类别分类问题, 注意 区别于多标签分类问题)
假设一共有M个样本,N个类别。预测出来的概率矩阵P(M,N),标签矩阵L (M,N)

  • micro
    根据P和L中的每一列(对整个数据集而言),计算出各阈值下的TPR和FPR,总共可以得到N组数据,分别画出N个ROC曲线,最后取平均
  • macro
    将P和L按行展开,然后转置为两列,最后画出一个ROC曲线

⑧ PR曲线(precision recall curve)

横轴:recall
纵轴:precision

  • 评判:
    • 直观看,P-R包围的面积越大越好,P=R的点越大越好;
    • 通过F1-measure来看

比较ROC和P-R : 当样本中的正、负比例不平衡的时候,ROC曲线基本保持不变,而P-R曲线变化很大,原因如下:
当负样本的比例增大时,在召回率一定的情况下,那么表现较差的模型必然会召回更多的负样本,TP降低,FP迅速增加(对于性能差的分类器而言),precision就会降低,所以P-R曲线包围的面积会变小。

⑨ 混淆矩阵(confusion matrix)

行表示的是样本中的一种真类别被预测的结果,列表示的是一种被预测的标签所对应的真类别。

3. 代码

3.代码
注意 :以下的代码是合在一起写的,有注释。

from sklearn import datasets
import numpy as np
from sklearn.preprocessing import label_binarize
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, precision_score, accuracy_score,recall_score,\
f1_score,roc_auc_score, precision_recall_fscore_support, roc_curve, classification_report
import matplotlib.pyplot as plt

iris = datasets.load_iris()
x, y = iris.data, iris.target
print("label:", y)
n_class = len(set(iris.target))
y_one_hot = label_binarize(y, np.arange(n_class))

# alpha = np.logspace(-2, 2, 20)  #设置超参数范围
# model = LogisticRegressionCV(Cs = alpha, cv = 3, penalty = 'l2')  #使用L2正则化
model = LogisticRegression()  # 内置了最大迭代次数了,可修改
model.fit(x, y)
y_score = model.predict(x)  # 输出的是整数标签
mean_accuracy = model.score(x, y)
print("mean_accuracy: ", mean_accuracy)
print("predict label:", y_score)
print(y_score==y)
print(y_score.shape)
y_score_pro = model.predict_proba(x)  # 输出概率
print(y_score_pro)
print(y_score_pro.shape)
y_score_one_hot = label_binarize(y_score, np.arange(n_class))  # 这个函数的输入必须是整数的标签哦
print(y_score_one_hot.shape)

obj1 = confusion_matrix(y, y_score)  # 注意输入必须是整数型的,shape=(n_samples, )
print('confusion_matrix\n', obj1)

print(y)
print('accuracy:{}'.format(accuracy_score(y, y_score)))  # 不存在average
print('precision:{}'.format(precision_score(y, y_score,average='micro')))
print('recall:{}'.format(recall_score(y, y_score,average='micro')))
print('f1-score:{}'.format(f1_score(y, y_score,average='micro')))
print('f1-score-for-each-class:{}'.format(precision_recall_fscore_support(y, y_score)))  # for macro
# print('AUC y_pred = one-hot:{}\n'.format(roc_auc_score(y_one_hot, y_score_one_hot,average='micro')))  # 对于multi-class输入必须是proba,所以这种是错误的

# AUC值
auc = roc_auc_score(y_one_hot, y_score_pro,average='micro')  # 使用micro,会计算n_classes个roc曲线,再取平均
print("AUC y_pred = proba:", auc)
# 画ROC曲线
print("one-hot label ravelled shape:", y_one_hot.ravel().shape)
fpr, tpr, thresholds = roc_curve(y_one_hot.ravel(),y_score_pro.ravel())   # ravel()表示平铺开来,因为输入的shape必须是(n_samples,)
print("threshold: ", thresholds)
plt.plot(fpr, tpr, linewidth = 2,label='AUC=%.3f' % auc)
plt.plot([0,1],[0,1], 'k--')  # 画一条y=x的直线,线条的颜色和类型
plt.axis([0,1.0,0,1.0])  # 限制坐标范围
plt.xlabel('False Postivie Rate')
plt.ylabel('True Positive Rate')
plt.legend()
plt.show()

# p-r曲线针对的是二分类,这里就不描述了

ans = classification_report(y, y_score,digits=5)  # 小数点后保留5位有效数字
print(ans)


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM