2009.07.04

netflix prize is over, 時間経過による嗜好性の変化

米国のオンラインDVDレンタルサービス「Netflix」が、現在利用しているレコメンデーションシステムの性能をはじめに10%改善したチームに100万ドルの賞金を与えるという触れ込みで始まったnetflix prizeは当初の予想よりも時間がかかったが、つい最近最初からトップを走り続けていたbellkorと、上位陣のコラボレーションのチームが10%の壁を破った(leaderboard)。

彼らの手法は「非常に多くの様々な種類のレコメンデーションシステムの結果を混ぜ合わせる」という愚直だがいかにも精度が出そうだという方法を採用している(、と昨年度の結果からは思われる。近々詳細は出るだろう。)

実際に使ってとどめになったかどうかは分からないが、彼らのチームの主要メンバーがKDDで新しい手法を発表しており、単一の手法による最高精度を達成している。ちなみに今年のKDD(データマイニング系の学会の最高峰の一つ)のBest Research Paperである

Yehuda Koren, "Collaborative Filtering with Temporal Dynamics ", KDD 2009 pdf

これは時間経過による嗜好性の変化をモデルに組み込んだものである。

協調フィルタリングによるレコメンデーションを行おうと思うと時間経過による様々な変化がある。例えば、ある人の嗜好性が連続的に変わる、もしくはある商品に対する評価が連続的に変わるということもあるし、ちょっと面白い例で、一つのアカウントを家族で使う状況だと、ある日はお父さんが使っていて、次の日は娘が使う場合があり、この場合だと、アカウントだけをベースにみていると嗜好の傾向が非連続的に変わることになる。

この嗜好の時間変化についてはずっと昔から多くの人が取り組み、利用してきたがどうもうまくいかなかったものだが(グラフの変化、テンソルでとらえるような研究も多い)、この研究では、まず単純に時間経過情報を入れただけではうまくいかないというところからスタートして、様々な工夫を入れている。最終的に高い精度を達成した手法では、人毎、商品毎のbias項、人と商品の隠れ項の部分に時間変化の影響を入れており、緩やかな場合の変化をスプライン関数で捉え、さらに連続的ではない急激な変化を1日毎のログを別に加えることで捉えている。

この論文で特に面白かったのが6章から始まる結果の分析であり、様々な時間経過による指向性の変化を仮説を立てて調べている。2004年頃に全体のレーティングが非連続的に上がるという現象がみられ、さらに古い映画の評価が新しい映画の評価よりも高くなるという現象がみられている。

分析の手法は実際に論文を読んでもらうとして、結果、分かったのは、2004年頃にnetflix自身が提供しているレコメンデーションシステムのcinematchの精度が向上し、GUIもよくなったおかげでユーザーがより自分の嗜好にあった映画を見られるようになったということである。さらに、新しい映画はなんとなく流行りだから見ている場合が多いのに対し古い映画はレコメンデーションシステムによってお勧めされたものが多いので古い映画の評価が相対的に高いことが起きたらしい。

10%の性能改善という絶妙な目標設定とともに、最終的にnetflix社のcinematchがユーザーの満足度を上げているのに成功したということが証明された形でnetflix prizeが終わりを迎えることで、netflixすごいなとおもいました。

| | Comments (3) | TrackBack (0)

2009.07.03

Burrows-Wheeler変換の線形時間アルゴリズム

研究紹介です。今夏のSPIRE 2009という学会で

"A Linear-Time Burrows-Wheeler Transform using Induced Sorting", D. Okanohara, K. Sadakane, SPIRE 2009 pdf(draft)

というのを発表します。これは与えられた文字列に対し接尾辞配列を経ないでBurrows-Wheeler変換を直接行うというもので、アルファベットサイズによらず入力長に対して線形時間で行えます。基本的なアイディアは昨年のInduced Sortingによる接尾辞配列の線形時間構築アルゴリズム(いわゆるSAIS)を接尾辞配列を使わないでシミュレートするものです。pushとpop操作だけからなり、そのまま外部記憶上での構築とかにも対応できるようになっています。

Burrows-Wheeler変換(BWT, Block Sortingとも呼ばれるen-wikipedia)は、94年(発見自体は80年代)にBurrows, Wheelerらによって提案された文字列の可逆変換であり、データ圧縮、全文検索、データマイニングなど広い分野で使われる変換手法です。なにか大規模な文字列処理をするなら、とりあえずBWTをかけとけば大抵楽に処理できます。

--
今回の論文の位置づけを示すために、文字列処理用のデータ構造の歴史的背景とかを書いてみます。

