Ad

CaboChaEditとは anchor.png Edit

CaboChaEditはどの単語がどの単語を修飾しているかなど、日本語の係り受け関係を解析するツール。 詳細は公式ページhttps://taku910.github.io/cabocha/を参照のこと。

例えば

echo "これは私のもっている赤いペンです"|cabocha

とすると、

     これは-----D
         私の-D |
     もっている-D
     赤いペンです
EOS

とツリー出力されます。これはわかりやすいようで曖昧な感じの表現です。より厳密な表示をさせるため「-f1」オプションをつけて実行しなおすと以下のようになります。

echo "これは私のもっている赤いペンです"|cabocha -f1
* 0 3D 0/1 -2.060711
これ	名詞,代名詞,一般,*,*,*,これ,コレ,コレ
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
* 1 2D 0/1 2.120296
私	名詞,代名詞,一般,*,*,*,私,ワタシ,ワタシ
の	助詞,格助詞,一般,*,*,*,の,ノ,ノ
* 2 3D 0/2 -2.060711
もっ	動詞,自立,*,*,五段・タ行,連用タ接続,もつ,モッ,モッ
て	助詞,接続助詞,*,*,*,*,て,テ,テ
いる	動詞,非自立,*,*,一段,基本形,いる,イル,イル
* 3 -1D 1/2 0.000000
赤い	名詞,一般,*,*,*,*,赤井,アカイ,アカイ
ペン	名詞,一般,*,*,*,*,ペン,ペン,ペン
です	助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
EOS

アスタリスクから始まる行がCaboChaEditの解析結果で、それ以外は形態素解析の結果です。ここではMecabを使っているので、その結果となっています。

一つ目の

* 0 3D 0/1 -2.060711

を例にすると、各データの意味は以下の通りです。

  • 最初の0は文節の通番。文頭なので0
  • 3Dは数字の部分がその文節がかかっている通番。ここでは通番3の「赤いペンです」にかかっている。かかり先がなければ-1。よって文末は常に-1。Dの意味は資料がなく不明
  • 0/1の主辞(文節の中心となる単語)と機能語(助詞など)の位置を示している。この例では「私」が主辞で「の」が機能語
  • 次の小数値はかかりやすさの度合い

CaboChaEditは文を文節、つまり形態素の集まりに分解し解析するので、CaboChaEditのそれぞれの結果には複数の形態素が含まれます。アスタリスクから始まる行の続きの行がその形態素です。つまりこの通番0の結果には「これ」「は」の二つの形態素が含まれます。

実際によく使うのは最初の通番と二番目のかかり先です。主辞/機能語は公式ページによると廃止も検討されています。かかりやすさの度合いは実際にどの程度精度に関わっているかは調査中だそうです。

よって上の例をまとめると、

  • 「これは」は「赤いペンです」にかかっている
  • 「私の」は「もっている」にかかっている
  • 「もっている」は「赤いペンです」にかかっている
  • 「赤いペンです」は文末なのでかかり先なし

となります。

コマンドライン引数で形態素解析のエンジンにパラメーターを渡すことも可能です。

echo "おいしいチーズケーキをもらった"|cabocha -f1 

の結果は

* 0 1D 0/0 1.755362
おいしい	形容詞,自立,*,*,形容詞・イ段,基本形,おいしい,オイシイ,オイシイ
* 1 2D 1/2 1.755362
チーズ	名詞,一般,*,*,*,*,チーズ,チーズ,チーズ
ケーキ	名詞,一般,*,*,*,*,ケーキ,ケーキ,ケーキ
を	助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
* 2 -1D 0/1 0.000000
もらっ	動詞,自立,*,*,五段・ワ行促音便,連用タ接続,もらう,モラッ,モラッ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
EOS

となって「チーズケーキ」が認識されないですが、例えば「 /usr/local/lib/mecab/dic/mecab-ipadic-neologd/」にmecab-ipadic-NEologdの辞書をインストールしておけば、

echo "おいしいチーズケーキをもらった"|cabocha -f1 -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/

という風にmecabの「-d」オプションを使うことで、

* 0 1D 0/0 1.656278
おいしい	形容詞,自立,*,*,形容詞・イ段,基本形,おいしい,オイシイ,オイシイ
* 1 2D 0/1 1.656278
チーズケーキ	名詞,固有名詞,一般,*,*,*,チーズケーキ,チーズケーキ,チーズケーキ
を	助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
* 2 -1D 0/1 0.000000
もらっ	動詞,自立,*,*,五段・ワ行促音便,連用タ接続,もらう,モラッ,モラッ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
EOS

と出力されます。

他にもいろいろなコマンドラインオプションがありますが、ここでは使わないので詳細は公式ページを参照してください。

Page Top

Pythonから使う anchor.png Edit

CaboChaEditはpythonから使うこともできます。インストール方法などは他にもたくさんの資料があるのでそちらにゆずるとして、使い方は、まずインポートして

import CaboCha

次にパーサーを取得します。このとき前節のコマンドラインオプションと同様に、辞書を指定することもできます。

c = CaboCha.Parser("-d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/")

あとはこのパーサーでパースします。

parsed =  c.parse("これは私のもっている赤いペンです")

ツリー表示なども可能です。

parsed =  c.parse("これは私のもっている赤いペンです")
print parsed.toString(CaboCha.FORMAT_TREE)
     これは-----D
         私の-D |
     もっている-D
     赤いペンです
EOS

注意しないといけないのは、パーサーは内部的にデータの保持はしてくれないことです。つまり

parsed =  c.parse("これは私のもっている赤いペンです")
parsed2 = c.parse("おいしいチーズケーキをもらった")
print parsed.toString(CaboCha.FORMAT_TREE)

