应对多标签分类中的类别不平衡问题

10

我看到了一些关于多类别不平衡的问题。但是,我面临的是一个多标签问题,那么在这种情况下,你该如何处理呢?

我有大约300k个文本示例。正如标题中提到的那样,每个示例至少有一个标签,而仅有100个可能的唯一标签。通过利用命名空间,例如:

从:

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个标签组合。我想知道是否有其他人有任何建议。
编辑:我最终有机会测试了类不平衡,特别是对于vw。 vw处理不平衡非常糟糕,至少对于高维度,稀疏填充的文本特征而言。我尝试了从1:1到1:25的比率,性能在1:2比率处突然下降。

我可以完全摆脱“0”标签。而且这些标签二进制约简中的命名空间。 - richizy
你能找到你的问题的答案吗?看起来我们还没有一个确定的答案。 - GeorgeOfTheRF
@ML_Pro 查看我的回答:使用 --loss_function logistic - Zach
3个回答

7
任何线性模型,如果您强制将其用于二元分类问题的平方损失函数,它都无法很好地处理类别不平衡。想一想这个损失函数:如果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 

在vowpal wabbit中,针对二元分类问题,请使用--loss_function="logistic"--loss_function="hinge"。您可以使用汉明损失评估预测结果,但将结果与始终预测0的汉明损失进行比较可能更具信息量。


线性模型在不平衡分类中为什么比逻辑回归差?或者最小化平方损失比最小化交叉熵(最大化对数似然)更糟糕?坦白地说,我能想到的唯一原因是大多数模型在不平衡分类上表现不佳的原因是,它们试图最小化训练数据上的总损失,如果我们在大多数多数类示例上出错,损失可能很高,而如果在大多数少数类示例上出错,则产生的损失很小。 - avocado
2
@avocado 这取决于您从模型中想要什么。请注意原始问题中的引用:“我注意到所有示例都使用“0”标签进行预测...这是一种最小化损失的方式,我猜测。”我的观点只是最小化均方根误差会倾向于给出这个结果。如果您不想要这个结果,您需要使用另一个损失函数。 - Zach
@avocado 哈哈,没问题。如果你喜欢的话,你可以点赞我的评论 :-D - Zach

1
我猜你已经将问题简化为了100个二分类问题?这是在多标签设置中做事情的标准方式。
如果您的评估指标确实是汉明损失,那么您可能最好只为每个二元问题预测大多数。对于高度不平衡的问题,很难超越它。但在大多数情况下,您的评估指标本身是不同的。例如,您可能希望优化F1度量(微观或宏观)。在这种情况下,您可以尝试以某种方式平衡每个二进制问题的+ve和-ve样本。有几种方法可以做到这一点。
正如Slater所提到的,您可以尝试优化每个学习问题的AUC。在这种情况下,您将学习一个以实例为输入的实值函数。现在,您可以在不同的值处进行阈值处理并尝试性能。
实际上,即使对于您已经优化的普通最小二乘法,您也可以尝试'不同的'阈值处理。但是,此阈值至关重要,您必须通过交叉验证来选择它。

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

我不知道如何在VW中实现这一点。您需要自己解决。


1

一般来说,如果您想要解决训练数据中的类别不平衡问题,那么您需要更改为更适合的损失函数。特别是针对类别不平衡问题,您需要将损失函数更改为ROC曲线下面积。这个损失函数是专门设计用来解决这个问题的。

虽然有一个多标签版本,但如果您已经将其简化为二元分类,则应该可以直接使用。

这里有一篇wikipedia文章更详细地解释了这个概念。

这里是相关的sklearn文档,但由于我不确定发生在哪种语言中,可能会不太有帮助。


2
AUC并非专门为不平衡的数据集设计。它是关于推迟对精确度/召回率权衡的决策(直到某个领域专家告诉你假阳性与假阴性之间的成本为止)。如果你知道所需的精确度/召回率水平,就不需要使用AUC进行模型选择。处理不平衡数据集只需要监控两个指标,而不是一个精确度/召回率、敏感度/特异度等。将其总结为一个指标如AUC或F-score很容易误导你。所讨论的问题完全不同。 - iliasfl
3
实际上并不是这样。我可能有点过于简化了,但是auc作为一种度量标准是专门选择的,以排除随机猜测和类别不平衡的问题,当简单的准确性在这些方面失败时。当您使用具有严重不平衡的模型进行训练,并且正在优化准确性时,模型很快会收敛于仅选择一个类,就像问题中发生的那样。如果改用AUC作为评估指标而不是准确性,则此问题将消失。如果您还没有被说服,请考虑一下在随机猜测或全部猜测一个数字时会发生什么。 - Slater Victoroff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接