hatunina’s blog

メモと日記です

crfsuiteとpycrfsuiteについて

CRFについて勉強中です。
色々調べつつサンプルを動かして見ました。

こちらはコマンドラインで実行できるcrfsuiteのチュートリアル記事です。

CRFsuite - Tutorial on Chunking Task -

英語ですが、難しい単語は出てこないですしざっくり大まかな概要は把握できると思います。特にfeature generationがわかりやすくてよかったです。固有表現抽出タスクについて勉強を始めた際に特徴量の形状が全く掴めなかったのですが、下図のように一般化されているとスッと頭に入って来ます。

・w[t-2], w[t-1], w[t], w[t+1], w[t+2],
・w[t-1]|w[t], w[t]|w[t+1],
・pos[t-2], pos[t-1], pos[t], pos[t+1], pos[t+2],
・pos[t-2]|pos[t-1], pos[t-1]|pos[t], pos[t]|pos[t+1], pos[t+1]|pos[t+2],
・pos[t-2]|pos[t-1]|pos[t], pos[t-1]|pos[t]|pos[t+1], pos[t]|pos[t+1]|pos[t+2]

tというインデックスが対象となっている単語です。
tを基準にして前後2単語と前後1単語との組み合わせ、また同様に品詞を特徴量と使用するわけです。

例えば、「4月は代々木公園で花見をします。」という文章で特徴量を考えてみます。

import MeCab
m = MeCab.Tagger()
print(m.parse("4月は代々木公園で花見をします。"))

実行結果

4月   名詞,副詞可能,*,*,*,*,4月,シガツ,シガツ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
代々木公園 名詞,固有名詞,地域,一般,*,*,代々木公園,ヨヨギコウエン,ヨヨギコーエン
で 助詞,格助詞,一般,*,*,*,で,デ,デ
花見  名詞,サ変接続,*,*,*,*,花見,ハナミ,ハナミ
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
し 動詞,自立,*,*,サ変・スル,連用形,する,シ,シ
ます  助動詞,*,*,*,特殊・マス,基本形,ます,マス,マス
。 記号,句点,*,*,*,*,。,。,。
EOS

ここでtを「代々木公園」とすると各特徴は下記のようになります。

w[t-2], w[t-1], w[t], w[t+1], w[t+2] = 4月, は, 代々木公園, で, 花見
w[t-1]|w[t], w[t]|w[t+1] = は|代々木公園, 代々木公園|で
pos[t-2], pos[t-1], pos[t], pos[t+1], pos[t+2], = 名詞, 助詞, 名詞, 助詞, 名詞
pos[t-2]|pos[t-1], pos[t-1]|pos[t], pos[t]|pos[t+1], pos[t+1]|pos[t+2] = 名詞|助詞, 助詞|名詞, 名詞|助詞, 助詞|名詞
pos[t-2]|pos[t-1]|pos[t], pos[t-1]|pos[t]|pos[t+1], pos[t]|pos[t+1]|pos[t+2] = 名詞|助詞|名詞, 助詞|名詞|助詞, 名詞|助詞|名詞

で、「代々木公園」に対するラベルは固有表現かつ名詞なので「B-NP」とかになるわけですね。
IOB2といったタグ付け方法が有名っぽいですが他にも色々あるようです(まだ調べてない)。


イマイチ理解仕切れていないのですが、IOB2タグ付けはみなさんどうやっているのでしょうか?
ひたすら目視でタグ付け?尋常ではないくらい大変な作業だと思うのですが、、、
ちなみに、僕が今お世話になっている会社では、データがちょっと特殊なため目視ではなくPythonで自動化できています。


話はそれましたが、これで一つの単語に対し正解データとなるラベルと各特徴量が準備できました。
この処理を各単語について行うことになるわけですが、実際に文章を読み込んで特徴量を作ってみると、元のデータ量はそんなに多くないのに生成してみるとめちゃくちゃデータ量増えるやんけ。。。ってなります。学習よりもfeture generateの方が時間がかかったりします。


次は、crfsuiteをPythonで使えるようにしたpycrfsuiteのサンプルを動かします。

github.com

NLTKに含まれているコーパスを利用しています。
だがしかし、スペイン語

試しにコーパスの一部を翻訳にかけてみると、、、

原文

ElAbogadoGeneraldelEstado,DarylWilliams,subrayóhoylanecesidaddetomarmedidasparaprotegeralsistemajudicialaustralianofrenteaunapáginadeinternetqueimposibilitaelcumplimientodelosprincipiosbásicosdelaLey.

翻訳

国家評議会(Daryl Williams)は、法律の基本原則を遵守することを可能にするインターネットページの観点から司法制度を保護するための措置を講じる必要があることを強調した。

めっちゃ真面目な内容でした。

こんな感じの文章に対して学習と予測をさせるのですが、先ほどのように特徴量を生成しないといけません。
今回のサンプルではword2featuresという関数で実装されています。
おそらく、この部分は分析した文章の性質によっては独自で作ることはできそうです。
ただ、細かくなりすぎるとメンテしづらいんだろうなあ。。。

データの中身を見ながら動かした形跡はgitへあげたので興味のある方はこちらへどうぞ

github.com
ちなみに、NLTKのコーパスを初めて使う際は下記コードを先に実行してコーパスをダウンロードする必要があるので注意

import nltk
nltk.download()



こんな感じでCRFについて勉強中です。
アルゴリズムについてはまた近々まとめるかもしれません。
今のところ、このスライドがわかりやすい気がしてます。

http://2boy.org/~yuta/publications/nlp2006-slides.pdf