使用概率而非原始类(因子)进行分类训练

数据挖掘 分类 研究
2021-10-14 14:15:08

我有一个问题,而不是有类,即 0 和 1 的向量,我有一个观察属于一个类的概率。

具有 0.1、0.95、0.2、0.3 等的向量。

显而易见的方法是使用回归,并且效果相对较好,但我对一种方法感兴趣,该方法可以训练观察属于某个类的这些概率并对它们进行分类。

还尝试了多项分类方法。这种方法的问题在于它没有考虑类别(因素)的顺序,这在某些情况下会导致观察的最高预测类别位于一端(假设为 0.2)而第二个位于另一端 (0.8)。此外,类越多,这种方法的可扩展性就越低。相反,如果类别太少,预测中的差距就会开始出现。

所以我的问题是:是否有一种分类算法支持训练概率而不仅仅是因子(0 和 1)?或者,是否有另一种既不是回归也不是分类的方法可以解决这个问题?

4个回答

贝塔回归

您可以使用 beta 回归。我对这种类型的回归没有实际经验。但是,这可能是您的任务的正确方法。据我了解,选择链接功能是为了限制是的^[0,1].

这是一个R 实现,文档说:

使用具有均值(取决于协变量上的链接函数)和精度参数(称为 phi)的参数化,通过最大似然拟合比率和比例的 beta 回归模型。

例子:

library("betareg")
data("GasolineYield", package = "betareg")
summary(GasolineYield$yield)

Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
0.0280  0.1165  0.1780  0.1966  0.2705  0.4570 

br = betareg(yield ~ batch + temp, data = GasolineYield)
preds = predict(br, newdata=GasolineYield)
summary(preds)

Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
0.04571 0.10309 0.16364 0.19655 0.26429 0.50792 

序数数据的回归模型

序数逻辑回归可以用于这个问题,因为类是有序的,多项分类不考虑类的顺序。在实践中,该算法不能扩展到许多类或许多观察,因为它的计算成本很高。

这是使用R 中的序数包将累积链接模型 (CLM) (例如比例赔率模型)拟合到数据的示例

require("ordinal")
fm1 <- clm(rating ~ contact + temp, data=wine)
summary(fm1)

formula: rating ~ contact + temp
data:    wine

link  threshold nobs logLik AIC    niter max.grad cond.H 
logit flexible  72   -86.49 184.98 6(0)  4.01e-12 2.7e+01

Coefficients:
       Estimate Std. Error z value Pr(>|z|)    
contactyes   1.5278     0.4766   3.205  0.00135 ** 
tempwarm     2.5031     0.5287   4.735 2.19e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Threshold coefficients:
    Estimate Std. Error z value
1|2  -1.3444     0.5171  -2.600
2|3   1.2508     0.4379   2.857
3|4   3.4669     0.5978   5.800
4|5   5.0064     0.7309   6.850

带有逻辑链接函数的回归

正如 Ben Reiniger 在问题评论中所建议的那样,另一种选择是在回归模型中简单地使用 Logistic Link 函数。

一个例子是使用 xgboost 和 reg:logistic 作为目标函数。但是,许多库可能不支持这种行为,因为它们需要目标是 1 或 0。

您所描述的只是交叉输入损失(也称为相对熵或 kullback-leibler 散度)。如果你的目标概率是 one-hot,你会得到最常见的 NLL 形式,但它实际上是试图匹配概率分布的损失。您的问题的简单解决方案将是一个线性层,然后是 softmax,然后是 torch.nn.KLDivLoss 或您喜欢的框架中的等价物。

从未尝试过,但我认为它会起作用:假设您正在使用神经网络。继续使用您的正常 y 值(1、0 等),但请确保将每个分类的相应概率保存在内存中(它们都应大于 1/类数)。然后,一旦算法计算出样本的损失,将损失乘以该样本的概率,确保在任何反向传播之前执行此操作。我认为你必须在相当低的水平上做到这一点。Tensorflow 应该能够让你到达那里,尽管我不太确定像 Keras 这样的东西是否会。

您要解决的问题到底是什么?您是否尝试将概率映射到类?如果是这样,为什么不将观察结果分配给概率最高的类呢?

如果您出于某种原因真的想使用分类方法,您是否考虑过提升树?

这种方法有几个优点:

  • 无需标准化输入
  • 在将概率输入模型之前无需校准概率
  • 该方法对输入特征之间的相关性具有鲁棒性

根据您选择的语言,有可用的开源库。我知道这听起来很简单,但根据您的问题,这似乎是可以快速满足您需求的最简单的解决方案。