CaboCha でパースした結果を FORMAT_XML
するとこんな感じになるので、
<sentence>
<chunk id="0" link="1" rel="D" score="1.990242" head="0" func="1">
<tok id="0" feature="名詞,固有名詞,一般,*,*,*,金融商品取引法,キンユウショウヒントリヒキホウ,キンユーショーヒントリヒキホー">金融商品取引法</tok>
<tok id="1" feature="助詞,格助詞,一般,*,*,*,に,ニ,ニ">に</tok>
</chunk>
<chunk id="1" link="7" rel="D" score="0.627582" head="2" func="3">
<tok id="2" feature="動詞,自立,*,*,五段・カ行イ音便,連用タ接続,基づく,モトヅイ,モトズイ">基づい</tok>
<tok id="3" feature="助詞,接続助詞,*,*,*,*,て,テ,テ">て</tok>
<tok id="4" feature="記号,読点,*,*,*,*,、,、,、">、</tok>
</chunk>
<chunk id="2" link="3" rel="D" score="0.900482" head="5" func="6">
<tok id="5" feature="名詞,固有名詞,一般,*,*,*,事業年度,ジギョウネンド,ジギョーネンド">事業年度</tok>
<tok id="6" feature="助詞,並立助詞,*,*,*,*,や,ヤ,ヤ">や</tok>
</chunk>
<chunk id="3" link="4" rel="D" score="2.602002" head="7" func="8">
<tok id="7" feature="名詞,一般,*,*,*,*,四半期,シハンキ,シハンキ">四半期</tok>
<tok id="8" feature="助詞,連体化,*,*,*,*,の,ノ,ノ">の</tok>
</chunk>
<chunk id="4" link="7" rel="D" score="0.888829" head="11" func="12">
<tok id="9" feature="名詞,サ変接続,*,*,*,*,終了,シュウリョウ,シューリョー">終了</tok>
<tok id="10" feature="名詞,固有名詞,一般,*,*,*,3か月,サンカゲツ,サンカゲツ">3カ月</tok>
<tok id="11" feature="名詞,非自立,副詞可能,*,*,*,以内,イナイ,イナイ">以内</tok>
<tok id="12" feature="助詞,格助詞,一般,*,*,*,に,ニ,ニ">に</tok>
</chunk>
<chunk id="5" link="7" rel="D" score="1.938762" head="13" func="14">
<tok id="13" feature="名詞,固有名詞,一般,*,*,*,金融庁長官,キンユウチョウチョウカン,キンユーチョーチョーカン">金融庁長官</tok>
<tok id="14" feature="助詞,格助詞,一般,*,*,*,に,ニ,ニ">に</tok>
</chunk>
<chunk id="6" link="7" rel="D" score="2.378815" head="15" func="16">
<tok id="15" feature="名詞,サ変接続,*,*,*,*,提出,テイシュツ,テイシュツ">提出</tok>
<tok id="16" feature="助詞,格助詞,一般,*,*,*,が,ガ,ガ">が</tok>
</chunk>
<chunk id="7" link="8" rel="D" score="2.697188" head="17" func="20">
<tok id="17" feature="動詞,自立,*,*,一段,未然形,義務づける,ギムヅケ,ギムズケ">義務づけ</tok>
<tok id="18" feature="動詞,接尾,*,*,一段,連用形,られる,ラレ,ラレ">られ</tok>
<tok id="19" feature="助詞,接続助詞,*,*,*,*,て,テ,テ">て</tok>
<tok id="20" feature="動詞,非自立,*,*,一段,基本形,いる,イル,イル">いる</tok>
</chunk>
<chunk id="8" link="12" rel="D" score="-1.536080" head="21" func="22">
<tok id="21" feature="名詞,一般,*,*,*,*,書類,ショルイ,ショルイ">書類</tok>
<tok id="22" feature="助詞,格助詞,一般,*,*,*,で,デ,デ">で</tok>
<tok id="23" feature="記号,読点,*,*,*,*,、,、,、">、</tok>
</chunk>
<chunk id="9" link="10" rel="D" score="1.541807" head="24" func="25">
<tok id="24" feature="名詞,一般,*,*,*,*,事業,ジギョウ,ジギョー">事業</tok>
<tok id="25" feature="助詞,連体化,*,*,*,*,の,ノ,ノ">の</tok>
</chunk>
<chunk id="10" link="11" rel="D" score="2.508582" head="31" func="33">
<tok id="26" feature="名詞,一般,*,*,*,*,状況,ジョウキョウ,ジョーキョー">状況</tok>
<tok id="27" feature="記号,一般,*,*,*,*,・,・,・">・</tok>
<tok id="28" feature="名詞,一般,*,*,*,*,財務,ザイム,ザイム">財務</tok>
<tok id="29" feature="名詞,一般,*,*,*,*,状態,ジョウタイ,ジョータイ">状態</tok>
<tok id="30" feature="記号,一般,*,*,*,*,・,・,・">・</tok>
<tok id="31" feature="名詞,固有名詞,一般,*,*,*,経営成績,ケイエイセイセキ,ケイエイセイセキ">経営成績</tok>
<tok id="32" feature="助詞,副助詞,*,*,*,*,など,ナド,ナド">など</tok>
<tok id="33" feature="助詞,連体化,*,*,*,*,の,ノ,ノ">の</tok>
</chunk>
<chunk id="11" link="12" rel="D" score="-1.536080" head="34" func="35">
<tok id="34" feature="名詞,一般,*,*,*,*,情報,ジョウホウ,ジョーホー">情報</tok>
<tok id="35" feature="助詞,格助詞,一般,*,*,*,を,ヲ,ヲ">を</tok>
</chunk>
<chunk id="12" link="-1" rel="D" score="0.000000" head="37" func="40">
<tok id="36" feature="名詞,サ変接続,*,*,*,*,掲載,ケイサイ,ケイサイ">掲載</tok>
<tok id="37" feature="動詞,自立,*,*,サ変・スル,連用形,する,シ,シ">し</tok>
<tok id="38" feature="助詞,接続助詞,*,*,*,*,て,テ,テ">て</tok>
<tok id="39" feature="動詞,非自立,*,*,一段,連用形,いる,イ,イ">い</tok>
<tok id="40" feature="助動詞,*,*,*,特殊・マス,基本形,ます,マス,マス">ます</tok>
<tok id="41" feature="記号,句点,*,*,*,*,。,。,。">。</tok>
</chunk>
</sentence>
pydotでグラフ描いてみた話。
コード
無駄に指定したキーワードを赤くする機能も入れてみたり。
import CaboCha
import lxml.etree
import pydot
def xml_to_chunks(xml_txt):
root = lxml.etree.fromstring(xml_txt)
assert root.tag == "sentence"
ret = {}
for chunk in root.getchildren():
assert chunk.tag == "chunk"
sentence = "".join([ token.text for token in chunk.getchildren() ])
chunk_id = chunk.attrib["id"]
ret[chunk_id] = (sentence, chunk)
return ret
def create_pydot_node(label, elem, kwds):
node_id = "%s_%s" % (elem.tag, elem.attrib["id"])
for kwd in kwds:
if kwd in label:
fontcolor = "#FF0000"
break
else:
fontcolor = "#000000"
return pydot.Node(node_id, label=label, fontcolor=fontcolor)
def sentence_to_graph(parser, text, kwds):
tree = parser.parse(text)
xml = tree.toString(CaboCha.FORMAT_XML)
chunks = xml_to_chunks(xml)
graph = pydot.Dot(graph_type='digraph')
for sentence, elem in chunks.values():
link = elem.attrib["link"]
if link == "-1":
continue
link_sentence, link_elem = chunks[link]
node1 = create_pydot_node(sentence, elem, kwds)
node2 = create_pydot_node(link_sentence, link_elem, kwds)
graph.add_node(node1)
graph.add_node(node2)
graph.add_edge(pydot.Edge(node1, node2))
return graph
if __name__ == '__main__':
parser = CaboCha.Parser("-d /usr/local/lib/mecab/dic/mecab-ipadic-neologd")
text = "金融商品取引法に基づいて、事業年度や四半期の終了3カ月以内に金融庁長官に提出が義務づけられている書類で、事業の状況・財務状態・経営成績などの情報を掲載しています。"
keywords = ["事業"]
g = sentence_to_graph(parser, text, keywords)
g.write_png("a.png")