とすると結果は

     おいしい-D  
 チーズケーキを-D
         もらった
EOS

となり変数parsed2に結果を格納したつもりでも、parsedの方も書きかわってしまいます。そのため、パースしたその結果を保持したければ、自分で他の変数に結果を移さなければなりません。

そのためにはパース結果からデータを取り出す必要があります。 パーサーが返す結果には次のメソッドがあります。

まず文節のデータに関しては

メソッド名引数概要
chunk整数引数番目の文節のデータを取得する
chunk_sizeなし文節の個数を取得する

一方、形態素解析のデータに関しては

メソッド名引数概要
token整数引数番目の形態素のデータを取得する
token_sizeなし形態素の個数を取得する

というメソッドがあります。

よって文節のデータを全て取り出すには、先ほどパースした「parsed」に対して以下のようにします。

for i in range(parsed.chunk_size()):
    chunk = parsed.chunk(i)

このとき取り出した一つ一つのデータ(上の例ではchunk)には以下のプロパティがあります。

プロパティ名概要
scoreかかりやすさの度合い
link文節がかかっている通番
token_size含まれる形態素の数
token_pos含まれる形態素の先頭の場所
head_pos主辞の場所
func_pos機能語の場所

ほとんどのプロパティは前節のコマンドラインで実行した例で解説しているので、分からないところは戻って確認してください。token_posは例えば

first_token = parsed.token(chunk.token_pos)

とするとその文節の最初の形態素が取得できます。

一方、tokenつまり形態素解析の結果についてはMecabのpythonバインディングと全く同じ格納のされかたをされています。詳細は自然言語解析​/MeCabをpythonで使うを参照してください。

例えば

print token.surface

とすれば元の単語が表示されます。 よって

for i in range(parsed.chunk_size()):
    chunk = tree.chunk(i)
    for j in range(chunk.token_size):
            token = parsed.token(chunk.token_pos + j)
            print token.surface,

とすると、元の文章が空白区切りで出力されます

これらのことから、Cabochaの結果をpythonで保持するには、次のようなクラスがあれば良いことになります。

各々の文節(chunk)について

class CabochaChunk:
   __ATTRS = ("score","link","token_pos","token_size","head_pos","func_pos")
   def __init__(self,chunk):
       for attr in self.__ATTRS:
           setattr(self, attr, getattr(chunk, attr))

を定義し、

cabochaCunk = CabochaChunk(chunk)

とすれば文節のデータを保持できます。 あとはこれと形態素のデータを配列で保持するクラスを作れば、CaboChaEditの結果が保持できます。

class CabochaResult:
   def __init__(self,tree):
       self.reSetPrm(tree)
   def reSetPrm(self,tree):
       self.chunks = []
       self.tokens = []
       for i in range(tree.chunk_size()):
           chunk = tree.chunk(i)
           cc = CabochaChunk(chunk)
           self.chunks.append(cc)
       for i in range(tree.token_size()):
           token = tree.token(i)
           mr = MecabResult(oken.surface,token.feature)
           self.tokens.append(mr)

ここでMecabResultEditCabochaChunkEditと同様にMecabの形態素解析の結果を保持するクラスです。

Page Top

実際の利用例 anchor.png Edit

実際には例えば飲食店の口コミの解析で使ってみました。

まず形態素の頻度解析を行い、その上位の名詞について係り受け解析を行い、かかっている語の中から形容詞を抜き出してみました。

あるラーメン店でそれを行ってみた結果が以下の通りです。

ラーメン :やさしい :良い :なく :分厚い :無かっ :嬉しい :安い :硬い :おいしい :優しい :うまい :潔い :旨い 
スープ :熱い :おいしい :いい :茶色い :こい :薄い :高い :良い :うまい :柔かい :甘い 
麺 :柔い :固い :面白い :淡い :おいしい :硬い :柔かい :堅い
卵 :無し :硬い :潔い :なく :良い 
テーブル :多い 
豚骨 :薄い :おいしい :いい 

上の結果から、とんこつで茶色いスープ、固めの麺でトッピングは玉子、値段は安めで優しい味、テーブル席が多めの店かなと予想できます。

実際の口コミを読むと、麺は「固くなく」という表現が多く、実は柔らかいことがわかりました。上の結果でも「柔らかい」もあり微妙なところです。他の部分はあっていました。

否定語などの扱いをどうするかをちゃんとすれば、ある程度印象のようなものが解析できそうです。 また料理は形容詞以外、例えば名詞(例:ボリュームがある)や副詞(例:こってり)、比喩表現などで説明することも多く、そういったものも解析できれば精度が上げられるかもしれません。

他の問題点として同じラーメンでも複数の主力メニューがあるとその印象が混じってしまう可能性があります。 対象となるのが何かを判断するには、各々の文がどういう構造かではなく、全体の文脈が必要となるので、この方法ではこの問題を解決するのは難しそうです。

係り受けや頻度解析からさらに精度を上げるには、プログラムに何らかの形で「意味」を理解させたりすることが必要かも知れません。


Front page   Edit Freeze Diff Backup Upload Copy Rename ReloadPrint View   New Page Page list Search Recent changes   Help   RSS of recent changes (RSS 1.0) RSS of recent changes (RSS 2.0) RSS of recent changes (RSS Atom) Powered by xpWiki
Counter: 5323, today: 5, yesterday: 2
Princeps date: 2016-11-11 (Fri) 15:08:57
Last-modified: 2016-11-27 (Sun) 13:05:42 (JST) (2086d) by njf
MenuBar
広告

ログイン

ユーザー名:


パスワード:





パスワード紛失

Portuguese | English | German | Greek | Japanese | Korean | Russian | T-Chinese top
NJF