自然言語処理勉強会@東京 第1回

id:nokuno さん主催の自然言語処理勉強会@東京にのこのこ行ってきた。
主催者、発表者、参加者、そして会場を提供してくださった mixi さん、みなさんありがとうございました。
こんな機会を自分で作ることは出来ないので、次回も是非何か作って参加したい。


今回は、Conditional Random Fields(条件付き確率場)という機械学習の系列ラベリングの手法を使って、Project Gutenberg や html の本文を抽出する、という試みについて話をさせてもらった。

追記】おっと、そういえば Project Gutenberg はあまり知られていないんだった。著作権フリーのテキストを集めたデータベース。主に英語だが、ドイツ語やフランス語、スペイン語、中国語なども徐々に。海外版の青空文庫といえば多少通りがいい?【/追記



よくわかっている人にはいろいろツッコミをもらえるように、火傷しそうなあやふやなところもあえて踏み込んでいく。
あまり CRF についてご存じない人には、わかんないけどおもしろそう、頑張れば手が届きそう、と感じてもらう。
という狙いでプレゼンを作ってみたが、まあだいたいうまくいったのではないかと。
調子に乗って資料を作りすぎて、50分ほどしゃべってしまったのは減点。


一通り動かして満足できる結果が出たことを確認したくらいのタイミングで、どうやら全く同じようなことをやってそうな論文が見つかってしまった(苦笑)。

[Marek+ 2007] Web Page Cleaning with Conditional Random Fields
http://ufal.mff.cuni.cz/~pecina/publications/wac3-2007.pdf

せっかくここまで自分の考えで進めてきたので、勉強会まではあんまり目を通さないようにしていたが、これから多分読む。
一番乗りではなかったのはちょっぴり残念だが、エンジニアはそんなことではくじけない*1


実は最初は隠れマルコフモデルでやろうと思っていた。github にはそのコードの断片も転がっている。
ふと、研究会とか行くたび耳にする MEMM(最大エントロピーマルコフモデル) や CRF もそろそろやっつけとかないとな、とたまたま思って、McCallum らの MEMM の原論文を読んでみたら、FAQ のラベリングの例が載っていた。いやあのこれって Project Gutenberg の本文抽出 にそのまま使えるんですけど。
さらに Lafferty らの CRF の原論文を読み始めて、こっちのほうが向いてるんじゃあないかという思いをさらに強くしたのが勉強会の2週間前。
そこからいろいろな CRF の論文を読んで、実装して、最低限の学習データを作って、ギリギリ間に合った。ふう。


今回しみじみ実感したのは、Project Gutenberg 本文抽出や Web 本文抽出をドロ臭い方法で作ったことがあるという経験が、素性特徴量の設計において最大に役に立った、ということ。
機械学習では自動でパラメータを決定出来るといっても、最後に物を言うのは対象に対する知識や愛なんだろうなあ。


今回の CRF Python 実装の中身や使い方の説明はこのブログでそのうち(今週……?)。
100KB程度のhtmlのラベリングに3〜5秒かかる Python 実装ではあきらかに実用的ではないので、きちんとしたアプリケーションとするには CRF++ など高速なライブラリを使った実装に置き換える必要があるが、そもそもその前にまずやるべきは定量的な評価(そのためのテストセットの整備)だろう。
地道でめっちゃ時間かかる作業であり、他にもやってみたいことがいっぱいあるので、おいおいということになるだろうなあ。


いただいたツッコミの中では、半教師有り CRF は興味あるな。読んでみたい。


素性は「そせい」と呼ぶのが自然言語処理界隈の習わしで、「すじょう」と呼んだらお里が知れる的なツッコミは、とても勉強になる反面、心のもう片側では強烈に「どーでもいーよそんなのー」とか思ってしまうw。
機械学習界隈で、応用分野によって同じものの呼び方がころころ変わるのには正直閉口していたので、懇親会で示唆をいただいた「特徴量」に個人的には統一していく。
gihyo.jp の連載でもそっちで呼び続ければ、多少は拡散する?

他の方の発表。


FSNLPの1章&2章(id:nokuno さん、@suzuvie さん)。
1章の山場は Zipf 則? "randomly generated text exhibits Zipf's law" で、ほほう! とおもむろスクリプトを書き始めてしまった不真面目な聴講生だったのでw。
2章の確率はなんというか非常に中途半端で、suzuvie さんもとてもやりにくそうだった(苦笑)。
2章の最後の 'nice' な language とやらは、予習で読んでいるときはもうさっぱりわからなかったのだが、勉強会での指摘を聞いているうちに、(2.48) 式は log m(x_1n) の期待値を与えていて、期待値(あるいはその近似値)を与える変数の値がきっとあるはずで、それを 'nice' な language x_1n としてしまえば、(2.49) 式になるということなのかな? と一応言いたいことはわかったつもりになれた。
って、そんな x_1n の存在はわかるとしても、そんな理想的な x_1n なんて取ってくることは出来るわけないのに、そこを気にしない(ように見える)ところは相変わらず馴染めないなあ……


追記】「確率的言語モデル」(黒本?)には、FSNLP が言う 'nice' とは ergodic である場合であり、しかも (2.48) から (2.49) への変形には シャノン・マクミラン・ブライマンの定理を使う、と記してあった。書こうよ……>FSNLP【/追記


ソーシャル検索エンジンAardvarkの論文紹介(id:sleepy_yoshi さん)
なんかこの論文は ちやほやする声が多いのだけど、個人的にはとても気持ち悪い論文だった。
確率モデルのフリをしてるくせに、一番最初に出てくるモデルの最も重要な式でいきなり確率を崩しているし。
p(u_i|t) を求めるのに p(u_i|t)=\frac{p(t|u_i)p(u_i)}{p(t)} で、p(u_i) は一様分布、p(t) はトピックの頻度、っていやいやいや。p(u_i) が一様とかある意味モデルの否定だし、仮に百歩譲ってそうだとしても、p(u_i) を与えた時点で p(t) は正規化パラメータになるので、こっちにトピックの頻度なんて与えたら、p(u_i|t) が確率ではなくなってしまう。
自分一人で勝手に気持ち悪がってるだけなのかな、と不安だったが、id:niam さんも同じ気持ち悪さを感じてくれていたのでよかった。やっぱり気持ち悪いんだ〜。
p(u_i|u_j) を求めるのに、「ありがとう」を言ったかどうか、メッセージの長さ、返事までの早さなどを特徴とする、というのは素直に面白いと思った。自分で似たようなものを作るときはきっと参考にさせてもらう。


LDAでtweetタギング(@PENGUINANA_ さん)。
twitter検索タギングに LDA を使っている、という話は前に聞いたことあって、無教師なのにどうやってラベリングしてるんだろう、手かなあ、と思っていたら、手だった。
モデルに賞味期限があるという話は、Pathtraq カテゴライズでいろいろ身に覚えがあるので、とてもわかるw
あわせて紹介してはった、人種と名前の対応確率とかもおもしろかった。泥臭いの大好きw


#手前味噌だが LDA の R 実装なんてのも。あんまり興味のある人はいないだろうけど。

これのおかげで R の限界を感じて、このタイプの実装には Python/numpy を使ってみることに。

*1:研究者には致命的かもしれないけど……