PythonでGraphvizを使ってマルコフチェーンを描画する

概要

マルコフチェーン(markov chain)を、PythonのPydotplus(又はPydot)からGraphvizを使って簡単に作るモジュール(markovViz)を作成しました。以下イメージです。

環境構築

以下の記事と同じなので省略します。

PythonでGraphvizを使ってニューラルネットワークを描画する


入力条件

pandasのデータフレームのindexを遷移元、columnを遷移先とし、値として遷移確率を設けたデータフレームを入力とします。
以下がイメージです。

表の値の説明(抜粋)

  • 状態aからbに遷移する確率:20%
  • 状態aからdに遷移する確率: 0%
  • 状態bからaに遷移する確率:70%
  • 状態bから遷移しない確率:30%

プログラム

以下がソースコードです。適当に張り付けて使ってください。

#必要なモジュールのインポート
import pandas as pd
import numpy as np
import pydotplus

def markovViz(markovdf, fileName='default.png'):

#オブジェクトを定義
graph = pydotplus.Dot(graph_type='digraph')

#ノードを追加
for c in df.columns:
node = pydotplus.Node(c)
graph.add_node(node)

#エッジを追加
for i in df.index:
for c in df.columns:
if df.ix[i, c] > 0:
edge = pydotplus.Edge(graph.get_node(i)[0], graph.get_node(c)[0])
edge.set_label('{:.1f}'.format(df.ix[i, c]))
graph.add_edge(edge)

#グラフ描画
graph.write_png(fileName, prog='dot')

いろいろ試してみる

せっかく作ったのでいろいろ試してみました。
まずは例題の結果。

if __name__ == "__main__":
df = pd.DataFrame(index=['a', 'b', 'c', 'd'],
columns=['a', 'b', 'c', 'd'],
data=[[0.6, 0.2, 0.2, 0.0],
[0.7, 0.3, 0.0, 0.0],
[0.0, 0.4, 0.5, 0.1],
[0.1, 0.3, 0.3, 0.3]])

markovViz(df)


ラベルと線の間の余白や線の曲がりがちょっと気になりますが、まずは使えるレベルと言えそうですね。

10の状態を設けた場合の結果。

if __name__ == "__main__":

#ランダムなデータを作成
np.random.seed(0)
data = np.random.rand(10, 10)

#行方向の合計が1になるように正規化
data = (data / data.sum(axis=0)).T

#DataFrame作成
df = pd.DataFrame(data, index=np.arange(10).astype('str'), columns=np.arange(10).astype('str'))

#グラフ作成
markovViz(df)


うまくかけていますね。こういうのを見ると、Graphvizやるなぁ、という気がします。

20の状態を設けた場合の結果。

ここまでくると何が何だかわかりませんが、参考ということで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA