gpt4 book ai didi

java - 为什么 liblinear 不预测多数类?

转载 作者:行者123 更新时间:2023-11-30 04:29:46 24 4
gpt4 key购买 nike

大多数机器学习分类器在遇到没有以前见过的特征的​​实例时,会将该示例分类为训练数据中最常见的类。

liblinear-java 的情况似乎并非如此我想知道为什么会这样。下面是一些示例代码,我在其中构造了一个示例问题,其中有两个特征,并且训练数据的 0 标签数量是 1 标签的 4 倍:

Problem problem = new Problem();
problem.l = 5;
problem.n = 2;
problem.x = new FeatureNode[][] {
new FeatureNode[] { new FeatureNode(1, 1) },
new FeatureNode[] { new FeatureNode(1, 1) },
new FeatureNode[] { new FeatureNode(1, 1) },
new FeatureNode[] { new FeatureNode(1, 1) },
new FeatureNode[] { new FeatureNode(2, 1) },
};
problem.y = new int[] {0, 0, 0, 0, 1};

Parameter parameter = new Parameter(SolverType.L2R_L2LOSS_SVC, 1.0, 0.01);
Model model = Linear.train(problem, parameter);

现在让我们在新功能 3 上测试一下,该功能不在训练数据中。由于经过训练的模型对特征 3 一无所知,因此我预计预测的类别将为 0,即训练数据中最常见的类别。

FeatureNode[] instance = new FeatureNode[] { new FeatureNode(3, 1) };
int prediction = Linear.predict(model, instance);
System.err.println(prediction);

最后一行打印出1。这是为什么?

最佳答案

我相信这就是 liblinear 命令行版本的“-B”(偏差)参数旨在解决的问题。如果您直接创建 FeatureNode,则该参数不可用,但它本质上与在每个 的开头添加一个 new FeatureNode(1, 1) 相同特征节点[]。如果我遵循这种方法,并在训练和分类期间添加额外的偏差特征,那么一切都会起作用。该代码如下所示:

Problem problem = new Problem();
problem.l = 5;
problem.n = 3;
problem.x = new FeatureNode[][] {
new FeatureNode[] { new FeatureNode(1, 1), new FeatureNode(2, 1) },
new FeatureNode[] { new FeatureNode(1, 1), new FeatureNode(2, 1) },
new FeatureNode[] { new FeatureNode(1, 1), new FeatureNode(2, 1) },
new FeatureNode[] { new FeatureNode(1, 1), new FeatureNode(2, 1) },
new FeatureNode[] { new FeatureNode(1, 1), new FeatureNode(3, 1) },
};
problem.y = new int[] {0, 0, 0, 0, 1};

Parameter parameter = new Parameter(SolverType.L2R_L2LOSS_SVC, 1.0, 0.01);
Model model = Linear.train(problem, parameter);
FeatureNode[] instance = new FeatureNode[] { new FeatureNode(1, 1), new FeatureNode(4, 1) };
int prediction = Linear.predict(model, instance);

为了弄清楚为什么偏置功能是必要的,我深入研究了 liblinear-java 代码。预测代码如下所示:

for (int i = 0; i < nr_w; i++)
dec_values[i] = 0;

for (FeatureNode lx : x) {
int idx = lx.index;
// the dimension of testing data may exceed that of training
if (idx <= n) {
for (int i = 0; i < nr_w; i++) {
dec_values[i] += w[(idx - 1) * nr_w + i] * lx.value;
}
}
}

因此,在训练过程中从未见过这些特征的情况下,我们只会得到一个全零的 dec_values(决策值)数组,这意味着所有类都具有相同的概率。因此,至关重要的是,在分类过程中看到的每个实例中至少存在一个在训练过程中看到的特征。

添加具有常量值(例如 1)的“偏差”功能可以解决此问题,允许模型学习默认权重以应用于任何新实例。在上面的代码中,模型学习了偏差特征的权重 0.0869565217391306,这意味着模型正确地学会了偏爱类 0 而不是类 1.

关于java - 为什么 liblinear 不预测多数类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14949781/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com