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": "。"
}
]
}
]
}
}