#係り受け解析とは?
文節間の「修飾する(係る)」「修飾される(受ける)」の関係を調べる事です。
そして、CaboCha は, CRF (Conditional random field; 条件付き確率場) に基づく日本語係り受け解析器です。
#係り受け解析ができると何がいいの?
例えばこのようなことができます。
【Python】🍜可愛い店員さんがいるラーメン店を食べログ口コミから自然言語処理で抽出してみた。🍜
https://qiita.com/toshiyuki_tsutsui/items/a192cac082926a7aced5
#さて
そんな優秀なcabochaさんでも苦手なことがあるようです。
試しにこちらの文章を係り受け解析してみたいと思います。
私はお金も希望もない
なぜその言葉を選んだ!?というツッコミは受け付けません。
import CaboCha
def get_word(tree, chunk):
surface = ''
for i in range(chunk.token_pos, chunk.token_pos + chunk.token_size):
token = tree.token(i)
features = token.feature.split(',')
if features[0] == '名詞':
surface += token.surface
elif features[0] == '形容詞':
surface += features[6]
break
elif features[0] == '動詞':
surface += features[6]
break
return surface
def get_2_words(line):
cp = CaboCha.Parser('-f1')
tree = cp.parse(line)
chunk_dic = {}
chunk_id = 0
for i in range(0, tree.size()):
token = tree.token(i)
if token.chunk:
chunk_dic[chunk_id] = token.chunk
chunk_id += 1
tuples = []
for chunk_id, chunk in chunk_dic.items():
if chunk.link > 0:
from_surface = get_word(tree, chunk)
to_chunk = chunk_dic[chunk.link]
to_surface = get_word(tree, to_chunk)
tuples.append((from_surface, to_surface))
return tuples
line = '私はお金も希望もない'
tuples = get_2_words(line)
for t in tuples:
print(t[0] + ' → ' + t[1])
>>>
私 → ない
お金 → 希望
希望 → ない
私 → ない
お金 → 希望
希望 → ない
一見正しいようにも見えますが、
私 → ない
お金 → ない
希望 → ない
が正しい係り受けです。
こちらの係り受け解析ツールを使った結果
http://copita.jpn.org/ai/nlptool/da.php
こちらのツールでは正しく係り受け解析ができているようです。
原因
CaboCha は, CRF(Conditional random field; 条件付き確率場) に基づく日本語係り受け解析器ですので、教師ありの機械学習によって作られています。
そのため、並列構造の学習不足により誤った係り受けをしてしまうことがあるようです。
*並列構造・・・今回の例でいうと「お金と希望」の部分
詳しくはこちら↓
https://slidesplayer.net/slide/16974243/
バージョンアップによって改善はしているそうですがまだまだ課題があるみたいですね。
#結論
猿も木から落ちるように、CaboChaでも係り受け解析をミスることがあります。
個人的には、猿が木から落ちる姿🐒は可愛らしくきらいではありません。
なので、たとえ CaboCha🎃が係り受け解析をミスったとしても 「微笑ましいな」 と寛大な心で受け止めたいと思います。