使えそうなベイジアンネットワークのJavaライブラリを探す

# はじめに
Javaでベイジアンネットワークを動かす必要ができたので良さげなライブラリを探しました。
#やったこと
条件としては

- 現在も保守が続いている
- jarファイルで頒布されている
- チュートリアル完備
- オープンソース

ベイジアンネットワークのライブラリで
ネットワーク構造と条件付き確率を学習してくれるやつないかな〜と探しました。

# 結果
使えそうなのは以下の二つ

- weka
- mahout

それ以外で検討したものは以下

- Netica-j(エラー解決できなかった)
- jayes(ビルドで失敗した、GitHubの更新も５〜６年前でストップしていて保守されていない雰囲気がある)
- BayesServer(すごくいい感じ、ただし有料、約７万円かかる)

## ライブラリの利用
### weka
wekaはニュージーランドのワイカト大学で開発した機械学習ソフトウェアでjarファイルはGUIアプリケーションとして使うこともできる代物。
今回はjarファイルの中のクラスをJavaで使わさせていただくことにします。
学習用のデータはこちらを利用しました。
https://gist.github.com/carl0967/7a3588cd6f0d40d02a26

以下ソースコード

```java
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を利用してベイジアンネットワークを作る](http://informationstudent.blog.fc2.com/blog-entry-23.html)

結果

```
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を利用するのが大抵の場合妥当だと感じました。