まず、接尾辞木(Suffix Tree, ja-wikipedia)が1973年にWeinerによって提唱されます。接尾辞木は次のように作られます。まず長さnの入力文字列T[1, n]に対し、i文字目からj文字目までの部分文字列をT[i, j]で表すとします。この時、Si = T[i, n]をTのi番目の接尾辞と呼びます。入力Tには全部でn個の接尾辞があるのですが、この接尾辞それぞれをキーとしたtrieを作ります。次に、子が一つしかない節点を取り除き、更に文字列を枝上でそのまま持つ代わりに、葉に何番目の接尾辞に対応するかの情報を格納すると共に、各節点には深さ情報のみを記録するとします。するとT中に出現する全ての部分文字列はO(n^2)個あるのですが、節点の数は高々n個で、さらに葉の数もn個しかないようなコンパクトなデータ構造ができます。これが接尾辞木です。接尾辞木を利用することで非常に多くの様々な文字列処理を高速に行えることが知られています
(suffix treeを利用した様々なアルゴリズムについては有名なGusfield本にいろいろ書いてありますAlgorithms on Strings, Trees and Sequences: Computer Science and Computational Biology

こうしたデータ構造は、大量のデータ(30億文字かならるヒトゲノムとか)を扱うことが主な目的なので、高速に構築できることが重要になります。接尾辞木も提案されてから様々な手法が提案されてきました。様々な改良が重ねられた後に、95年 Ukkonenによってアルファベットサイズが定数の場合の現実的な線形時間アルゴリズムが、97年にFarachによって任意のアルファベットサイズに対する線形時間アルゴリズムが提案されています。

接尾辞木は非常に強力なツールなのですが大きな問題がありました。それは接尾辞木を保存するのに必要な作業領域量、つまりメモリを非常にたくさん必要とすることです。入力サイズに対し(ポインタのサイズが定数の場合)線形のサイズとはいえ効率的な実装でも入力長に対し数十倍のメモリが必要とされてました。

こうした問題を解決したのが91年にManberらによって提案された接尾辞配列(Suffix Array)です。これは接尾辞木の葉の部分のみを使ったもので作業領域量を入力長*ポインタサイズ(普通は4バイト)と大幅に減らすことに成功しました。接尾辞配列を正確にいうと、入力Tに対し、接尾辞配列SA[1, n]をT[SA[i], n] < T[SA[i+1], n]が全ての1 <= i < n-1に対し成り立つような配列と定義されます(文字列間の<は辞書式順序とする)。SAを使えば、接尾辞が辞書式順序に並んでいるので、ある文字列qを検索したい場合にはT[SA[l], n] <= q <= T[SA[r], n]が成り立つようなl, rを二分探索で求めることでqの出現場所を全て発見することができ、SA[l, r]がqの出現場所であり、r-l+1がqの出現回数となります。任意の文字列に対しO(log n)時間で検索できるデータ構造が約5n byte(入力文字列n + 接尾辞配列4nバイト)で保持できるということになります。

大幅に作業領域量を減らすことに成功した接尾辞配列でしたが、構築時間が大きくなるという問題がありました。接尾辞木を最初に作り葉の部分だけを回収すれば線形時間で構築できるのですが、結局作業領域量が大きくかかってしまいます。接尾辞木を経ないで接尾辞配列を直接構築するには、接尾辞を辞書式順序にソートする必要があり、最悪計算量がO(n^2 log n)かかるという問題がありました(入力にT = aaaaaa...a$というものを考えた場合、毎回の比較にO(n), 比較回数にO(n log n)かかるため)。この構築時間は97年に定兼先生によってO(n log n)に改善され、2003年には接尾辞配列を直接線形時間で構築するアルゴリズムが3つ同時に提案されます。その後もさらに高速な構築アルゴリズムが提案されていき、現在の構築時間では1秒あたり4~8MB程度構築できるようになっています(ベンチマーク@white page

接尾辞配列と大体同時期にBurrows Wheeler変換というものが提案されました。これは入力T[1, n]をB[i] := T[SA[i]-1](SA[i]=0の時はB[i]=T[n])で定義される文字列B[1, n]に変換するというものです。
この変換は一見すると直感的ではありませんが、非常に重要な性質を持っていることが分かっています。代表的なものを三つあげると、

(1)可逆変換である

BW変換後のB[1, n]のみから入力文字列T[1, n]に戻すことがO(n)時間で可能です。これはLF-mappingと呼ばれるものを利用します。B[i]=cに対応する接尾辞はrank(B, i, c) + C(c)番目にあるというものです、但しrank(B, i, c)はB[1, i]中のcの出現回数、C(c)はB中のcより小さい文字の出現回数です(つまりT中と言い換えても同じ)。(実際の逆変換のコードはC++20行弱程度で例えばpdfの20枚目あたりにあります)

(2)元の入力が圧縮しやすい場合、BW変換後は同じ文字が連続して出現しやすい

Bは定義より、各文字をそれに後続する文字列をキーとしてソートした結果となっています。よって似た文脈の直前に同じ文字が出現しやすいのであれば、Bでは連続して同じ文字が出現することになります。例えば英語では"the"が頻出するので"he .."の文脈の直前には"t"が出現しやすくB中でも"t"が連続して出現するようになります。

この直感は様々な形で解析されています。まず圧縮しやすいというのは(k-1)文字を見たら次の文字は非常に予測しやすいということでいえて、これはHk(k次経験エントロピー)という数値で測ることができます。そして、BW変換後は文脈情報を全く無視して先頭移動法などローカルな情報だけを使って符号化してもその後のサイズがHkに漸近することが知られています("A simpler analysis of Burrows-Wheeler-based compression, H. Kaplan., and et. al.pdf

(3)(圧縮)全文検索に利用できる

元々データ圧縮用に作られたBW変換は、2001年にFerraginaらによるFM-indexと呼ばれるデータ構造によって全文検索に利用できるということが分かりました。BW変換の定義には接尾辞配列が使われているので接尾辞の情報が入っているのですが実際にこれを、LF-mappingの性質を使うことで全文検索ができることが示されました。
このFM-indexではLF-mapping、つまりはrank(B, i, c)を求める必要があり、FM-indexが最初に提案された時には、この部分の効率的かつ高速な計算の実現が困難でした。それが03年にGrossiらによって提案されたwavelet treeを使うことで高速に行うことができ、現在ではFM-indexはテキスト長に依存せずクエリ長に比例する時間で全文検索が行えます。しかも必要な作業領域量はBと同じだけのスペースなので約nバイトで済みます。

詳細を追うことはやめておきますが、最長共通接頭辞配列や、木を表すテーブルと組み合わせることで接尾辞配列(拡張接尾辞配列、Enhanced Suffix Arrays)やBWTは接尾辞木と同じように複雑な文字列検索を行えることがわかっています。

ここまでの流れを追うと、文字列処理用のデータ構造は、効率的に操作できる能力を変えずにどんどんコンパクトになってきていました。

- 接尾辞木 1973年 O(n log n)、元文書の約20倍でヒトゲノムの場合は約50GB
- 接尾辞配列 1991年 n log n 、元文書の約5倍でヒトゲノムの場合は約13GB
- BW変換 1994年(2001年)、nHk、元文書の等倍以下でヒトゲノムの場合は約750MB

また、それらのデータ構造を直接高速に線形時間で構築するようなアルゴリズムも提案されてきました。今回の発表はこの流れに沿うものになってます。

線形時間の構築
- 接尾辞木 Ukkonen 1995年、Farach 1997年
- 接尾辞配列 Aluruなど 2003年
- BW変換 今回の 2009年

さて、今後もこの流れは続くかですが、コンパクトになっていく流れは、このままでは難しいといえます。すでにBW変換は元の文書を圧縮したサイズに近いサイズまできています。全文検索において、任意の部分文字列に対し正しい結果が得られるということは、元の文書を復元できるということを意味しているので、データ圧縮とやっていることは同じです。ですので、元の文書が持っている情報を捨てない限りはこれ以上小さくするのはかなり難しいと思われます(もしできたらデータ圧縮においても革命)。結果の正確さを100%ではなく、何らかの形で保障しながらサイズを劇的に減らす方向については十分ありうると思います。

それに対し、構築時間については、理論上は線形時間よりは速くするのはちょっと大変そうですが、実際には改善が続けられています。今回提案した手法も実装に落すところでは更に工夫が必要です(その実験/論文はそのうち)。実装以外にも例えば接尾辞配列において並列に計算するような方法や、検索時間を犠牲にして構築時間を減らすような方法もでています。秒間数MBを処理できるとは数年前から比べたら各段の進歩ですが、今流行りのマイクロブログのリアルタイム検索などを実現しようと考えたり、もうすぐ実用化されると噂される次々世代シーケンサは秒間1GB超という速さでゲノム配列を読めるということで、まだまだ改良しなければならなさそうです。

| | Comments (0) | TrackBack (0)

2009.06.07

NAACL/HLT 2009報告

コロラド・ボルドーで開催されたNAACL/HLT 2009に行ってきました。
NAACLは自分の中での分類では自然言語処理の学会で統計的な手法とかが多い学会に思える(それに対しヨーロッパではEACLでは文法とか言語理論とかが多い)。比較的自分にあう学会。

開催地となったコロラド大ボルダー校はとてもきれいなキャンパスで(、「全米で最も美しいキャンパス」の4位にランキング)、宇宙飛行士をたくさん輩出してたり、ノーベル物理学賞を4名輩出するなど、研究レベルも高いそうです。

で、学会は適当に休みながらまったり聞いていたのですが全体的に教師無学習に関する話が多かったような気がします。教師有学習による言語処理がある程度成熟してきているのに対し、教師無の方はまだまだ伸びしろが多いので研究がしやすいのでしょう。教師無に利用するモデルも、単純な混合分布から、様々な分布が入り乱れる複雑なグラフィカルモデルになって精緻なモデル化ができるようになって理論的にも面白いのだとおもいます。

自分の発表(組み合わせ素性の自動抽出)は、素性設計をやったことがある人にはよく共感してもらえました。

聞いた発表の中で面白かったものをいくつか挙げます

* Shrinking Exponential Language Models, Stanley F. Chen. [pdf]
* Performance Prediction for Exponential Language Models, Stanley F. Chen. [pdf]
(Technical Reportが手に入る pdf)

指数分布族(いわゆる最大エントロピーモデルによる言語モデル)による言語モデルで、訓練データ上のパープレキシティとその時の重みの絶対値の和でテストデータ上のパープレキシティが恐ろしいほどの精度で予測できるということを示した。様々なデータ、パラメータで試したらなぜかうまくいく式を発見したらしい。テストデータ上での性能を予測する手法はMDLやらAIC、VC理論などがあるが、ここまでぴったり当てはまるのは初めて。本人もある程度の考察をしていたがここまであてはまるのは、正直困ったといっていた。

二つ目の論文では予測できるということで、テスト上のパープレキシティが下がるような言語モデルをうまく設計できればいいのではということで実際に設計した。スムージングとかの効果が「異なるN-gram上の重みを共有している」ことで全体の重みの相和が減ってテスト上のパープレキシティが減るということが示されていた。

普通のMEとかでもこの式は使えるのだろうかなぁ・・

この人は元々Rosenfeldの元でExponential Language Modelをやっていて、Gaussian PriorをMEに使うことを最初に提唱したりした人。久々にでてきた気がする。

* Improving Unsupervised Dependency Parsing with Richer Contexts and Smoothing, William P Headden III, Mark Johnson and David McClosky [pdf]

教師無係り受け解析で最高精度を達成。実はこれと殆ど同じ手法を自分も昨年しばらくやっていて、精度でなくてあきらめていたので、その延長線上にいい世界があったのかとちょっとショック

- 基本的には係り受けのモデルをsplit-headによるPCFGに変換
- PCFGのモデルでは品詞と単語を線形補間でスムージング
- 右側(左側)にかかるときに一回目にかかるものと二回目にかかるものを分けてモデル化
- 基本的にEMで推定するが、分布に対してDirichelt Priorをかけて, 変分ベイズで推定
- 初期化をものすごくたくさん試し、よさそうなものをさらに収束するまでずっと繰り返す

上三つまでは自分やっていたが、下二つ(特に最後)が結構きくらしい。これで70%ぐらい達成

* Online EM for Unsupervised Models, Percy Liang; Dan Klein [pdf]

これは以前紹介したOnline EM(ohmmというオープンソースもだしました)の本発表。発表で面白かったのがOnline EMで学習した方が従来のEMよりも(尤度は同じだが)高精度を達成する場合が多いということだ。彼の説明ではOnline EMにはいい山を見つける能力が高いのではないかということ。学習の形からみれば焼きなまし法で温度をさげていくのに確かに似ている。

* Unsupervised Morphological Segmentation with Log-Linear Models, Hoifung Poon; Colin Cherry; Kristina Toutanova pdf

教師無での形態素分割について、線形対数モデルを使って自由に特徴を利用した場合に精度はすごくあがったという話。Semi-Markov MRFに近い。best paper(student best paper)

ちなみにもう一つのbest paperは
* 11,001 New Features for Statistical Machine Translation, David Chiang; Kevin Knight; Wei Wang [pdf]

タイトルがなんか格好いいが、従来のblue scoreとモデルの調整でOchの最適化法を使うより、MIRAとかで学習すると特徴数が非常に多くても学習できるし、精度もいいよという話。

* Joint Inference for Natural Language Processing, Andrew McCallum (CoNLL Invited Talk)

非常に複雑なグラフィカルモデルで学習を行いたい場合はsample rank(彼の学生のCulottaのthesis)というのがお勧めだというのが印象にのこった。これはMetropolis-HastingsによるMCMC法で変数をいろいろ変えていく際にモデルのパラメータ変化と、実際の確率の変化が違う場合にパーセプトロンのように、変化が同じになるようにパラメータのアップデートを行うもの。実装が簡単なうえに学習の効率が高いらしい

| | Comments (0) | TrackBack (0)

2009.05.25

貪欲な変数選択による最適化

最適化問題において、最適化対象の変数を最初は空に初期化して、関数値にもっとも効きそうな変数から順に最適化対象にGreedyに加えていく方法は変数の数が非常に多い場合(全ての部分文字列に特徴が対応するなど、そもそも列挙できないくらい多い場合など)に有効です。

詳細な中身は違いますが、grafting, column generation, cutting planeとかがこの枠組みに当てはまルと思います。

ここでのポイントは「効きそうな変数」を効率的に求めることができたら、圧倒的に速く最適化できるようになることです。別分野でデータマイニングの手法だとか、上限/下限だとかデータ構造とか何か技を持っている人は、ぜひチャレンジしてみてください。

で、私もやってます。という宣伝

・特徴(変数)が文書中の全ての部分文字列に対応する場合
"Text Categorization with All Substring Features", SDM 2009, D. Okanohara, J. Tsujii [poster(ppt)]

・特徴が基本素性の全ての組み合わせの場合
"Learning Combination Features with L1 Regularization", NAACL HLT 2009, D. Okanohara T. Tsujii. to appear

あといくつかできそうなのですが、実装が追い付かない。

とりあえず上の二つは今のライブラリに組み込む形などで公開したいとおもいます

| | Comments (0) | TrackBack (0)

2009.05.19

ohmm(オンラインEMによるHMM学習)をリリースしました

Ohmm-0.01をリリースしました

[Ohmm 日本語] [Ohmm English]

これは、以前のブログで書いた、オンラインEM法をそのまま素直に隠れマルコフモデル(HMM)に対し適用したライブラリです。

使う場合は、単語(アクセス履歴とかなんでもよい)に分けられているテキストを入力として与えれば、HMMによる学習を行い、結果を出力します。他で利用できるように、パラメータを出力したり、単語のクラスタリング結果を出力します。

HMM自体は、言語情報やアクセス履歴、生物情報(DNA)といったシーケンス情報において、前後の情報を用いて各要素をクラスタリングしたい場合に用います。

本ライブラリの特徴はオンラインEMの特徴通り、従来のEMよりも速く収束します。一応標準的な最適化手法(スケーリング、スパースな期待値情報の管理)もいれているので、そこそこ高速に動きます

速度的には100万語、隠れ状態数が40ぐらいで1回のループが10秒程度です。正式な実験ではないですが1億語ぐらいまでが一台で1~2時間ぐらいで収束します。

歴史のある隠れマルコフモデルはいろいろな変種があるので、それらも暇なときに実装しようかなと思います

| | Comments (0) | TrackBack (0)

2009.04.25

部分文字列の話

ここしばらく、部分文字列の統計量を利用した機械学習やデータマイニングをやっている。そこの話からちょっと抜粋。

長さnの文字列T[1,...,n]が与えられた時、T中に出現する部分文字列T[i...j] (1≦i≦j≦n)の数はn個の中からiとjの2箇所を選ぶのでO(n^2)個ある。例えば、n=10^6(1MB)だったら、部分文字列の数は約10^12個(1T)と非常に大きい。

しかし、これらの部分文字列の出現位置は同じである場合が多い。例えばT="abracadabra"であれば、"abra"と"abr"の出現場所は1番目と8番目であり、全く同じである。

では出現位置(部分文字列の左端を出現位置とする)が全く同じであるような部分文字列をまとめてグループにした場合、グループの数はいくつになるのだろうか。

これは接尾辞木(wikipedia 授業の資料)を知っているなら簡単に説明できる。

Tに対しT[i,...,n]、つまり頭の文字を削った文字列、をTの接尾辞と呼ぶ。この接尾辞から構築したtrieに対し、子が一つであるような節点を文字を残したまま取り除いて枝にしてしまったものが接尾辞木である(正確には接尾辞木のスケルトン。実際にはsuffix linkとかつける)。各葉には、接尾辞の出現位置を記録しておく。

この接尾辞木において、節点に対応する部分文字列の出現位置は、その節点の子孫の葉の集合に対応する。枝の途中に対応する部分文字列の出現位置も、その先の節点の出現位置と同じであり、同じ枝に対応する部分文字列の出現位置は同じである。

この接尾辞木の節点の数は、接尾辞を一個ずつ加えて接尾辞木を構築する過程を考えると、各追加で、高々一つしか節点は増えないので、高々n-1個である。

一回しか出現していない部分文字列のグループは、接尾辞木中の葉に隣接する枝に対応し、二回以上出現している部分文字列のグループは節点と節点の間の枝に対応している。葉の数は接尾辞の数と同じなのでn個。よって、グループの数は(葉の数)+(節点の数) = 2n-1、二回以上出現しているグループの数はn-1個と分かる。

最初の問いに答えると、部分文字列の数はn^2なのに、それらをまとめると高々n個しかない。ものすごく少ないことがわかる。

さらに、これらの極大部分文字列は左側に伸ばした場合の冗長も考えるとさらにまとめることができる。(たとえば先ほどの例はbraとabraの出現位置もおなじ)。

こうすると例えば、さっきの例のTにおける極大部分文字列で二回以上出現しているものはaとabraのみである。

では、実際にこれらのグループに対応する部分文字列(極大部分文字列)を取り出すにはどうすればいいのか。接尾辞木を構築するのが一番直感的だが、接尾辞木のサイズは非常に大きい。

現在では接尾辞配列と共通接頭辞配列を組み合わせて、線形時間で求めるのが一番手っ取り早い。
接尾辞配列の線形時間はSAISとか使えばできて、線形時間での共通接頭辞配列構築と、それを利用した極大部分文字列の列挙は[pdf]中の論文の疑似コードをそのまま書けばできる。左側の冗長性に関してはBWT配列に関するrankを使えば全部トータルでも線形時間で極大な部分文字列を求めることができる(ちょっと面倒なのでやらなくてもいいが)。

これでテキスト長が10億文字ぐらいになっても10分程度で全ての極大な部分文字列を抜き出すことができる。

出現位置がまとめられたらいろいろ使いどころはある。例えば、私が今やっている全ての部分文字列を利用した文書分類では、全ての文書をつなげた文字列から極大部分文字列を抽出し、そこから各部分文字列に関する統計量(尤度の微分とか)を効率良く計算することができている。

ちょっと毛色の違う例として、例えば、アクセスログのパターンを解析をする場合を考えてみる。ログデータとして、アクセスしたサイトの記録がセッション毎に残されているとする。各セッション中に含まれるサイト数の平均が約百で、サイトの総種類数が1万、セッションが1000万回分記録されているとする。ここから10回以上出現しているアクセスパターン(サイト列)を、そのパターンの長さを問わずに抽出しろというお仕事があったとする。

見積もろうとすると、まず全通りのパターンを力づくで記録するのは、長さ2のアクセスパターンで1万×1万=1億通りのパターンがでる可能があるので長さ10とかはまず無理である。
ちょっと考えて、実際に出現したパターンをハッシュとかで記録して求めようとすると、各セッション毎に一万個(百×百)のアクセスパターンを記録する必要があり、合計で1000億個のアクセスパターンを記録する必要がある。とてもメモリに載らないので10台ぐらい必要、もしくはDBとかでガリガリで1日ぐらいかかるのではないかということになる。まず長さを切ってしまうだろう。

この場合のスマートな回答は、全てのセッションをつなげた長い配列を作り、そこから極大部分文字列を抽出し、10回以上出現する極大部分文字列のみを報告すればよい(極大部分文字列に含まれる部分文字列は全て頻出)。このときセッションを跨いだパターンを抽出しないようにセッション間には特殊文字をいれておけばよい。これらの特殊文字は全て違うものにしといてもよい。こうすると文字種類数も数千万となるが今の接尾辞配列構築アルゴリズムの計算量はアルファベット数には依存しない。1台のマシンでしかも10分程度で漏れなくパターンが抽出できますよといえば、驚かれるかもしれない
(実際できる見積もりを、そのまま言っていいかどうかは、また考える必要があるが)。

| | Comments (0) | TrackBack (0)

2009.04.16

オンラインEMアルゴリズム

EMアルゴリズム(Expectation Maximizationアルゴリズム、期待値最大化法、以下EMと呼ぶ)は、データに観測できない隠れ変数(潜在変数)がある場合のパラメータ推定を行う時に有用な手法である。

EMは何それという人のために簡単な説明を下の方に書いたので読んでみてください。

EMのきちんとした説明なら持橋さんによる解説「自然言語処理のための変分ベイズ法」や「計算統計 I―確率計算の新しい手法 統計科学のフロンティア 11」が丁寧でわかりやすい。

EMは教師無学習では中心的な手法であり、何か観測できない変数を含めた確率モデルを作ってその確率モデルの尤度を最大化するという枠組みで、観測できなかった変数はなんだったのかを推定する場合に用いられる。
例えば自然言語処理に限っていえば文書や単語クラスタリングから、文法推定、形態素解析、機械翻訳における単語アライメントなどで使われる。

EMは大量のデータを使えば使うほど精度があがり、しかもデータは教師無でよいので事実上使い放題である。結果として計算量は大きくなる。

EMはMap Reduceの枠組みでの大規模並列化しやすいのが知られているが[pdf:chu nips2006] [pdf:Wolfe icml2008]、それでも重い。
で、高速化の話がちらほらでていたが、教師有のオンライン学習のように、データ毎に更新してもうまくいくという研究報告がでてきた。

"Online EM for Unsupervised Models", [pdf] P. Liang D. Klein, NAACL 2009 to appear

期待値を求める部分で、全てのサンプルを使って求めるのではなく
(1) Incremental EM (iEM), 今の期待値の計算部分の、各データに対応する部分を一個ずつ取り替えていく
(2) Stepwise EM (sEM), 期待値の計算部分を、確率的に近似し(確率的勾配法に似ている)、今持っている期待値を補間をとりながら更新していく

の二通りで近似する。どちらも実装は単純であり、データ数に比例する計算量で行える。
ただ、iEMは全てのデータを保存しておかないのが問題であり、sEMではそれは必要なく、必要な作業領域量はデータ数に依存せずスケーラブルである。ただ、sEMの場合確率的に近似する部分でのステップ幅の設定が必要である。だがそれも彼らの実験結果によれば、大部分でロバストに動くらしい。

実験では品詞推定、単語分割、機械翻訳における単語アライメントで試しており単語分割などにおいて2回ぐらいで収束し(バッチだと10回ぐらい)、品詞推定の場合では20回ぐらい(バッチだと100回ぐらい)で収束し、大体バッチEMと同程度の精度が達成可能である。

これによる簡単な拡張も考えられるだろう。
例えば、EMにおいて、期待値を求める部分で、そのままの値を使わずに定数を引いたものを使って期待値を求めれば、Dirichlet Processの平均場近似と同じ効果が得られることが知られている([pdf:percy ACL tutorial 06])。これと同じことをオンラインEMでやろうと思えば、ちょっとずつ値を引けばいいだろう。


以下EM法の解説。自分で書いていていろいろ思い出した。
--
はじめに多項分布の最尤推定からはじめる。箱の中に赤、青、黄の三色の球がそれぞれ何個か入っていて、これらの数を推定したい。実際に100回試しにとってみて(毎回球は戻すとする)、赤、青、黄の数がそれぞれ50個、20個、30個だったとすると、直感的には箱の中の球の割合はそれぞれ0.5、0.2、0.3であると推定される。この推定は最尤推定といって、実際に観測した事象が最も起きやすい割合がこうだから、そう推定しているのである。数式で書けばパラメータθ(今回これは球の割合)を推定するにあたり、観測した事象Xの確率p(X|θ)を最大にするようなθを求めるのが最尤推定である

(これに対し、p(θ|X)を最大にするようなθを求めるのは、ベイズの定理よりp(θ|X) = P(X|θ)P(θ)/P(X)であり、P(X)はθに依存しないので、結果としてP(X|θ)P(θ)を最大にするようなθを求めればよい。P(θ)はθに対する事前分布であり、大抵、「こういうθがいいなぁ」と人が決める。この推定を事後確率最大化推定、MAP推定と呼ぶ)

先ほどの場合の最尤推定を真面目にしてみると、箱中の赤、青、黄が入ってある割合をそれぞれp(r), p(b), p(y)とした時、観測された事象の確率(組み合わせ数は無視)p(r)^50 * p(b)^20 * p(y)^30を最大にするのはp(r)=0.5, p(b)=0.2, p(y)=0.3の時なので、そう推定しているのである(a^bはaのb乗)。きちんと求めようと思えば、これの対数をとってp(r)+p(b)+p(y)=1の拘束条件をとって、最大化をラグランジュの未定乗数法を使って求めればでてくる。

#多項分布の場合の最尤推定は人間は自然にできるので、当たり前だといわれるが、まじめにやると結構大変

次に、箱が二つある場合を考える。それぞれの箱には違う割合で赤、青、黄の球が入っている。
一回の試行では、ある確率pで片方の箱を選び、(1-p)で違う方の箱を選ぶ。そして次にその箱から球を10個取り出す。

この試行を6回繰り返した時の、それぞれの赤、青、黄の数は以下のようであったとする。しかし、どちらの箱を選んだのかは分からない。

1回目 (2, 5, 3)
2回目 (7, 2, 1)
3回目 (2, 7, 1)
4回目 (1, 6, 3)
5回目 (2, 4, 4)
6回目 (7, 1, 2)

このような中でパラメータ(どちらの箱を選ぶかの確率p、及びそれぞれの箱の中の球の割合)を求めることを考える。

例えば、ウェブページのセッション毎のアクセスログがあり、各ページへのアクセス回数を記録していたとする。データを見ているとどうやら男性と女性のグループでアクセス傾向が違うと思われるのだが、それぞれのセッションでは男性か女性か分からないような場合を想定してほしい。こんな中でもそれぞれのアクセスがどっちで、それらのがどんなウェブページかを推定したいのが今回のケースにあたる。

このデータをよくみてみると、片方の箱には青が多めに入っていそうであり(1,3,4,5回目)、片方の箱には赤が多めに入っていそうである(2, 6回目)。そして、箱を選ぶ確率pはなんとなく4:2なので4/6になりそうである。この直観を最尤推定できちんとみてみる。

i回目に選んだ箱の番号をzi={A,B}で表すことにする。箱ziを選ぶ確率をp(zi)とし、p(xi|zi)を箱ziを選んだ時にxi=(r,b,y)個の玉の組み合わせが出てくる確率とする。この時の尤度p(X,Z)(X=x1,x2,..x6, Z=z1,z2,...z6)は
p(z1) p(x1|z1)
* p(z2) p(x2|z2)
...
* p(z6) p(x6|z6)
である。これが最大になるようなパラメータを求めたい。

しかし問題は、毎回どちらの箱を選んだか、つまりziが分からないことである。そこで、(少々強引だが)両方確率的に選んだと考える。つまり、p(z1) p(x1|z1)の代わりにp(A) p(x1|A) + p(B) p(x1|B) を尤度と考え、最大化する。p(x1, A) + p(x1, B) = P(x1)であり、P(X)を最大化していると考えられる。

{ p(A) p(x1|A) + p(B) p(x1|B) }
* { p(A) p(x2|A) + p(B) p(x2|B) }
...
* { p(A) p(x6|A) + p(B) p(x6|B) }

この確率を最大化するパラメータp()を求めたい。尤度の対数を計算することにすると次のL(X)を最大化するパラメータを求める最適化問題を解くことになる。

L(X) = ∑_{i} log ∑_{z} p(xi,z)

厄介な点は、対数の中に和の計算があることである(対数をとらなければいいと思えるが、乗算系の最適化は更に困難)。一般に、観測できない事象がある中で最尤推定したい場合には、このような対数の中に和が入る形になる。

で、ようやくEM。EMはこのような場合の最適化法である。オリジナルの場合のEMはQ関数が出てきてややこしいのだが、今回の多項分布のような場合は非常に簡単な計算になる(一般的には確率分布が指数型分布族の場合に簡単になる)

EMは次の方法で、L(X)が大きくなるようなパラメータを求める。ただし、L(X)が最大になるとは限らない。

---
1)パラメータの初期値を適当に設定する
2)次のE, Mステップを収束するまで交互に繰り返す。
Eステップ 今のパラメータでの、各潜在変数ziの期待値p(zi|xi)を求める
Mステップ この期待値を重みとして使って対数尤度(logP(X,Z))を最大化する
---

直感的にはEステップで今のパラメータを使った場合に、i番目のサンプルでziが使われた可能性はどれくらいかを求め、Mステップで先ほど求めたziを信じて尤度を最大化している。

EMはL(X)の下限を最大化しているのに相当する。

先ほどの例で試してみる。
最初に適当にパラメータを設定する。p(.|A)は箱Aの場合の赤、青、黄の割合のパラメータである。

p(A)=0.5 p(B)=0.5
p(.|A) = 0.2 0.4 0.4
p(.|B) = 0.4 0.4 0.2

はじめにEステップ。p(zi|xi)を求める

p(zi|xi) = p(xi|zi)p(zi)/P(xi)を求める。
p(xi)=p(xi|A)p(A)+p(xi|B)p(B)なので、

q(A,xi)=p(A)p(xi|A)
q(B,xi)=p(B)p(xi|B)
を求めれば

p(A|xi)=q(A,xi)/(q(A,xi)+q(B,xi))
p(B|xi)=q(B,xi)/(q(A,xi)+q(B,xi))

として計算できる

例えば、q(A,xi)=p(A)*p(xi|A)は
0.2 * (0.4^2 + 0.4^5 + 0.2^3)
である。実際の計算では掛け算を繰り返すと非常に小さな値になって問題が生じるので、対数で計算して、あとで戻してあげる。

次にMステップ。今求まったp(zi|xi)をつかってL(x)を最大化するような
パラメータp(.|A), p(.|B)を求める。今回の多項分布の場合は、単純にそれぞれの出現回数を
p(zi|xi)で重みづけした結果を出現回数だと思って、計算すればよい

例えば箱Aの赤の仮想的な出現回数 r'は
p(A|x1) * 2 +
p(A|x2) * 7 +
p(A|x3) * 2 +
p(A|x4) * 1 +
...

であり、これで求まったそれぞれの色の仮想的な出現回数r',b',y'をつかって
p(r|A) = r'/(r'+b'+y')
とすればよい。

