R でベイジアンネットワーク
Rでベイジアンネットワークをやる際に、少数のノードの場合はよいのですが、多数のノードによるネットワークを表現するためには、少し工夫がいるようでした。
以下のhoxo_mさんのエントリなどを参考にやっていましたが、特にノードの表現で巨大ネットワークでは難しいことがわかりました。
使うライブラリ
R にはlibrary(deal)、library(bnlearn)などのライブラリがありますが、上記で紹介されている、比較的有名そうなdealを使う例が多いようでしたが、これだとノード数がある程度を超えると、以下のようなエラーに見舞われることが多いようです。
> prior.dist <- jointprior(pre.network)
Error in array(1, Dim) : negative length vectors are not allowed
このエラーは以下のStackoverflowのエントリを読むとどうもメモリオーバーフロー問題のようです。
Negative number of rows in data.table after incorrect use of set - stackoverflow
使っているデータはノード数が400を超えるので、これはこのライブラリには難しいのかもしれません。
抜本的な対策ではありませんが(打算的な対応ですが)bnlearnというライブラリを使ってみましたところ、同じネットワークに対してモデルを構築することができました。
参考:Rでグラフィカルモデル(ベイジアンネットワーク)を行う際に使うパッケージまとめ
library | Author | Organization | Download | Document |
---|---|---|---|---|
deal | Susanne G. Bøttcher, Claus Dethlefsen | Aalborg U. | CRAN | |
bnlearn | Marco Scutari | U. Oxford | CRAN | bnlearn |
catnet | Nikolay Balov, Peter Salzman | Stata Corp LP | CRAN | r-project |
catnetは触っていませんが、後発のようです。
ネットワークの表示
dealにはplotメソッドがあらかじめ用意されていましたので、簡単に表示できました。しかし上記の理由で大きなネットワークそのものを作れませんでしたので、どの程度まで表示できるかはわかりませんでした。
bnlearnでは外部のgraphvizを内包しており、以下のようにやれば、簡単にネットワークを表示できます。ちなみにshapeをrectangleにしないと、キャプションが入りきらず、見えにくくなります。
graphviz.plot(fitted, layout = "dot", shape = "rectangle")
しかし、これで表示しても、レイアウトによっては、以下のようにプロットエリアの解像度の問題で、大きなネットワークではノード名などがつぶれて表示されなくなります。
おそらくオートレイアウト機能がフォントサイズをコントロールしており、規定以下のサイズになり、消えてしまったのでしょう。
bnlearnのgraphvizラッパーには、解像度やフォントサイズをコントロールするオプションはありませんでした。
そこで、高解像度の表示をするためにpdf化を行ったところ、plotエリアの制限を超えて表示できました。width,heightで大き目のサイズ(インチ)の用紙を設定すれば、高解像度になります。dpiの直接指定はできません。
pdf("plots.pdf", width = 24, height = 18)
graphviz.plot(fitted, layout = "dot", shape = "rectangle")
dev.off()
PDF化をすれば、さらに大きなネットワークでもなんとかなりそうですね。ちなみに大きなPDFはブラウザ内蔵のビュアーではなくAcrobat Readerを使わないと拡大しきれないようです。