BayesServerには.NETやJavaのライブラリが存在し、API経由でほぼすべての機能が使えます。
学習、推論まで可能なのですが、残念ながらネットワークビューをSDKで利用することは無理なようです。(開発元に問い合わせ済み)
BayesServerのクライアント(BayesServerは実際”サーバー”ではありませんが)で、作成したネットワークは、GUI上で推論などが可能なのですが、推論や予測をターゲットを絞ってやる際や、アプリケーションに組み込みたい場合はAPIを利用するのがよいです。
Bayes Server .NET Library を利用する
Bayes ServerをインストールしたPCであれば、すでに.NETのライブラリがインストールされています。
デフォルトであれば、以下のようなフォルダにあります。
C:\Program Files\Bayes Server\Bayes Server 7.20\API\NET 4.0\BayesServer.dll
Visual Studioの参照追加から、以下のようになっていればOKです。
.NET Frameworkベースのアプリケーションを作成します。最新のVisual Studio 2017では、Windows クラシックデスクトップというらしいですね。
using BayesServer;
using BayesServer.Inference;
using BayesServer.Inference.RelevanceTree;
UWPなどではダメでした。GUIなしなんだから、Portable版期待。
Bayes Serverの準備
code centerなどからサンプルが手に入ります。
大体の事は網羅されていますが、少しマニアックになるとやり方わかりません。
読み込みは以下のように、簡単です。desktopアプリで作ったネットワークを読み込んでくれます。
var network = new Network();
network.Load(fileName);
そして、推論用のクラスを生成しておきます。オプション、出力は空で良いようです。
var factory = new RelevanceTreeInferenceFactory();
inference = factory.CreateInferenceEngine(network);
queryOptions = factory.CreateQueryOptions();
queryOutput = factory.CreateQueryOutput();
すぐ推論
学習済みのモデルを使うので、いきなり推論してみましょう。
まず、証拠となる入力データを設定します。
Evidenceというものが推論オブジェクトのメンバにあるので、そこに、当該のノードの変数の状態(Nodes[].Variables[].States[] のような構造)を設定しましょう。
実験ではbooleanしかないノードを使っていたので、States[1]をセットします。対象外のノードはState[0]にするとより良い結果を得られる可能性はあります。
private void selectEvidences()
{
// reset query
inference.Evidence.Clear();
foreach (var n in network.Nodes)
{
var targetVar = n.Variables[0];
State state;
if (SelectedItems.Contains(n.Name))
{
state = targetVar.States[1];
}
else
{
state = targetVar.States[0];
}
inference.Evidence.SetState(state);
}
}
XAMLのコードビハインドのSelectedItemsというプロパティに設定された変数名がTrueになっている場合を想定しています。
これで、任意の変数セットがTrueになった場合の推論ができます。Evidenceは毎回Clearしないとどんどん増殖しますよ(笑)
次に推論を実行します。
QueryDistributionsというプロパティに、結果を収集したいVariableを設定します。ノードではなくVariableを設定しなければなりません。ここでは全ノードの全変数をクエリーしています。
クエリーする前には事前確率が設定されています。
private void updateInference()
{
inference.QueryDistributions.Clear();
foreach (var n in network.Nodes)
{
foreach (var v in n.Variables)
{
inference.QueryDistributions.Add(new BayesServer.Table(v) );
}
}
inference.Query(queryOptions, queryOutput);
}
結果を読む
inferenceオブジェクトの先ほど設定したQueryDistributionsに、値が入っているので、取りに行きます。
まずは確率値。Distributionの下のTable[1]に真になる確率が入っているので、降順にして取り出します。
var tabs = from tab in inference.QueryDistributions
orderby tab.Distribution.Table[1] descending
select tab;
結果はQueryDistributionというクラスのコレクションが得られます。
これから、値を取り出して、Values(モデルを想定)に入れるには以下:
Values.Clear();
Values.AddRange(tabs.Select(x => x.Distribution.Table[1])
ラベルのリストを取り出すには以下:
Labels.Clear();
var labels = tabs.Select(x => x.ToString());
foreach (var lab in labels) Labels.Add(lab);
ValuesはAddRangeがあるコレクションですが、Labelsは普通のコレクションでした。。。
(チャートコントロールを使ったのでこんなことに)
まとめ
BayesServerは、APIが整理されており、GUIの使い方を分かっていれば、APIドキュメントだけでもどうにか、アプリ開発できそうです。少し凝ったところも、GUIのメニューに書かれた文言を頼りにAPIを探っていきましょう。