如何确定多分类器的质量


30

给定

  • 具有实例和类的数据集,其中每个实例恰好属于一个类xiNxiyi
  • 多类分类器

经过训练和测试之后,我基本上有了一张表,其中包含测试集中每个实例的真实类和预测类。因此,对于每个实例,我都有一个匹配项()或一个未命中()。yiaixiyi=aiyiai

如何评估比赛的质量?问题是某些类可以具有许多成员,即,许多实例属于该类。显然,如果所有数据点的50%属于一个类,而我的最终分类器总体上是正确的50%,那么我什么也得不到。我也可以做一个琐碎的分类器,无论输入什么,它都能输出最大的分类。

是否有一种标准方法根据每个类的匹配和匹配的已知测试集结果来估计分类器的质量?区分每个特定类别的匹配率也许甚至很重要?

我能想到的最简单的方法是排除最大类的正确匹配。还有什么?


我不确定我是否正确理解了这个问题。您知道混淆矩阵和派生度量吗?这是您问题的答案吗?还是您指的是更复杂的东西?
steffen 2012年

我认为这是引起我困惑的根源:在第一段中,您声明.. yi是真实的类,而...:您的意思是实例可以属于/具有多个类?还是每个属于/只有一个类?你能澄清一下吗?xixi
steffen 2012年

@steffen:我看过混淆矩阵。在我的特殊情况下,我有4个班级。因此,我不确定可以使用哪些派生的度量方法,并且是否有意义。每个仅属于一个类。但是,总共有两个以上的可能的类。xii[1,,N]
Gerenuk

@steffen这些派生的度量主要适用于二进制分类,而此问题明确地涉及两个以上的类。然后,这需要对术语如“真正肯定”的理解有所修改。
Michael McGowan 2012年

@MichaelMcGowan我已要求OP进行澄清,然后执行编辑以明确反映多类问题,这在编辑(IMHO)之前并不明显。
steffen 2012年

Answers:


16

像二进制分类一样,您可以使用经验错误率来估计分类器的质量。令为分类器,和分别为数据库及其类的示例。 如您所说,当类不平衡时,基线不会50%,但占较大阶层的比例。您可以在每个类上增加权重以平衡错误。令为类的权重。设置权重,使并定义加权经验误差gxiyi

err(g)=1nin1g(xi)yi
Wyy1Wy1nin1yi=y
errW(g)=1ninWyi1g(xi)yi

正如Steffen所说,混淆矩阵可能是估计分类器质量的好方法。在二进制情况下,您可以从此矩阵中得出一些度量值,例如敏感性和特异性,从而估计分类器检测特定类别的能力。分类器的错误来源可能是特定的方式。例如,分类器在预测1时可能会过分自信,而在预测0时却永远不会说错。可以对许多分类器进行参数化控制,以控制此比率(误报与误报),然后您会对分类器的质量感兴趣分类器的整个家族,而不仅仅是一个。由此您可以绘制ROC曲线,并测量ROC曲线下方的面积可为您提供这些分类器的质量。

可针对您的多类问题扩展ROC曲线。我建议您阅读此主题的答案。


1
是否有必要将加权的经验误差除以类别数,使其与经验误差在同一范围内?否则,它将更大……
PhilippPro

17

为了评估多方向文本分类系统,我使用了微观和宏观平均F1(F度量)。F度量本质上是精度和召回率的加权组合。对于二进制分类,微观和宏观方法是相同的,但是对于多路情况,我认为它们可能会帮助您。您可以将Micro F1视为精确度和召回权的加权组合,它赋予每个文档相同的权重,而Macro F1赋予每个类相同的权重。对于每一个,F-measure方程都是相同的,但是您计算精度和调用方式有所不同:

F=(β2+1)PRβ2P+R,

其中通常设置为1。然后,β

Pmicro=i=1|C|TPii=1|C|TPi+FPi,Rmicro=i=1|C|TPii=1|C|TPi+FNi

Pmacro=1|C|i=1|C|TPiTPi+FPi,Rmacro=1|C|i=1|C|TPiTPi+FNi

其中为“真正”,为“假正”,为“假负”,为类。TPFPFNC


1
# Function in R, using precision, recall and F statistics

check.model.accuracy <- function(predicted.class, actual.class){

  result.tbl <- as.data.frame(table(predicted.class,actual.class ) ) 

  result.tbl$Var1 <- as.character(result.tbl$predicted.class)
  result.tbl$Var2 <- as.character(result.tbl$actual.class)

  colnames(result.tbl)[1:2] <- c("Pred","Act")

  cntr <- 0  
  for (pred.class in unique(result.tbl$Pred) ){
    cntr <- cntr+ 1
    tp <- sum(result.tbl[result.tbl$Pred==pred.class & result.tbl$Act==pred.class, "Freq"])
    tp.fp <- sum(result.tbl[result.tbl$Pred == pred.class , "Freq" ])
    tp.fn <- sum(result.tbl[result.tbl$Act == pred.class , "Freq" ])
    presi <- tp/tp.fp 
    rec <- tp/tp.fn
    F.score <- 2*presi*rec/(presi+rec)
    if (cntr == 1 ) F.score.row <- cbind(pred.class, presi,rec,F.score)
    if (cntr > 1 ) F.score.row <- rbind(F.score.row,cbind(pred.class,presi,rec,F.score))
  }

  F.score.row <- as.data.frame(F.score.row) 
  return(F.score.row)
}

check.model.accuracy(predicted.df,actual.df) 
# For multiclass, average across all classes 

5
您可以添加一些文字来说明吗?
gung-恢复莫妮卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.