🐣 PyDot なしで Graphviz だけで描画させる
作成日: 2021/12/14
0

きょうは『言語処理100本ノック』の 44 をやりました。第5章に入ってから急に難度が上昇した気がします。知らないことが多いなあと痛感しているところです。
こちらの解答例を参考にさせていただきながら学習を進めていますが、ここ数回はほぼ写経状態になってしまいました。
さて、解答例では以下のように PyDot と Graphviz をインポートし、PyDot で係り受け木をグラフ化しています。

import pydot
from IPython.display import Image,display_png
from graphviz import Digraph

sentence = sentences[7]
edges = []
for id, chunk in enumerate(sentence.chunks):
  if int(chunk.dst) != -1:
    modifier = ''.join([morph.surface if morph.pos != '記号' else '' for morph in chunk.morphs] + ['(' + str(id) + ')'])
    modifiee = ''.join([morph.surface if morph.pos != '記号' else '' for morph in sentence.chunks[int(chunk.dst)].morphs] + ['(' + str(chunk.dst) + ')'])
    edges.append([modifier, modifiee])
n = pydot.Node('node')
n.fontname = 'IPAGothic'
g = pydot.graph_from_edges(edges, directed=True)
g.add_node(n)
g.write_png('./ans44.png')
display_png(Image('./ans44.png'))

私のPCには 'IPAGothic' はインストールしていないので、代わりに 'MS Gothic' を指定しました。ところが、理由は分かりませんが、日本語部分が文字化けしてしまいました。
ans44_x.png
ネット上をあちこち検索して、PyDot で日本語フォントを指定する方法を調べましたが、いずれもうまくいきません。
こちらの Webページに Graphviz だけでグラフ化する例が書いてあったので、上記の解答例を PyDot ではなく、Graphviz で直接描画するように書き換えてみました。

dot = Digraph(format='png')
# フォント設定
dot.attr('node', fontname="MS Gothic")

for id, chunk in enumerate(sentence.chunks):
    if int(chunk.dst) != -1:
        modifier = ''.join([morph.surface if morph.pos != '記号' else '' for morph in chunk.morphs] + ['(' + str(id) + ')'])
        modifiee = ''.join([morph.surface if morph.pos != '記号' else '' for morph in sentence.chunks[int(chunk.dst)].morphs] + ['(' + str(chunk.dst) + ')'])
        # エッジ作成
        dot.edge(modifier, modifiee)
        edges += [modifier, modifiee]

dots = set(edges)
for elem in dots:
    # ノード作成
    dot.node(elem)

dot.render("test44")

今度は日本語が文字化けせずにうまく表示されました。
ans44_o.png
一応メデタシメデタシなのですが、ちょっと腑に落ちません。ひょっとしたら、私のPCの環境設定がどこかマズイのかもしれません。


pythonで自然言語処理プログラムが書けるようになりたいと思っています。Ticketnoteで自分の到達度を確認できれば嬉しいです。