动力网站建设,做网站 你的出路在哪里,云虚服务器网站建设,门户网站建设 突出服务混淆矩阵Confusion Matrix
混淆矩阵定义
混淆矩阵是机器学习中总结分类模型预测结果的情形分析表#xff0c;以矩阵形式将数据集中的记录按照真实的类别与分类模型预测的类别判断两个标准进行汇总。其中矩阵的行表示真实值#xff0c;矩阵的列表示预测值#xff0c;下面我…混淆矩阵Confusion Matrix
混淆矩阵定义
混淆矩阵是机器学习中总结分类模型预测结果的情形分析表以矩阵形式将数据集中的记录按照真实的类别与分类模型预测的类别判断两个标准进行汇总。其中矩阵的行表示真实值矩阵的列表示预测值下面我们先以二分类为例看下矩阵表现形式如下
预测/真实1Postive0Negative1 (Postive)TPTrue Postive:真阳FP (False Postive:假阳)0NegativeFN (False Negative:假阴)TN (True Negative:真阴) 在讲矩阵之前我们先复习下之前在讲分类评估指标中定义的一些符号含义如下
TP(True Positive)将正类预测为正类数真实为0预测也为0FN(False Negative)将正类预测为负类数真实为0预测为1FP(False Positive)将负类预测为正类数 真实为1预测为0TN(True Negative)将负类预测为负类数真实为1预测也为1
刚才分析的是二分类问题那么对于多分类问题混淆矩阵表示的含义也基本相同这里我们以三类问题为例看看如何根据混淆矩阵计算各指标值。 与二分类混淆矩阵一样矩阵行数据相加是真实值类别数列数据相加是分类后的类别数那么相应的就有以下计算公式;
精确率_类别1a/(adg)召回率_类别1a/(abc)
python 实现混淆矩阵
混淆矩阵Confusion Matrix是一种在深度学习中常用的辅助工具可以让你直观地了解你的模型在哪一类样本里面表现得不是很好。
示例代码一如下 import seaborn as sns
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt# 使用 seaborn 风格设置
sns.set()# 创建混淆矩阵
C2 confusion_matrix([0, 1, 2, 0, 1, 2, 0, 2, 2, 0, 1, 1], [0, 1, 1, 2, 1, 0, 0, 2, 2, 0, 1, 1])# 创建子图
f, ax plt.subplots()# 打印混淆矩阵
print(C2)# 绘制热力图
sns.heatmap(C2, annotTrue, axax)# 设置标题和轴标签
ax.set_title(Confusion Matrix) # 标题
ax.set_xlabel(Predicted) # x轴
ax.set_ylabel(True) # y轴# 显示图像
plt.show()示例代码二如下 import matplotlib.pyplot as plt
import numpy as npdef plot_Matrix(cm, classes, titleNone, cmapplt.cm.Blues):plt.rc(font, familyTimes New Roman, size8) # 设置字体样式、大小# 按行进行归一化cm cm.astype(float) / cm.sum(axis1)[:, np.newaxis]print(Normalized confusion matrix)str_cm cm.astype(np.str).tolist()for row in str_cm:print(\t.join(row))# 占比1%以下的单元格设为0防止在最后的颜色中体现出来for i in range(cm.shape[0]):for j in range(cm.shape[1]):if int(cm[i, j] * 100 0.5) 0:cm[i, j] 0fig, ax plt.subplots()im ax.imshow(cm, interpolationnearest, cmapcmap)# ax.figure.colorbar(im, axax) # 侧边的颜色条带ax.set(xticksnp.arange(cm.shape[1]),yticksnp.arange(cm.shape[0]),xticklabelsclasses, yticklabelsclasses,titletitle,ylabelActual,xlabelPredicted)# 通过绘制格网模拟每个单元格的边框ax.set_xticks(np.arange(cm.shape[1] 1) - .5, minorTrue)ax.set_yticks(np.arange(cm.shape[0] 1) - .5, minorTrue)ax.grid(whichminor, colorgray, linestyle-, linewidth0.2)ax.tick_params(whichminor, bottomFalse, leftFalse)# 将x轴上的lables旋转45度plt.setp(ax.get_xticklabels(), rotation45, haright,rotation_modeanchor)# 标注百分比信息fmt dthresh cm.max() / 2.for i in range(cm.shape[0]):for j in range(cm.shape[1]):if int(cm[i, j] * 100 0.5) 0:ax.text(j, i, format(int(cm[i, j] * 100 0.5), fmt) %,hacenter, vacenter,colorwhite if cm[i, j] thresh else black)fig.tight_layout()plt.savefig(cm.jpg, dpi300)plt.show()# 构造一个混淆矩阵
cm np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
classes [class1, class2, class3]# 调用函数绘制混淆矩阵
plot_Matrix(cm, classes, titleConfusion Matrix)PR曲线 AP
Recall召回率查全率: R e c a l l T P T P F N Recall\frac{TP}{TPFN} RecallTPFNTP
含义TP除以第一列即预测为1实际为1的样本在所有真实为1类别中的占比。
Presession精准率查准率 P r e s e s s i o n T P T P F P Presession\frac{TP}{TPFP} PresessionTPFPTP
含义FP除以第一行即预测为1实际为1的样本在所有预测为1类别中的占比。
PR曲线
同理ROC曲线。在模型预测的时候我们输出的预测结果是一堆[0,1]之间的数值怎么把数值变成二分类设置一个阈值大于这个阈值的值分类为1小于这个阈值的值分类为0。ROC曲线就是我们从[0,1]设置一堆阈值每个阈值得到一个PresessionRecall对纵轴为Presession横轴为Recall把所有的PresessionRecall对对连起来就得到了PR曲线。 APPR曲线下的面积
跟TPR和FPR不一样的是在PR关系中是一个此消彼长的关系但往往我们希望二者都是越高越好所以PR曲线是右上凸效果越好也有例外有比如在风险场景当预测为1实际为0时需要赔付时大致会要求Recall接近100%可以损失Precision。所以除了特殊情况通常情况都会使用Precision-recall曲线来寻找分类器在Precision与Recall之间的权衡。
AP就是Precision-recall 曲线下面的面积通常来说一个越好的分类器AP值越高。
还有一个mAP的概念mAP是多个类别AP的平均值。这个mean的意思是对每个类的AP再求平均得到的就是mAP的值mAP的大小一定在[0,1]区间越大越好。该指标是目标检测算法中最重要的一个。
精准率和召回率是相互制约的如果想要精准率提高召回率则会下降如果要召回率提高精准率则会下降我们需要找到二者之间的一个平衡。
P-R曲线的生成方法根据学习器的预测结果对样本进行排序排在前面的是学习器认为最可能是正例的样本排在最后的是最不可能是正例的样本按此顺序逐个将样本作为正例预测则每次可以计算出当前的查全率、查准率以查全率为横轴、查准率为纵轴做图得到的查准率-查全率曲线即为P-R曲线。也就是说对每个样本预测其为正例的概率然后将所有样本按预测的概率进行排序然后依次将排序后的样本做为正例进行预测从而得到每次预测的查全率与查准率。这个依次将样本做为正例的过程实际上就是逐步降低样本为正例的概率的域值通过降低域值更多的样本会被预测为正例从而会提高查全率相对的查准率可能降低而随着后面负样本的增加查全率提高缓慢甚至没有提升精度降低会更快。 代码实现如下
import matplotlib.pyplot as plt
from sklearn.metrics import precision_recall_curve
import numpy as npplt.figure(P-R Curve)
plt.title(Precision/Recall Curve)
plt.xlabel(Recall)
plt.ylabel(Precision)#y_true为样本实际的类别y_scores为样本为正例的概率
y_true np.array([1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0])
y_scores np.array([0.9, 0.75, 0.86, 0.47, 0.55, 0.56, 0.74, 0.62, 0.5, 0.86, 0.8, 0.47, 0.44, 0.67, 0.43, 0.4, 0.52, 0.4, 0.35, 0.1])
precision, recall, thresholds precision_recall_curve(y_true, y_scores)plt.plot(recall,precision)
plt.show()ROC曲线 AUC
真阳率: T P R T P T P F N F P P TPR\frac{TP}{TPFN}\frac{FP}{P} TPRTPFNTPPFP
含义TP除以第一列即预测为1实际为1的样本在所有真实1类别中的占比。
假阳率 F P R F P F P T N F P N FPR\frac{FP}{FPTN}\frac{FP}{N} FPRFPTNFPNFP
含义FP除以第二列即预测为1实际为0的样本在所有真实0类别中的占比。
ROC曲线
在模型预测的时候我们输出的预测结果是一堆[0,1]之间的数值怎么把数值变成二分类设置一个阈值大于这个阈值的值分类为1小于这个阈值的值分类为0。ROC曲线就是我们从[0,1]设置一堆阈值每个阈值得到一个TPR,FPR对纵轴为TPR横轴为FPR把所有的TPR,FPR对连起来就得到了ROC曲线。 代码实现
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import precision_recall_curve, roc_curveplt.figure()
plt.title(PR Curve)
plt.xlabel(Recall)
plt.ylabel(Precision)
plt.grid()# 只是理解两种曲线的含义所以数据简单的构造
confidence_scores np.array([0.9, 0.46, 0.78, 0.37, 0.6, 0.4, 0.2, 0.16])
confidence_scores sorted(confidence_scores, reverseTrue) # 置信度从大到小排列
print(confidence_scores)data_labels np.array([1, 1, 0, 1, 0, 0, 1, 1]) # 置信度所对应的标签# 精确率召回率阈值
precision, recall, thresholds precision_recall_curve(data_labels, confidence_scores)
print(precision)
print(recall)
print(thresholds)
plt.plot(recall, precision)
plt.show()# 真正率假正率
fpr, tpr, thresholds roc_curve(data_labels, confidence_scores)
# print(fpr)
# print(tpr)
plt.figure()
plt.grid()
plt.title(Roc Curve)
plt.xlabel(FPR)
plt.ylabel(TPR)from sklearn.metrics import aucauc auc(fpr, tpr) # AUC计算
plt.plot(fpr, tpr, labelroc_curve(AUC%0.2f) % auc)
plt.legend()
plt.show()AUC(area under the curve)
1计算方法一
AUC即ROC曲线下的面积。曲线越靠近左上角意味着TPRFPR模型的整体表现也就越好。所以我们可以断言ROC曲线下的面积越大模型效果越好。
最坏的情况是总是有TPRFPR如下图表示对于不论真实类别是1还是0的样本分类器预测为1的概率是相等的。换句话说分类器对于正例和负例毫无区分能力。如果AUC小于0.5那么只要把预测类别取反便得到了一个AUC大于0.5的分类器。 2计算方法二
AUC还有一种解释就是任取一对正负样本正样本的预测值大于负样本的预测值的概率。 显然可以写出计算AUC伪代码为
1.统计所有正样本个数P负样本个数N
2.遍历所有正负样本对统计正样本预测值大于负样本预测值的样本总个数number
3. A U C n u m b e r / ( P ∗ N ) AUC number / (P * N) AUCnumber/(P∗N) 一些计算细节是当正负样本预测值刚好相等时该样本记为0.5个。
PS: 在实际代码实现过程中其实可以和第一种方法一样进一步优化可以先对正负样本排序利用dp的思想迭代计算个数可以将复杂度从 O ( N 2 ) O(N^2) O(N2)降低为 O ( N l o g N ) O(NlogN) O(NlogN)。
类别不平衡问题中如何选择PR与ROC
这里特指负样本数量远大于正样本时在这类问题中我们往往更关注正样本是否被正确分类即TP的值。PR曲线更适合度量类别不平衡问题中
因为在PR曲线中TPR和FPR的计算都会关注TPPR曲线对正样本更敏感。而ROC曲线正样本和负样本一视同仁在类别不平衡时ROC曲线往往会给出一个乐观的结果。
理解的动态图 https://zhuanlan.zhihu.com/p/92218196