はじめに
Javaでベイジアンネットワークを動かす必要ができたので良さげなライブラリを探しました。
やったこと
条件としては
- 現在も保守が続いている
- jarファイルで頒布されている
- チュートリアル完備
- オープンソース
ベイジアンネットワークのライブラリで
ネットワーク構造と条件付き確率を学習してくれるやつないかな〜と探しました。
結果
使えそうなのは以下の二つ
- weka
- mahout
それ以外で検討したものは以下
- Netica-j(エラー解決できなかった)
- jayes(ビルドで失敗した、GitHubの更新も5〜6年前でストップしていて保守されていない雰囲気がある)
- BayesServer(すごくいい感じ、ただし有料、約7万円かかる)
ライブラリの利用
weka
wekaはニュージーランドのワイカト大学で開発した機械学習ソフトウェアでjarファイルはGUIアプリケーションとして使うこともできる代物。
今回はjarファイルの中のクラスをJavaで使わさせていただくことにします。
学習用のデータはこちらを利用しました。
https://gist.github.com/carl0967/7a3588cd6f0d40d02a26
以下ソースコード
import java.io.*;
import java.util.*;
import weka.core.converters.ArffLoader;
import weka.classifiers.Evaluation;
import weka.classifiers.bayes.BayesNet;
import weka.classifiers.bayes.net.search.SearchAlgorithm;
import weka.classifiers.bayes.net.search.local.SimulatedAnnealing;
import weka.classifiers.bayes.net.search.local.K2;
import weka.core.Instances;
import weka.core.converters.ConverterUtils.DataSource;
public class bayesNet{
Instances instances;
BayesNet bnet;
Evaluation evaluation;
public bayesNet(){}
void setFile(File dataFile){
try {
ArffLoader al = new ArffLoader();
al.setFile(dataFile);
instances = al.getDataSet();
instances.setClassIndex(instances.numAttributes() - 1);
} catch (Exception e) {
e.printStackTrace();
}
}
void buildClassifier(){
try{
bnet = new BayesNet();
// サーチアルゴリズムの生成
SearchAlgorithm searchAlgorithm = new K2();
//BayesNetにセット
bnet.setSearchAlgorithm(searchAlgorithm);
//分類開始
bnet.buildClassifier(instances);
} catch(Exception e){
e.printStackTrace();
}
}
void evalute(){
try{
//評価
evaluation = new Evaluation(instances);
evaluation.evaluateModel(bnet, instances);
} catch(Exception e){
e.printStackTrace();
}
}
void showResult(){
System.out.println(evaluation.toSummaryString("Results\n",false));
}
public static void main(String[] args) {
bayesNet classifier = new bayesNet();
classifier.setFile(new File(args[0]));
classifier.buildClassifier();
classifier.evalute();
classifier.showResult();
}
}
参考: JavaでWekaのAPIを利用してベイジアンネットワークを作る
結果
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by weka.core.WekaPackageClassLoaderManager (file:/Users/Mnb0130/unirvFILE/semi/工学特別演習/bayesNet/weka/weka.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of weka.core.WekaPackageClassLoaderManager
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Results
Correctly Classified Instances 34 89.4737 %
Incorrectly Classified Instances 4 10.5263 %
Kappa statistic 0.6122
Mean absolute error 0.204
Root mean squared error 0.299
Relative absolute error 59.8749 %
Root relative squared error 73.3056 %
Total Number of Instances 38
少ないデータセットでおよそ89%の正解率なら想定移動りの動作であると思います。
やはりwekaを利用するのが大抵の場合妥当だと感じました。