language-detection を使った言語判定

language-detection を試してみました。

language-detection は指定されたテキストが何語か判定するJavaのライブラリで、、

といったように、とても実用的なライブラリのようです。

使用方法は、下記のようになっています。

  1. 各言語のプロファイルを読み込む(判定したい言語のプロファイルをディレクトリに配置して)
  2. テキストを設定
  3. 言語判定結果を取得(2種類の方法)
    • もっとも確率の高い言語
    • 確率の高い順に複数の候補(言語名とその確率)

簡単なコードにすると下記の通りです。

import java.util.ArrayList;

import com.cybozu.labs.langdetect.Detector;
import com.cybozu.labs.langdetect.DetectorFactory;
import com.cybozu.labs.langdetect.LangDetectException;
import com.cybozu.labs.langdetect.Language;

public class LandDetectSample {

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

        final String text = "Language-Detection Project は、テキストの言語判定(言語識別|言語判別)を行う Java ライブラリです。";

        // 言語プロファイルの読み込み
        DetectorFactory.loadProfile("profiles");

        Detector detector = DetectorFactory.create();

        // 判定対象のテキスト設定
        detector.append(text);

        // 判定結果(言語候補)を取得
        ArrayList<Language> languages = detector.getProbabilities();
        for (Language language : languages) {
            System.out.println(language.lang + ":" + language.prob);
        }
    }
}

上記を実行すると、下記のような結果が得られます。

ja:0.7142847350600212
en:0.2857129570646648

ただ、上記のコードを複数回実行したところ、なぜか実行毎に結果が違ってきてしまいます。

複数回実行するようなコードを書いてみて、、

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

    final String text = "Language-Detection Project は、テキストの言語判定(言語識別|言語判別)を行う Java ライブラリです。";

    // 言語プロファイルの読み込み
    DetectorFactory.loadProfile("profiles");

    for (int i = 0; i < 5; i++) {
        Detector detector = DetectorFactory.create();

        // 判定対象のテキスト設定
        detector.append(text);

        // 判定結果(言語候補)を取得
        ArrayList<Language> languages = detector.getProbabilities();
        for (Language language : languages) {
            System.out.println(i + ":" + language.lang + ":"
                    + language.prob);
        }
    }
}

そうすると、結果は下記のようになりました。

0:ja:0.7142848885692388
0:en:0.28571314811613724
1:ja:0.8571416824708172
1:gn:0.14285631420681125
2:ja:0.5714286787395505
2:gn:0.2857134027882973
2:en:0.14285607331900202
3:ja:0.7142839563385275
3:gn:0.2857138204479026
4:ja:0.42857075763497887
4:en:0.4285698282933965
4:sq:0.14285686855562352

1位が変わることはないですが、確率や2位以降に出てくるものが違うものになりました。
何に左右されてこのような結果になるのかが、まったく想像つかないのですが、、同じテキストならば、同じ結果になって欲しいなぁと思いました。(使い方で何かまずいところがあるのかなぁ...)

              • -

追記:
乱数を使っている部分があって、そこで変わってきてしまうようです。
同じテキストで毎回同じ結果になるようにできないかなぁ。

              • -

追記@2011/05/09
作者のn_shuyoさんに対応していただき、同じ文書が同じ結果となるよう、乱数のシードを指定できるようになりました。
(詳しくはコメント参照)

              • -

後で、もう少し大きなテキストでも試してみたいと思います。


アルゴリズムなどは、作者の方のプレゼン資料がとても参考になります。