中年engineerの独り言 - crumbjp

LinuxとApacheの憂鬱

熟語解析が難しい。。。(もはや走り書きメモ)

修正: x: unigram => o: bigram
 勢いで書くとこうだよ・・・

形態素解析でTokenize後にN-gramで熟語解析しようとしたが、ちと困った。。

 日本 維新 の 会

これをbigramすると
 日本維新
 維新の
 の会

となって、これを使ってもう一回Tokenizeすると

 日本維新 の会

更にbigramしてやっと完成する。

 日本維新の会

ここから、もう一回Tokenizeすると望む結果になるが、、

3回もTokenizeしたら日が暮れるじゃ済まないよ・・・

追記

とりあえず、一気に4-gram, 3-gram , 2-gram とかけてみる事にした。
辞書に無駄な登録をしない様に、登録前に熟語候補のDFを評価してフィルタ。

更に、『日本維新の会』に対して
 日本維新の
 維新の
 の会
みたいなのは、DFも掻い潜って来るのだが、、これはどうすれば良いんだろ・・・

先頭一致じゃない奴は評価が難しいな・・・

さらに追記

DF(日本維新の) >= DF(日本維新の会)

になってしまうので、

 本当のDF(日本維新の) = DF(日本維新の) - DF(日本維新の会)

と評価する事は出来るが、、若干重い。。
 (4-gram , 3-gram , 2-gramとやっているのでかなりの量がある。。)

更に、同じことは

  DF(維新の会) >= DF(日本維新の会)

でも言えるのだけど、こちらは前方マッチに掛けられないので、苦しい・・・

更に追記

FBで色々教えて頂きながら、組上げる事ができた。

色々メモを残しておいて、後でまとめよう。。

どうやらn-gramの結果から熟語を得る場合、C-VALUEを使う方法があるらしい。。

C-VALUE

DNA解析などで用いられている、全体と部分を評価する手法らしい。

Cが何なのか解らなかったのでwikipediaを引いてみたが・・・
I am afraid the letter C stood for nothing more glamorous than 'constant'

という訳で、たいした意味は無いっぽいw

C-VALUE(W) = ( n - 1 ) x ( tf(W) - t(W)/c(W) )

tf(W)
Wという単語の頻出度
t
Wという単語を含む単語の頻出度
c
Wという単語を含む単語の数(種類数)

式を分解して考えるとこうゆー事らしい。。

(n-1)
長い単語ほど価値が高い
tf(W)
頻出するものは価値が高い
- t(W) / c(W)
その単語を含むより長い単語がある場合は、価値が下がる。
しかしその様な単語が沢山ある場合は、下落率は低くなる。
(その単語にも何らかの意味があるはずだ!)

つまり
日本維新の会】 が5回現れて【維新の会】 が5回現れたとしたら、【維新の会】は完全に【日本維新の会】の一部であるので、価値はC-VALUEはゼロ。

そうではなく
日本維新の会】 が4回現れて、【大阪維新の会】が1回現れて【維新の会】が5回現れたとしたら、【維新の会】は単独で現れた訳では無いが、若干の意味があるはずだ。

実際は、、

tfをベースとすると、単独や少数のドキュメントの誤用法やタイポ、単に連呼してるだけ、、の様なものが上位に食い込みやすい。
どうもdfベースとした方が、好ましい結果がでるように感じた。

また、(n-1)の項は熟語解析には強すぎる。
橋下徹代表】が【橋下徹】よりずっと上に来るのはどうなのよ?と、、


という訳で、対数を取ったり色々補正項を試してみたが、1固定にした方がよさげ、、
つまり『長い単語ほど価値が高い』を否定した方が良い。。

計算量

今は4-gram , 3-gram , 2-gramの結果をC-VALUEに掛けているが、もう少し長くても良いかな?

ただ積極的にフィルターしていかないとデータ量の爆発についていけなくなる。

今はデータ量的に、Tokenizeの結果に対し、2,3,4-gramを全部あわせて1/10程度まで絞りに絞っている。