我应该在 VW 中使用哪些参数来执行二进制分类任务?例如,让我们使用 rcv1_small.dat .我thought最好使用逻辑损失函数(或铰链),使用 --oaa 2
毫无意义。 .然而,经验结果(在所有 4 个实验中报告的渐进式验证 0/1 损失)表明最佳组合是 --oaa 2
没有逻辑损失(即默认平方损失):
cd vowpal_wabbit/test/train-sets
cat rcv1_small.dat | vw --binary
# average loss = 0.0861
cat rcv1_small.dat | vw --binary --loss_function=logistic
# average loss = 0.0909
cat rcv1_small.dat | sed 's/^-1/2/' | vw --oaa 2
# average loss = 0.0857
cat rcv1_small.dat | sed 's/^-1/2/' | vw --oaa 2 --loss_function=logistic
# average loss = 0.0934
我的主要问题是:为什么
--oaa 2
不会给出与 --binary
完全相同的结果 (在上述设置中) ? 我的次要问题是:为什么优化逻辑损失不会改善 0/1 损失(与优化默认平方损失相比)?这是特定数据集的特定内容吗?
最佳答案
我在使用 --csoaa
时遇到过类似的事情.详情可查看here .我的猜测是,在 N 个类的多类问题的情况下(无论您将 2 指定为多个类),vw 实际上可以处理 N 个特征副本。当为每个可能的类预测/学习时,同一示例会获得不同的 ft_offset 值,并且此偏移量用于散列算法。因此,所有类都从同一数据集的行中获得“独立”的一组特征。当然特征值是相同的,但 vw 不保留值——只有特征权重。每个可能的类的权重是不同的。由于用于存储这些权重的 RAM 量是固定的 -b
(默认为 -b 18
) - 类越多,发生哈希冲突的机会就越大。您可以尝试增加-b
值并检查 --oaa 2
之间是否存在差异和 --binary
结果在减少。但我可能错了,因为我没有深入了解大众代码。
至于损失函数 - 您不能直接比较平方(默认)和逻辑损失函数的平均损失值。您应该从平方损失获得的结果中获得原始预测值,并在逻辑损失方面获得这些预测的损失。函数将是:log(1 + exp(-label * prediction)
其中 label 是先验已知的答案。在 vw 中实现的所有损失函数的此类函数 ( float getLoss(float prediction, float label)
) 可以在 loss_functions.cc 中找到。 .或者您可以使用 1.f / (1.f + exp(- prediction)
初步将原始预测值缩放到 [0..1]然后按照 kaggle.com 中所述计算对数损失:
double val = 1.f / (1.f + exp(- prediction); // y = f(x) -> [0, 1]
if (val < 1e-15) val = 1e-15;
if (val > (1.0 - 1e-15)) val = 1.0 - 1e-15;
float xx = (label < 0)?0:1; // label {-1,1} -> {0,1}
double loss = xx*log(val) + (1.0 - xx) * log(1.0 - val);
loss *= -1;
您还可以使用“/vowpal_wabbit/utl/logistic”脚本或
--link=logistic
将原始预测缩放到 [0..1]范围。两者都使用 1/(1+exp(-i))
.
关于vowpalwabbit - --oaa 2 和 --loss_function=logistic 在 Vowpal Wabbit 中的效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24674880/