首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么liblinear不能预测多数类?

为什么liblinear不能预测多数类?
EN

Stack Overflow用户
提问于 2013-02-19 12:20:23
回答 1查看 695关注 0票数 1

大多数机器学习分类器在遇到没有以前见过的特征的实例时,会用训练数据中出现频率最高的类对示例进行分类。

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

代码语言:javascript
复制
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,即训练数据中最常见的类。

代码语言:javascript
复制
FeatureNode[] instance = new FeatureNode[] { new FeatureNode(3, 1) };
int prediction = Linear.predict(model, instance);
System.err.println(prediction);

但是,最后一行打印的是1。为什么会这样呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-19 23:39:35

我相信这就是命令行版本liblinear的"-B“(偏置)参数想要解决的问题。如果直接创建FeatureNode,则该参数不可用,但本质上等同于在每个FeatureNode[]的开头添加new FeatureNode(1, 1)。如果我遵循这种方法,并在训练和分类过程中添加额外的偏差特征,一切都会正常工作。代码如下所示:

代码语言:javascript
复制
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代码。下面是预测代码的样子:

代码语言:javascript
复制
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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14949781

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档