CRF++の自分用メモetc

論文読んだりしているけど、実際にCRFを動かしたことがなかったり...ということで動かしてみる。動かすためにいくつか理解しないといけないことがあるので自分用メモ。

素性テンプレート

Unigram

まず簡単そうなところから。学習用の入力データがこんな感じになってるとして、3行目を今中心に見ているとしよう。

Input: Data
He        PRP  B-NP
reckons   VBZ  B-VP
the       DT   B-NP << CURRENT TOKEN
current   JJ   I-NP
account   NN   I-NP

このとき、どういうテンプレートを用意しておくと、どういう素性に展開されるかを表にしたのがこれ。

template expanded feature
%x[0,0] the
%x[0,1] DT
%x[-1,0] rokens
%x[-2,1] PRP
%x[0,0]/%x[0,1] the/DT
ABC%x[0,1] 123ABCDT123

論文とかで書かれている形と対応させたほうが分かりやすい気がするので、対応させることを考えてみる。f_v(X, y_t)は例えば

|%x[0,0]|the|

だとX_tが"the"かつY_tが"B-NP"ならば1という素性に展開されるということを表わしている。ここで注意したほうがいいこととしては、f_v(X_t, y_t)ではなくf_v(X, y_t)であるということだ。(HMMや)MEMMではf_v(X_t, y_t)となっていたが、これではlabel biasなどの問題が起こってしまうので、CRFではf_v(X, y_t)というものを考えている。これによって、Xのほうは見ているところに限定されず

|%x[-1,0]|rokens|

のように一個前を見ることもできるし、一個に限らず3個前とか10個後とか見ることもできる。ただ、遠くになると影響が小さくなるし、なんでもかんでも入れすぎると素性の数が無闇に増えてしまうので、前後二つとかが一般的なようだ。そして、Xのほうは自由に前後を見れるだけではなく、2個ペアで見ることもできる。つまり

U05:%x[-1,0]/%x[0,0]
U06:%x[0,0]/%x[1,0]

というような書き方をすることによって、Xのほうのバイグラムを考えることができる(もちろんこっちもY_tのほうも展開されることに注意)。別に単語自身のバイグラムだけではなく、品詞のほうについて考えることもできて、かつトライグラムのようなこともできる。次のような例はまさにそれだ。

U20:%x[-2,1]/%x[-1,1]/%x[0,1]
U21:%x[-1,1]/%x[0,1]/%x[1,1]
U22:%x[0,1]/%x[1,1]/%x[2,1]

Bigram

This is a template to describe bigram features. With this template, a combination of the current output token and previous output token (bigram) is automatically generated. Note that this type of template generates a total of (L * L * N) distinct features, where L is the number of output classes and N is the number of unique features generated by the templates. When the number of classes is large, this type of templates would produce a tons of distinct features that would cause inefficiency both in training/testing.

http://crfpp.sourceforge.net/

とあって、UnigramだけだとN個の素性だけだが、Bigramになるとoutputのほうのbigramを見るので、L^2倍素性関数が増えてるということになる。この場合、X(の部分集合)がなんとかというのもあるのだが、「y_{t-1} = Aかつy_t = B」のようなことを考えるので、ラベルの二乗に比例した数の素性関数ができる、ということである。"Here, unigram and bigram features mean uni/bigrams of output tags."と書いてあって、Bigramをかを見るのはword-levelのBigramではなく、output tagsに関してのBigramである。Bigramを考えると素性の数は結構増えてくるので、注意が必要。こういうこともあって、CRFとかMEMMでは素性マイニングと呼ばれる泥くさい作業が必要不可欠?

Bigramのテンプレートのほうは、Unigramのほうを勝手に展開してくれるようなので、"B"と書いておけばよいらしい。

オプション

-a CRF-L2 or CRF-L1

正則化のオプション。過学習を避けるために。L2のほうが一般的にはパフォーマンスがよいが、0に縮退しないパラメータがいっぱい残ってしまう。L1だとスパースな解を得ることができる(よってモデルサイズを小さくできる)。

-c float

正則化項についている係数。Cを大きくするにつれてoverfitするようになる。丁度よいCの値はcrossvalidationとかで頑張って。

-f NUM

一回しか登場していない単語とかを素性につっこんでしまうとモデルが不安定になってしまいがち。そこで、登場回数の少ない素性はそもそも追加しないようにしようじゃないかというオプション。NUMがその足切りの数。ディフォルトでは1になっている。

-p NUM

CPUをいくつか持っているようなCPUだったらマルチスレッドを使って学習を高速にできるらしい。学習のどの部分が並列に走らせられるんだったか確認しておかないと。。。


FAQ

  • 全部の文字が大文字であるとか最初の文字が大文字からなる、というようなものは素性に入れられないんですか?
    • 入れられます。それ用の列を用意しておいて、%x[0,2]のようにやるとマクロがちゃんと展開してくれます

調べないといけないこと

  • Bayes Point Machinesによる学習(Corston-Oliver et al. 2006)やマージン最大化法(MIRA)などについても調べる
    • "-a"のオプションにMIRAとかがあるので

参考

言語処理のための機械学習入門 (自然言語処理シリーズ)

言語処理のための機械学習入門 (自然言語処理シリーズ)