如何确定多类分类器的质量

机器算法验证 机器学习 分类 多级
2022-01-27 14:50:40

给定

  • 带有实例的数据集xi和...一起N每个实例所在的类xi完全属于一类yi
  • 多类分类器

经过训练和测试后,我基本上有一个真正的班级表yi预测的类ai对于每个实例xi在测试集中。因此,对于每个实例,我都有一个匹配项(yi=ai) 或错过 (yiai)。

如何评价比赛的质量?问题是一些类可以有很多成员,即很多实例属于它。显然,如果 50% 的所有数据点属于一个类,而我的最终分类器总体正确率为 50%,那么我将一无所获。我也可以制作一个简单的分类器,无论输入是什么,它都会输出最大的类。

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

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

3个回答

与二元分类一样,您可以使用经验错误率来估计分类器的质量。g是一个分类器,并且xiyi分别是您的数据库及其类中的示例。

err(g)=1nin1g(xi)yi
正如你所说,当类不平衡时,基线不是 50%,而是更大类的比例。您可以在每个类上添加权重以平衡错误。Wy成为班级的重量y. 设置权重,使得1Wy1nin1yi=y并定义加权经验误差
errW(g)=1ninWyi1g(xi)yi

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

ROC 曲线可以针对您的多类问题进行扩展。我建议你阅读这个线程的答案。

为了评估多路文本分类系统,我使用微观和宏观平均 F1(F-measure)。F-measure 本质上是精度和召回率的加权组合。对于二元分类,微观和宏观方法是相同的,但对于多路情况,我认为它们可能会对您有所帮助。您可以将 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

在哪里TP是真阳性,FP是假阳性,FN是假阴性,并且C是类。

# 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