「夫子憮然曰、鳥獣不可與同羣。吾非斯人之徒與、而誰與。
「論語」微子、第十八、六

2013/02/20

いかに記事を推薦するか、その1

実は二週間くらい前から、こっそり 新しいサーヴィス(Mynd Daily)を公開、試験運用している。 サーヴィスの内容は「毎朝あなたへのおすすめの記事を選んでメイルでお届けする」もので、 これ自体は珍しいものでも、革新的なものでもない。 例えば、ニュースリーダにおすすめ機能のついたアプリケーションやサーヴィスが色々あるし、 良く似た先行サーヴィスで有名なものに、 "Gunosy"がある。 それでもあえて新たに公開するのは、 未来に予定されているもっと大きな枠組みの(内側の)一部分のテストだから、 という理由が一つ、 そしてもう一つの理由は、今日の文章の最後に告白してある。

さて、このような「ユーザにおすすめの記事」の推薦は、 どんな仕組みで行なわれているのか。 正直に言って、標準的な方法があるのかどうか、私は知らない。 ただ、我々がどうしているかは知っているので、 ここで明かせる範囲で解説したい。 "Gunosy" のようにアルゴリズムをキー・テクノロジにしているところでは、 「アルゴリズムは秘密」ということが多いようだが、 あえて、説明してしまう。 そして明日以降は、その周辺の問題について議論したい。

私がこのアルゴリズムの原型を考えたのは、 一年半くらい前で、自分用に "Life hacker"リーダを作ったことから始まる。 私は "Life hacker" を google リーダに登録して読んでいたのだが、 私の英語力では毎日、全ての記事を読み終えられない。 そこで、私が読みたいと思うだろうものを予測して、好むだろう順番に並び変えるリーダを作ったのである。 (ちなみに、unix 上のコマンドラインツールで、vi 風のキー操作だった)。 当時の私は、「推薦」や「機械学習」について、ほとんど何も知らなかった。 しかし、文献調査が好きではないので、 以下のような発想に基き、スクラッチからアルゴリズムをでっちあげたのである。

まず、私はある記事を目にしたとき、読む読まないをどう判定しているのか、モデル化する。 おそらく、例えば、私は文章の中に「猫」という語があればとりあえず読んでみよう、 と思うのかも知れない。 よって、記事の特徴量として、その記事に含まれる語とその「重み」の情報をとる。 例えば、ある記事には「猫」要素が「0.4」くらいある、など。 一方で、私の好みの特徴量も、語とその語の「重み」の情報とする。 例えば、私は「猫」要素に 0.8 くらい反応するが、「犬」要素には -0.5 くらい反応する (プラスは私にとって好ましく、マイナスは好ましくない)。 そして、私がある記事を目にしたとき、どれくらいその記事を好むかは、 この二つの量の線形な計算(例えば、対応する語毎に重みをかけ算して足し合わせる)の答の大きさで決まるとしよう。 この演算が線形でいいのか、という疑問はもっともだが、線形代数は便利なので、 とりあえずこれでやってみる。駄目なら、どこかの空間に「持ち上げ」て、 演算が線形になるように変形することができるだろう。 ちなみに、弊社内ではこの演算を「テイスティング」と呼んでいる。ちょっと格好良い。

モデル化はこれでよいとして、次の問題はどうやって、 新しい記事に対する好みを予測するか。 もし、私の好みを表す(私の心の中にある)特徴量が分かっていれば、 それを新しい記事の特徴量に「テイスティング」すればよいが、 私の心の中は覗けないので、不明である。 しかし、過去に私が好んだ記事、好まなかった記事のテイスティングの値は分かっている(と、する)。 だから、これらを方程式として、私の心の特徴量を解けば良い。 ここまでは、珈琲を一杯飲んでいるくらいの間に考えたのだが、すぐに問題に気付いた。

それは、方程式の数が全く足りない、ということである。 私の心の特徴量には少なくとも数千語以上は登録されているだろう。 つまり、その重みを求めるべき変数が数千個以上ある。 これを求めるには方程式が同じ数くらい必要なはずだが、 ユーザはいつかこのサーヴィスが自分の好みを理解してくれるまで、 つまり十分な数の方程式が貯まるまで、 ランダムな記事をクリックしながら(実際、この一つ一つがテイスティング)、 一年も二年も待ってはくれない。 せいぜい一週間、いや、三日である程度の答が出なければ。 そう思っていたところ、 たまたま半正定値計画法の研究会に参加して、 「圧縮センシング」というアイデアを知った。

この教えによれば、この方程式系を解くのではなく、 この方程式系を制約条件だと思って、その条件を満たす中で、ある意味で一番「小さい」 ものを探す。すなわち、最適化問題に翻訳するのである。 もちろん、一番「小さい」ものが真の解であるとは限らない。 しかし、こういう節約的なものはきっと「良い」解に違いない。 実際、人間の脳もそのような節約性を持っているのかも知れない。 ただし、最適化問題を解くことはルーチンではあるものの、 計算量が大きいし、設定と誤差の処理が難しい。 そこで、私は簡単に計算できる方法で発見法的にある種の近似解を作ることにした。 これが最初のバージョンのアルゴリズムである。

ちなみに、このアルゴリズムで私の最初の目的、つまり "Life hacker reader" 作りは完全に果たされた。 「僕って天才かなあ」と思っていたくらいで、 当時は全く気付いていなかったのだが、これは「問題が易しかったから」に過ぎない。 実際、一般的なサーヴィスとして、記事推薦の仕組みを作ることは、全く易しくない。 ここに、曖昧にとは言え、アルゴリズムを公開したのは、 これを知ったところでどうもできない、ということを、今の私ははっきりと知っているからである。

ある意味、推薦サーヴィスとは一種の手品、マジックのようなものだ。 アルゴリズムはそれを組み立てる一つの「トリック」あるいは「技法(マヌーヴァ)」 であるに過ぎない。 マジックをマジックたらしめるものは、ショー全体の絶妙のバランス、 正確なチューニング、そして、人間そのものの深い理解に基く演出である。 そのためには、多くのユーザの大量の情報を得て学ぶ必要がある。 それが、我々がこのサーヴィスを、「二番煎じ」であると知っていながら、 あえて、公開する主旨なのである。

明日からは、 "Mynd Daily"を実例に、記事推薦をめぐる色々な問題を議論してみたい。 もしよろしければ、あなたもユーザ登録をして、おつきあいくださいませ。