LoginSignup
0
2

More than 5 years have passed since last update.

CaboChaの係り受けをpydotで描いてみる

Last updated at Posted at 2018-05-11

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でグラフ描いてみた話。

a.png

コード

無駄に指定したキーワードを赤くする機能も入れてみたり。

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")
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2