これを繰り返すとp(z)とp(x|z)が推定できる。

実際には、EMは最大になるのを求められるとは限らないので様々な初期値から始める

---

| | Comments (0) | TrackBack (0)

2009.03.14

大規模データを基にした自然言語処理

人工知能基本問題研究会 (SIG-FPAI)でタイトルの題目で一時間ほど話してきました。

発表資料 [pptx] [pdf]

話した内容は
- 自然言語処理における特徴ベクトルの作り方と、性質
- オンライン学習, Perceptron, Passive Agressive (PA), Confidence Weighted Learning (CW) 確率的勾配降下法 (SGD)
- L1正則化, FOLOS
- 索引を用いた効率化, 全ての部分文字列を利用した文書分類

で、スライドで70枚ぐらい。今までの発表とかぶっていないのはPA CW SGD FOLOSあたりでしょうか

オンライン学習、L1正則化の話がメインになっていて、その両方の最終形の
確率的勾配降下法 + FOLOSの組み合わせは任意の損失関数に対してL1/L2正則化をかけながらオンライン学習をとても簡単にできるという一昔前では考えられない感じになってます。
昔なんで収束しないんだとがりがり巨大なGISとかL-BFGSとかの最適化ルーチンをかいてたのがつい最近だったのに。。進歩が早いですね

