【问题标题】:Dealing with class imbalance in multi-label classification处理多标签分类中的类不平衡
【发布时间】:2013-12-26 00:20:52
【问题描述】:

我看到了一些关于多班级设置中班级不平衡的问题。但是,我有一个多标签问题,那么在这种情况下您将如何处理呢?

我有一组大约 30 万个文本示例。正如标题中提到的,每个示例至少有一个标签,并且只有 100 个可能的唯一标签。我通过利用命名空间将这个问题简化为 Vowpal Wabbit 的二进制分类,例如

发件人:

healthy fruit | bananas oranges jack fruit
evil monkey | bipedal organism family guy
...  

收件人:

1 |healthy bananas oranges jack fruit
1 |fruit bananas oranges jack fruit
0 |evil bananas oranges jack fruit
0 |monkey bananas oranges jack fruit
0 |healthy bipedal organism family guy
0 |fruit bipedal organism family guy
1 |evil bipedal organism family guy
1 |monkey bipedal organism family guy
...  

我使用的是 VW 提供的默认选项(我认为是在线 SGD,带有平方损失函数)。我使用平方损失,因为它非常类似于汉明损失。

训练结束后,在同一个训练集上进行测试时,我注意到所有示例都是用“0”标签预测的...我猜这是最小化损失的一种方法。在这一点上,我不知道该怎么办。我正在考虑使用成本敏感的一对一分类来尝试平衡类,但是将多标签减少到多类是不可行的,因为存在 2^100 个标签组合。我想知道是否其他人有任何建议。

编辑:我终于有机会测试类不平衡,特别是vwvw 处理不平衡非常糟糕,至少对于高维、稀疏填充的文本特征。我尝试了从 1:1 到 1:25 的比例,但在 1:2 的比例下性能会突然下降。

【问题讨论】:

  • 我可以完全摆脱0 标签。并且标签二进制归约中的命名空间。
  • 您找到问题的答案了吗?看起来我们还没有一个可靠的答案。
  • @ML_Pro See my answer:使用--loss_function logistic

标签: machine-learning classification text-classification vowpalwabbit


【解决方案1】:

一般而言,如果您要考虑训练数据中的类别不平衡,则意味着您必须更改为更适合的损失函数。特别是对于类别不平衡,您希望将损失函数更改为 ROC 曲线下的区域。专为解决此问题而设计。

有一个多标签版本,但如果您已经将其简化为二进制分类,它应该可以开箱即用。

这里有一个wikipedia article 更全面地解释了这个概念。

这里是相关的sklearn documentation,它可能不太有用,因为我不确定这是什么语言。

【讨论】:

  • AUC 不是“专门”为不平衡数据集设计的。这是关于推迟关于精确/召回权衡的决定(直到某些领域专家告诉您误报与误报之间的成本是多少)。如果您知道所需的 Precision/Recall 级别,则不需要 AUC 来选择模型。拥有不平衡的数据集只需要监控两个量,而不是一个精度/召回、灵敏度/特异性等。总结为 AUC 或 F-score 等一个量很容易误导您。所讨论的问题完全不同。
  • @iliasfl 事实上不是。我可能有点过于简单化了,但是当简单的准确性在这些方面失败时,专门选择 auc 作为度量来根除随机猜测和类别不平衡的问题。当您训练一个严重不平衡的模型并针对准确性进行优化时,模型会很快收敛于只选择一个类,就像问题中发生的那样。相反,如果使用 AUC 作为评估指标而不是准确性,这个问题就会消失。如果您不相信,请考虑一下当您随机猜测或猜测一个数字时会发生什么。
【解决方案2】:

我认为您已将问题简化为 100 个二进制分类问题?这将是在多标签设置中做事的标准方式。

如果您的评估指标确实是汉明损失,那么您实际上最好只预测每个二元问题的大多数。对于高度不平衡的问题,很难击败它。但在大多数情况下,您的评估指标本身是不同的。例如,您可能想要优化 F1 度量(微观或宏观)。在这种情况下,您可以尝试以某种方式平衡每个二进制问题的 +ve 和 -ve 样本。有几种方法可以做到这一点。

正如 Slater 所说,您可以尝试针对每个学习问题优化 AUC。在这种情况下,您将学习一个以实例为输入的实值函数。现在,您可以将其阈值设置为不同的值并尝试性能,而不是默认值(通常为 0)。

事实上,您甚至可以尝试对已优化的正常最小二乘法的“不同”阈值。这个阈值很重要,您必须通过交叉验证来选择它。

此外,您不能更改阈值,但可以更改不同学习问题中示例的“权重”。例如,如果您发现“健康”标签出现在 1k 个样本中,而没有出现在 29k 个样本中,只需对带有“健康”标签的示例使用 29 的权重,对于没有标签的示例使用 1 的权重。

我不知道你在大众汽车是怎么做到的。你必须弄清楚。

【讨论】:

    【解决方案3】:

    任何线性模型如果你强制它使用平方损失来解决二元分类问题,都会“非常糟糕”地处理类不平衡。想想损失函数:如果 99% 的观测值为零,那么在所有情况下预测为 0 的平方误差为 0.01。 Vowpal Wabbit 不能变魔术:如果你要求它最小化平方误差损失,它确实会最小化平方误差损失,就像任何其他回归程序一样。

    以下是 R 中线性回归模型的相同“问题”的演示:

    set.seed(42)
    rows <- 10000
    cols <- 100
    x <- matrix(sample(0:1, rows*cols, replace=TRUE), nrow=rows)
    y <- x %*% runif(cols) + runif(rows)
    y <- ifelse(y<quantile(y, 0.99), 0, 1)
    lin_mod <- glm(y~., data.frame(y, x), family='gaussian') #Linear model
    log_mod <- glm(factor(y)~., data.frame(y, x), family='binomial') #Logistic model
    

    比较线性模型与逻辑模型的预测表明,线性模型总是预测 0,而逻辑模型预测 0 和 1 的正确组合:

    > table(ifelse(predict(lin_mod, type='response')>0.50, 1, 0))
    
        0 
    10000 
    > table(ifelse(predict(log_mod, type='response')>0.50, 1, 0))
    
       0    1 
    9900  100 
    

    使用--loss_function="logistic"--loss_function="hinge" 解决vowpal wabbit 中的二元分类问题。您可以使用汉明损失在事后评估您的预测,但将您的结果与始终预测为 0 的汉明损失进行比较可能会提供更多信息。

    【讨论】:

    • 线性模型在不平衡分类中比逻辑模型更差的任何特殊原因?或者最小化平方损失比最小化交叉熵(最大化对数似然)更糟糕?坦率地说,我唯一能想到的为什么大多数模型在不平衡分类上表现不佳的原因是,它们试图最小化训练数据的总损失,如果我们在大多数类示例上出错,损失可能很高,而如果在大多数少数类示例上出现错误,则所产生的损失增量可以忽略不计。
    • @avocado 这取决于你想从模型中得到什么。请注意原始问题中的引用“我注意到所有示例都是用'0'标签预测的......我猜这是最小化损失的一种方法”。我的观点很简单,最小化 rmse 往往会产生这个结果。如果你不想这样,你需要使用另一个损失函数。
    • @avocado 哈哈,没问题。如果你喜欢,可以 +1 我的评论:-D
    猜你喜欢
    • 1970-01-01
    • 2020-09-04
    • 2017-11-03
    • 2021-04-19
    • 2020-02-01
    • 2021-06-28
    • 1970-01-01
    • 2023-03-17
    • 2017-11-01
    相关资源
    最近更新 更多