在二分类问题中,一般假设正负类别相对均衡,然而实际应用中类别不平衡的问题,如100, 1000, 10000倍的数据偏斜是很是常见的,好比疾病检测中未患病的人数远超患病的人数,产品质量检测中合格产品数量远超不合格产品等。在检测信用卡欺诈问题中,一样正例的数目稀少,并且正例的数量会随着时间和地点的改变而不断变化,分类器要想在不断变化的正负样本中达到好的检测效果是很是困难的。html
因为类别不平衡问题的特性使然,通常常使用于评估分类器性能的准确率和错误率可能就再也不适用了。由于在类别不平衡问题中咱们主要关心数目少的那一类可否被正确分类,而若是分类器将全部样例都划分为数目多的那一类,就能轻松达到很高的准确率,但实际上该分类器并无任何效果。
因此在这种时候学习的前提每每是采用不一样的评估指标。学习机器学习的过程当中总难免碰到各类评估指标,刚开始很容易被五花八门的术语绕晕了,因此类别不平衡问题的第一篇先对这些指标进行梳理。毕竟评估指标不明确的话,后面模型的效果好坏也就无从谈起。python
在二分类问题中,通常将数目少的类别视为正例,数目多的类别视为负例,下面先用matplotlib画张混淆矩阵图来直观地感觉一下:
机器学习
plt.figure(figsize=(10,6)) plt.text(0.5,2.25,'True Positive (TP)',size=20,horizontalalignment="center",verticalalignment="center") plt.text(1.5,2.4,'False Positive (FP)',size=20,horizontalalignment="center",verticalalignment="center") plt.text(0.5,0.9,'False Negative (FN)',size=20,horizontalalignment="center",verticalalignment="center") plt.text(1.5,0.75,'True Negative (TN)',size=20,horizontalalignment="center",verticalalignment="center") plt.text(1,3.4,'$True\ Class$',size=25,horizontalalignment="center") plt.text(-0.5,1.5,'$Predicted$\n$Class$',size=23,verticalalignment="center") plt.text(0.5,3.1,'$P$',size=20,horizontalalignment="center") plt.text(1.5,3.1,'$N$',size=20,horizontalalignment="center") plt.text(-0.1,2.25,'$Y$',size=20,va="center") plt.text(-0.1,0.75,'$N$',size=20,va="center") plt.text(2.4,2.25,r'Precision = $\frac{TP}{Y}$ = $\frac{TP}{TP+FP}$ ',size=18,ha="center",va="center") plt.text(0.5,-0.3,'Recall, Sensitivity, TPR = ',size=16,ha="center",va="center") plt.text(0.5,-0.6,'$\\frac{TP}{P}$ = $\\frac{TP}{TP+FN}$',size=18,ha="center",va="center") plt.text(1.5,-0.3,'FPR = $\\frac{FP}{N}$ = $\\frac{FP}{FP+TN}$',size=16,ha="center",va="center") plt.text(1.5,-0.7,'TNR, Specificity = $\\frac{TN}{N}$ = $\\frac{TN}{FP+TN}$',size=16,ha="center",va="center") plt.text(1.5,2.1,'Type I Error',size=20,horizontalalignment="center",verticalalignment="center") plt.text(0.5,0.6,'Type II Error',size=20,horizontalalignment="center",verticalalignment="center") plt.xticks([]) plt.yticks([]) plt.plot([1,1],[0,3],'k--') plt.plot([0,3],[1.5,1.5],'k:') plt.axis([0,2,0,3]) plt.fill_between([0,1],[1.5,1.5],[3,3],color='#98FB98') plt.fill_between([0,1],[0,0],[1.5,1.5],color='#EEA9B8') plt.fill_between([1,2],[0,0],[1.5,1.5],color='#9AFF9A') plt.fill_between([1,2],[1.5,1.5],[3,3],color='#EEB4B4')
True Positive (真正例,TP):实际为正例,预测为正例。性能
False Negative (假负例,FN):实际为正例,预测为负例。学习
True Negative (真负例,TN):实际为负例,预测为负例。搜索引擎
False Positive (假正例,FP):实际为负例,预测为正例。
Precision (查准率) = \(\frac{TP}{TP+FP}\) ,Precision衡量的是全部被预测为正例的样本中有多少是真正例。但Precision并无表现有多少正例是被错判为了负例(即FN),举个极端的例子,分类器只将一个样本判为正例,其余全部都判为负例,这种状况下Precision为100%,但其实遗漏了不少正例,因此Precision常和下面的Recall (TPR) 相结合。
True Positive Rate (TPR,真正例率) = \(\frac {TP}{TP+FN}\) ,又称__Recall__(查全率),Sensitivity(灵敏性)。Recall (TPR)衡量的是全部的正例中有多少是被正确分类了,也能够看做是为了不假负例(FN)的发生,由于TPR高意味着FN低。Recall的问题和Precision正相反,没有表现出有多少负例被错判为正例(即FP),若将全部样本全划为正例,则Recall为100%,但这样也没多大用。
False Negative Rate (FNR,假负例率) = \(\frac{FN}{TP+FN}\) = \(1 - TPR\),由混淆矩阵能够看出该指标的着眼点在于正例,意为有多少正例被错判成了负例。
True Negative Rate (TNR,真负例率) = \(\frac{TN}{TN+FP}\) ,又称Specificity(特异性)。Specificity衡量的是全部的负例中有多少是被正确分类了,因为类别不平衡问题中一般关注正例可否正确被识别,Specificity高则FP低,意味着不多将负例错判为正例,即该分类器对正例的判别具备“特异性”,在预测为正例的样本中不多有负例混入。
False Positive Rate (FPR,假正例率) = \(\frac{FP}{TN+FP}\) = \(1 - TNR\), 由混淆矩阵能够看出该指标的着眼点在于负例,意为有多少负例被错判成了正例。在ROC曲线中分别以TPR和FPR做为纵、横轴做图,显示出一种正例与负例之间的“博弈”,在下篇文章中详解。
F1 score = \[\frac{2}{\frac{1}{recall}+\frac{1}{precision}} = \frac{2 × precision × recall}{precision + recall}\],是一个综合指标,为Precision和Recall的调和平均 (harmonic mean),数值上通常接近于两者中的较小值,所以若是F1 score比较高的话,意味着Precision和Recall都较高。
FP和FN还有个还有个与之相关的概念,那就是统计假设检验中的第一类错误 (Type I error)和第二类错误 (Type II error) 。因为咱们比较关心正例,因此将负例视为零假设,正例视为备选假设,则第一类错误为错误地拒绝零假设 (负例),选择备选假设,则为FP;第二类错误为错误地接受零假设,则为FN。
spa
上面介绍的这些指标都没有考虑检索结果的前后顺序,而像搜索问题中咱们一般但愿第一个结果是与查询最相关的,第二个则是次相关的,以此类推,于是有时候不只要预测准确,对于相关性的顺序也很是看重。因此最后介绍两个普遍应用的排序指标。code
Mean Average Precision (MAP,平均准确率均值),对于单个信息需求,返回结果中在每篇相关文档上 Precision 的平均值被称为 Average Precision (AP),而后对全部查询取平均获得 MAP。
\[ \text{AP} = \frac{\sum\limits_{k=1}^n P(k) \times rel(k)}{M} \\[3ex] \text{MAP} = \sum\limits_{q=1}^Q \frac{\text{AP}_q}{Q} \]
其中 \(P(k)\) 为前 \(k\) 个结果的 Precision,又可写为\(\text{P}@\text{k}\)。 \(rel(k)\) 表示第 \(k\) 个结果是否为相关文档,相关为1不相关为0,\(M\) 表示全部相关文档的数量,\(n\) 表示全部文档数量。若是只关心前 \(K\) 个查询的状况,则是下式:
\[ \text{AP}\,@\,K = \frac{\sum\limits_{k=1}^{K} P(k) \times rel(k)}{M_K} \\[3ex] \text{MAP}\,@\,K = \sum\limits_{q=1}^Q \frac{\text{AP}_q @ K}{Q} \]
这里的 \(M_K\) 为前 \(K\) 个结果中相关文档的数量。orm
对于单个信息需求来讲,Average Precision 是 PR 曲线下面积的近似值,所以 MAP 可粗略地认为是某个查询集合对应的多条 PR 曲线下面积的平均值。htm
Normalized Discounted Cumulative Gain (NDCG,归一化折扣累计增益) 。若是说 MAP 是基于 0/1 二值描述相关性,那么 NDCG 则是可将相关性分为多个等级的指标。
对于信息检索和推荐之类的问题,每个返回的结果都被赋予一个相关性分数 \(\text{rel}\),则 NDCG 中的 CG 表示前 \(k\) 个结果的分数之和,即累计增益 :
\[ \text{CG}_k = \sum\limits_{i=1}^k \text{rel}_i \]
CG 没有考虑推荐的次序,因此在此基础上引入对结果顺序的考虑,即相关性高的结果若排在后面则会受更多的惩罚,因而就有了 DCG (discounted CG),折扣累积增益。公式以下:
\[ \text{DCG}_k=\sum_{i=1}^k \frac{2^{\text{rel}_i}-1}{\log_2(i+1)}. \]
\(i\) 表示一个结果在结果集中的顺序,若是该结果 \(\text{rel}\) 很高,但排在后面,意味着分母 \(\log_2(i+1)\) 会变大,则相应的整体 DCG 会变小 (注意这里的 \(\text{log}\) 是以 \(2\) 为底的)。
对于不一样的查询,每每会返回不一样的结果集,而不一样结果集之间由于大小不一样难以直接用 DCG 进行比较,因此须要进行归一化,这其实和机器学习中不一样特征因量纲不一样要进行归一化差很少意思。这个归一化后的指标就是 NDCG :
\[ \text{NDCG}_k=\frac{\text{DCG}_k}{\text{IDCG}_k} \]
其中 IDCG 表示 Ideal DCG, 指某个查询所能返回的最好结果集,IDCG 的值也是结果集中最大的。将全部结果按相关性大小排序,计算出的 DCG 即为前 \(k\) 个结果的 IDCG:
\[ \text{IDCG}_k=\sum_{i=1}^{|REL|} \frac{2^{\text{rel}_i}-1}{\log_2(i+1)}. \]
其中 \(|REL|\) 表示按相关性顺序排列的结果集。所以 DCG 的值介于 (0, IDCG] ,故 NDCG 的值介于(0,1],这样就起到了归一化的效果。不一样查询或用户的 NDCG 平均起来能够用以评估一个搜索引擎或推荐系统的总体效果。
NDCG 的缺点是须要预先指定每个返回结果的相关性,这个超参数须要人为指定。
/