Pythonでベイジアンネットワークを手軽に実装しましょう。
pgmpy[1]ここではpgmpyバージョン0.1.11を利用します。というライブラリを使えば、ベイジアンネットワークが簡単に実装できます。[2]pomegranateなども有名ですが、ここでやるような実装ならpgmpyの方がお手軽です。
実装したいベイジアンネットワークを眺める
まずは、今から実装するベイジアンネットワークについて。
2値(0か1)をとる3つの確率変数について、以下のようなグラフを実装します。
ここではbatteryとかfuelなど、ノードの意味を気にする必要はありませんが、念のため補足すると、上のグラフは車の燃料装置におけるバッテリーや燃料タンクの状態の関係を表しています。
ちなみにこの例のベイジアンネットワークは言わずと知れた名著PRMLを参考にしています。
battery(0)はバッテリーが空、(1)は満タンです。
そして、gauge(燃料計)のノードの隣の表は、gaugeに関する条件付き確率分布を表しています。
例えば、P(gauge=0|fuel=0, battery=0)=0.9というようになります。
ベイジアンネットワークを実装する
さて、上のベイジアンネットワークを実装していきます。
実装するといっても大したことはありません。
上のグラフのノードと確率分布を見て、順番を間違えないように入力していくだけです。
from pgmpy.factors.discrete import TabularCPD
from pgmpy.models import BayesianModel
# ベイジアンネットワークの構造
model = BayesianModel([
# ('親ノード', '子ノード')
('battery', 'gauge'),
('fuel', 'gauge'),
])
battery_cpd = TabularCPD(
variable='battery',
variable_card=2,
# values[0]: empty, values[1]: full
values=[[.1], [.9]])
fuel_cpd = TabularCPD(
variable='fuel',
variable_card=2,
values=[[.1], [.9]])
gauge_cpd = TabularCPD(
variable='gauge',
variable_card=2,
values = [[.9, .8, .8, .2],
[.1, .2, .2, .8]],
evidence = ['battery', 'fuel'],
evidence_card=[2, 2]
)
model.add_cpds(battery_cpd, fuel_cpd, gauge_cpd)
これで、さっきのグラフのベイジアンネットワークが実装できました。
ベイジアンネットワークを使って推論する
もちろん、推論もできます。
例えばgauge=0(燃料計が空を指してる)とき、fuel=0(燃料タンクが空)の確率は
from pgmpy.inference import VariableElimination
model_infer = VariableElimination(model)
fuel0_prob_given_gauge0 = model_infer.query(variables=['fuel'], evidence={'gauge': 0})
print(fuel0_prob_given_gauge0.values[0]) # 0.257142
約0.257と求まります。
簡単ですね。
pgmpyをもっと知りたい方へ
pgmpyの使い方をもっと知りたい方は、本家のexampleよりも以下の説明が分かりやすいです。[3]構造学習などの話は公式ドキュメントをご参照ください。
ただし、この動画での実装は最近のバージョンだと一部エラーになりますのでご注意ください。[4]エラーメッセージを読んだり、ググればすぐに修正できるので恐るるに足りません。
ここではpgmpyを使って、ベイジアンネットワークを実装しました。
実装全体をGitHubで公開しておりますので、よろしければご活用ください。
ここまでお付き合い頂き、ありがとうございました。
コメント