概要

LIBLINEARにはJava版が存在するらしい。試しに基本的なとこだけ使ってみた。

普通のC++版のLIBLINEARの説明はこっちを参照。

@CretedDate 2012/06/17
@Env LIBLINEAR1.8

導入

ダウンロードは公式サイトから。

jar1個で動き、依存ライブラリはなし。Mavenのセントラルにも置いてある。jarファイルは51KBと超軽量。BSDライセンス。

とても使い勝手が良さそう。

JavaDocはこちら

train

LIBLINEARはtrainで学習して、predictで結果予測を出力する。

とりあえずtrainしてモデルを出力してみる。ファイルはC++版を落とした時に付いてくるサンプル、heart_scaleを利用。

heart_scaleは下記のような行が記述された270行のファイル。1〜13までの要素に対してそれぞれ値が入っており、最初の列に+1/-1という評価が入れられている。これを使って学習することで、別の1〜13までの要素を持った値に対して、+1/-1を判別できるようになる。

+1 1:0.708333 2:1 3:1 4:-0.320755 5:-0.105023 6:-1 7:1 8:-0.419847 9:-1 10:-0.225806 12:1 13:-1
-1 1:0.583333 2:-1 3:0.333333 4:-0.603774 5:1 6:-1 7:1 8:0.358779 9:-1 10:-0.483871 12:-1 13:1
+1 1:0.166667 2:1 3:-0.333333 4:-0.433962 5:-0.383562 6:-1 7:-1 8:0.0687023 9:-1 10:-0.903226 11:-1 12:-1 13:1
-1 1:0.458333 2:1 3:1 4:-0.358491 5:-0.374429 6:-1 7:-1 8:-0.480916 9:1 10:-0.935484 12:-0.333333 13:1
-1 1:0.875 2:-1 3:-0.333333 4:-0.509434 5:-0.347032 6:-1 7:1 8:-0.236641 9:1 10:-0.935484 11:-1 12:-0.333333 13:-1

Parameterという利用するアルゴリズムとかを指定するクラスと、Problemというtrainする情報を保持するクラスを初期化し、Linear.trainすればいいらしい。

import java.io.File;

import de.bwaldvogel.liblinear.Linear;
import de.bwaldvogel.liblinear.Model;
import de.bwaldvogel.liblinear.Parameter;
import de.bwaldvogel.liblinear.Problem;
import de.bwaldvogel.liblinear.SolverType;

public class TrainSample {

    public static void main(String[] args) throws Exception {

        // ParameterとProblemを用意
        Parameter param = new Parameter(SolverType.L2R_L2LOSS_SVC_DUAL, 1, Double.POSITIVE_INFINITY);
        Problem prob = Problem.readFromFile(new File("heart_scale"), -1);

        // trainを実行
        Model model = Linear.train(prob, param);

        // 結果をファイルに出力
        model.save(new File("heart_scale.model"));
    }
}

これでModelファイルが生成される。

predict

次に生成したModelを使ってpredict、つまり値から結果を予測する処理を行なってみる。

FeatureNode(idxとvalueのペアを入れておく)の配列を作り、その配列に対してLinear.predictすると、heart_scaleの最初の列にいた+1/-1のどちらなのかが予測できるようになる。

import java.io.File;

import de.bwaldvogel.liblinear.FeatureNode;
import de.bwaldvogel.liblinear.Linear;
import de.bwaldvogel.liblinear.Model;

public class PredictSample {

    public static void main(String[] args) throws Exception {

        // ファイルからmodelを読み込む
        Model model = Model.load(new File("heart_scale.model"));

        // 判定したいデータを適当にでっちあげる
        // FeatureNodeのindexは1オリジン、すべて指定しなくても動く
        FeatureNode[] features = new FeatureNode[4];
        features[0] = new FeatureNode(1, 1.0);
        features[1] = new FeatureNode(3, -1.0);
        features[2] = new FeatureNode(8, 0.5);
        features[3] = new FeatureNode(11, -0.5);

        // predict実行
        int result = Linear.predict(model, features);
        System.out.println(result);
    }
}

heart_scaleは1〜13までの要素がすべて指定してあったが、上記のように一部だけ指定(1,3,8,11の要素だけ指定している)することもできる。

応用例

試しにこれを使ってフレーズ抽出を試みてみた。

長くなったので別記事にまとめる。

LIBLINEAR(Java版)でフレーズ抽出を試みたメモ
http://www.mwsoft.jp/liblinear_word_extract.html