1

ほとんどの機械学習分類器は、以前に見られた特徴を持たないインスタンスに遭遇した場合、トレーニング データで最も頻繁に見られたクラスで例を分類します。

これはliblinear-javaには当てはまらないようで、なぜそうなのか疑問に思っています。2 つの機能があり、トレーニング データにラベルの 4 倍の0ラベルがあるサンプル問題を作成するサンプル コードを次に示します1

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では、トレーニング データに含まれていない新しい機能 でこれをテストしてみましょう。訓練されたモデルは feature について何も知らないので3、予測されたクラス0は訓練データで最も一般的なクラスであると予想していました。

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

1ただし、最後の行は出力されます。何故ですか?

4

1 に答える 1

2

これが、liblinearのコマンドラインバージョンに対する「-B」(バイアス)引数が修正することを目的としているものだと思います。sを直接作成する場合、この引数は使用できませんが、基本的には、すべてのの先頭にFeatureNodeaを追加するのと同じです。このアプローチに従い、トレーニング中と分類中の両方でバイアス機能を追加すると、すべてが機能します。そのコードは次のようになります。new FeatureNode(1, 1)FeatureNode[]

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つの機能が、分類中に見られるすべてのインスタンスに存在することが重要です。

定数値(例1)で「バイアス」機能を追加すると、この問題が解決され、モデルがデフォルトの重みを学習して新しいインスタンスに適用できるようになります。上記のコードでは、モデルはバイアス機能の重みを学習します。これは、モデルがクラスよりも0.0869565217391306クラスを優先することを正しく学習したことを意味します。01

于 2013-02-19T15:39:35.060 に答える