| | Comments (0) | TrackBack (1)

2009.03.10

web+db レコメンド特集 サンプルコード

- WEB+DBプレスの「[速習]レコメンドエンジン」のサンプルプログラムを訂正してみる

にあったように、WEB+DB PRESS 49号 レコメンド特集での誌上のサンプルプログラムに誤植があり、そのまま書くとコンパイルできないという問題がありました。

サンプルコードの修正をぎりぎりにお願いして、ゴミが残ってしまったのが原因です。
ご迷惑をみなさんにおかけしました。すいません。

WEB+DB PRESS Vol.49サポートページ

ここから、動かせるサンプルコード(Part3用のサンプルコードというところ)をダウンロードできるので、買った方も(そうでない方も?)参考にしてみてください。

以後、気を付けます。

| | Comments (2) | TrackBack (0)

ベンチャーの興し方 PFI編

ベンチャーの話を昨日、R2P IST 1周年記念シンポジウム [link]というところでしてきました。

発表資料 [pptx] [zip(pdf)]

Preferred Infrastructure (PFI)という会社をどのようにやってきたか、学生と会社の関係とかの話です。

話すこと前提で書いているのでパワポだけではちょっと話の流れが見えにくいかも。会場やその先の飲み会ではもうちょっと突っ込んだ話をして面白かったのだが、そこが書けないのが残念。直接聞いてください。

| | Comments (0) | TrackBack (0)

«レコメンド, LSH, Spectral Hashing