CaboCha のツリーを扱いたいのですがデフォルトでは JSON でのアウトプットがない様なので、xmltodict を利用して XML 形式から JSON 形式に変換します。
XML での表出
まず、XML の表出は下記の様になります。
import CaboCha c = CaboCha.Parser() tree = c.parse('今日は天気がとても良いですね。') xmltree = tree.toString(CaboCha.FORMAT_XML) print(xmltree)
XML アウトプット
<sentence> <chunk id="0" link="3" rel="D" score="-1.359140" head="0" func="1"> <tok id="0" feature="名詞,副詞可能,*,*,*,*,今日,キョウ,キョー">今日</tok> <tok id="1" feature="助詞,係助詞,*,*,*,*,は,ハ,ワ">は</tok> </chunk> <chunk id="1" link="3" rel="D" score="-1.359140" head="2" func="3"> <tok id="2" feature="名詞,一般,*,*,*,*,天気,テンキ,テンキ">天気</tok> <tok id="3" feature="助詞,格助詞,一般,*,*,*,が,ガ,ガ">が</tok> </chunk> <chunk id="2" link="3" rel="D" score="-1.359140" head="4" func="4"> <tok id="4" feature="副詞,助詞類接続,*,*,*,*,とても,トテモ,トテモ">とても</tok> </chunk> <chunk id="3" link="-1" rel="D" score="0.000000" head="5" func="7"> <tok id="5" feature="形容詞,自立,*,*,形容詞・アウオ段,基本形,良い,ヨイ,ヨイ">良い</tok> <tok id="6" feature="助動詞,*,*,*,特殊・デス,基本形,です,デス,デス">です</tok> <tok id="7" feature="助詞,終助詞,*,*,*,*,ね,ネ,ネ">ね</tok> <tok id="8" feature="記号,句点,*,*,*,*,。,。,。">。</tok> </chunk> </sentence>
JSON での表出
xmltodict を使うので、インストールしていない場合はコマンド「pip install xmltodict」でインストールしてください。
import CaboCha import xmltodict import json c = CaboCha.Parser() tree = c.parse('今日は天気がとても良いですね。') xmltree = tree.toString(CaboCha.FORMAT_XML) jsonobj = xmltodict.parse(xmltree, attr_prefix='', cdata_key='surface', dict_constructor=dict) print(json.dumps(jsonobj, indent=2, ensure_ascii=False))
JSON アウトプット
{ "sentence": { "chunk": [ { "id": "0", "link": "3", "rel": "D", "score": "-1.359140", "head": "0", "func": "1", "tok": [ { "id": "0", "feature": "名詞,副詞可能,*,*,*,*,今日,キョウ,キョー", "surface": "今日" }, { "id": "1", "feature": "助詞,係助詞,*,*,*,*,は,ハ,ワ", "surface": "は" } ] }, { "id": "1", "link": "3", "rel": "D", "score": "-1.359140", "head": "2", "func": "3", "tok": [ { "id": "2", "feature": "名詞,一般,*,*,*,*,天気,テンキ,テンキ", "surface": "天気" }, { "id": "3", "feature": "助詞,格助詞,一般,*,*,*,が,ガ,ガ", "surface": "が" } ] }, { "id": "2", "link": "3", "rel": "D", "score": "-1.359140", "head": "4", "func": "4", "tok": { "id": "4", "feature": "副詞,助詞類接続,*,*,*,*,とても,トテモ,トテモ", "surface": "とても" } }, { "id": "3", "link": "-1", "rel": "D", "score": "0.000000", "head": "5", "func": "7", "tok": [ { "id": "5", "feature": "形容詞,自立,*,*,形容詞・アウオ段,基本形,良い,ヨイ,ヨイ", "surface": "良い" }, { "id": "6", "feature": "助動詞,*,*,*,特殊・デス,基本形,です,デス,デス", "surface": "です" }, { "id": "7", "feature": "助詞,終助詞,*,*,*,*,ね,ネ,ネ", "surface": "ね" }, { "id": "8", "feature": "記号,句点,*,*,*,*,。,。,。", "surface": "。" } ] } ] } }
さらに改良
上記でも JSON 形式で返ってきますが、chunk や tok 要素の中身が 1 つしかない時にリスト形式になっていない、feature がカンマ区切りの文字列(リスト形式でない)になっているなど少し不便です。
下記の様に処理を追加するとフォーマットを揃えることができます。
import CaboCha import xmltodict import json c = CaboCha.Parser() tree = c.parse('今日は天気がとても良いですね。') xmltree = tree.toString(CaboCha.FORMAT_XML) jsonobj = xmltodict.parse(xmltree, attr_prefix='', cdata_key='surface', dict_constructor=dict) # 追記分 ↓ if jsonobj['sentence']: # sentence が存在する際に処理を行う if type(jsonobj['sentence']['chunk']) is not list: # chunk を必ずリスト形式にする jsonobj['sentence']['chunk'] = [jsonobj['sentence']['chunk']] for chunk in jsonobj['sentence']['chunk']: if type(chunk['tok']) is not list: # tok を必ずリスト形式にする chunk['tok'] = [chunk['tok']] for tok in chunk['tok']: feature_list = tok['feature'].split(',') # feature をリスト形式に変換 tok['feature'] = feature_list # 追記分 ↑ print(json.dumps(jsonobj, indent=2, ensure_ascii=False))
JSON アウトプット ver 2
{ "sentence": { "chunk": [ { "id": "0", "link": "3", "rel": "D", "score": "-1.359140", "head": "0", "func": "1", "tok": [ { "id": "0", "feature": [ "名詞", "副詞可能", "*", "*", "*", "*", "今日", "キョウ", "キョー" ], "surface": "今日" }, { "id": "1", "feature": [ "助詞", "係助詞", "*", "*", "*", "*", "は", "ハ", "ワ" ], "surface": "は" } ] }, { "id": "1", "link": "3", "rel": "D", "score": "-1.359140", "head": "2", "func": "3", "tok": [ { "id": "2", "feature": [ "名詞", "一般", "*", "*", "*", "*", "天気", "テンキ", "テンキ" ], "surface": "天気" }, { "id": "3", "feature": [ "助詞", "格助詞", "一般", "*", "*", "*", "が", "ガ", "ガ" ], "surface": "が" } ] }, { "id": "2", "link": "3", "rel": "D", "score": "-1.359140", "head": "4", "func": "4", "tok": [ { "id": "4", "feature": [ "副詞", "助詞類接続", "*", "*", "*", "*", "とても", "トテモ", "トテモ" ], "surface": "とても" } ] }, { "id": "3", "link": "-1", "rel": "D", "score": "0.000000", "head": "5", "func": "7", "tok": [ { "id": "5", "feature": [ "形容詞", "自立", "*", "*", "形容詞・アウオ段", "基本形", "良い", "ヨイ", "ヨイ" ], "surface": "良い" }, { "id": "6", "feature": [ "助動詞", "*", "*", "*", "特殊・デス", "基本形", "です", "デス", "デス" ], "surface": "です" }, { "id": "7", "feature": [ "助詞", "終助詞", "*", "*", "*", "*", "ね", "ネ", "ネ" ], "surface": "ね" }, { "id": "8", "feature": [ "記号", "句点", "*", "*", "*", "*", "。", "。", "。" ], "surface": "。" } ] } ] } }