taki["blog"] = "200 OK"

社会人3年目の日常

2017/9/19 体力切れとICDM2017論文消化×1

昨日遊んでいたので体力が切れており、集中力が通常平均の50%〜70%程度だった(実感)(悪い)。細々とした「特」の資料つくり、面談などをやった。やりきれてないので今週やる必要があるが、別のことがやりたい週なので、詰んだかも。残業で好きな仕事をやり、平時にやるべき仕事をやる(たぶんやらない(悪い))。土日に外で走れなかったため、運動量減少気味。火曜日に入れるとしんどいが、火曜日に入れるしかない(別件)。

家でICDM2017の論文を一本読んだのでメモ。本当に読みたいやつのPDFがまだ出てこないので、そっちは様子見。全然日記にも論文にも関係がないメタ的な話として、はてなブログ数式書きづらすぎて投げそうになる。ついでに真面目な話を記録するために「真面目なことも書いてある日記」というタグを作成。


論文情報

  • X Liu, Y Song, C Aggarwal, Y Zhang, and X Kong, BiCycle: Item Recommendation with Life Cycles

背景

  • 伝統的な推薦システム(協調フィルタリング的な手法)はアイテム・ユーザの扱いが時不変なので、実アプリケーションとは異なる
  • これまでに研究されている明示的なタイムスタンプを入れる手法は、上手く行かない場面があるため、Life Cycle という考え方をアイテム・ユーザの両方に導入して新しい手法を構築
  • 基本的なアイデアは「発売直後に人気が出て、徐々に落ちていき、最終的に平均的な挙動へと落ち着く」といった商品の売れ方の基本的なステージを取り入れること。論文の図が雰囲気が分かりやすい。

f:id:takilog:20170919212500p:plain

  • 時間的な変化を入れると、訓練データがスパースになるため学習が難しい。そこで「相関のあるユーザは、Life Cycleの似たステージで似た変化のパターンを取っているはず」「時間変化に対して好みやLife Cycleは徐々に変化していく」という観察に基づいて手法を実験し、実験で評価した。

過去の手法

  • 協調フィルタリング(CF)でやること: \Omega=\{ (i, j) \mid r_{ij} \text{ is observed.} \} から非観測なi, jについてスコアを予測する
  • 行列分解(MF)でやること:  \min_{U, V} ||R-U^T V||^2_F + \frac{\lambda}{2}( ||U||^2_F + ||V||^2_F)
    • 評価値R、ユーザの行列U、アイテムの行列Vと見なせば、いい感じの表現になる。例えばフロベニウスノルムに正則化を付ける
  • Time-aware CFでやること: 観測値のうち、適当なウィンドウ (t_s, t_e] を考え、そのタイムスタンプを持つデータだけを集めてCFし、次のウィンドウ (t_e, t_f] の評価値を予測する

提案手法

  • 例えばTime-aware CFの枠組みにMFを使えば、とりあえず予測モデルになるが、学習データがスパースになり、時間変化と共時間変化(co-evolution patterns)を捉えられないので、美味しくない
  • ユーザとアイテムの両方について、ライフサイクルという大きな枠があると仮定し、サイクルにおける個別の段階をライフステージとする。要するにウィンドウの列(アイテム・ユーザごと)。
  • ライフステージは何らかの手法でgivenとする。
  • 「時刻tにおけるユーザi、商品jに関する評価値」というTime-aware CFのデータを、ユーザのp番目のライフステージとアイテムのq番目のライフステージの情報を元に振り分けする
    • ユーザ、アイテムごとのライフステージがgivenなので、大丈夫
  • MFをかければ良いが、明らかにデータがスパースなので、スムージングする。スムージングの手法はかなりナイーブ。(ただし徐々に変化するという研究上の前提があるため、大丈夫)。
f:id:takilog:20170919214806p:plain
  • 残りはどういう正則化を付けて行列分解の目的関数を拡張するか?という点になる。時間方向の正則化なので、temporal regularization という名前になる。そのまま。一つは平均と分散に関する正則化、もう一つは隣り合うステージ同士の誤差が小さくなるような正則化。そのまま。
f:id:takilog:20170919215123p:plain f:id:takilog:20170919215135p:plain
  • 最適化は普通に行列の偏微分して、UとVをGDする。
  • 目的関数はpとqの組について、MFを適用する感じ。ここでco-evolutionの雰囲気が入ってくる。

実験

  • 時間的な変化を入れない行列分解、SVD、入れるTimeSVD、Popなどの手法と、アイテムのみ(ItemCycle)、ユーザのみ(UserCycle)、両方(BiCycle)を比べる。
  • 詳細な結果は論文を参照として、BiCycle/ItemCycle/UserCycle共に性能が良い。(もちろんデータによってはSVDやTimeSVD、MFが勝つ場合もある)
  • 窓をスライドさせつつ、c番目の窓より後ろの全データと、今の窓cの20%を学習データにして、残りがテストデータ。こういうやり方で良い?(知らない)。
  • 評価はtop-kを出させた上で、recall/prec at kとMRRを使う(たぶん普通)。
  • 実験結果のWindow 1、2、3は何か順序がある(1<2<3)のか、適当に選択した窓1番目、2番目、3番目なのか英語読解してないので不明。論文の中身的には適当な場所っぽい。

感想

  • EpionionsではTimeSVDも悪くないけど、DBLPとML100Kだと明らかに提案手法が強いけど、どんなデータの違いなのかよく分からない。前処理がどれぐらい影響しているのか気になる。ぱっと持ったイメージだとDBLPだけデータの性質が違いそうな気がしたけど、結果的にはそうではないかもしれない。
  • 時間に関するデータを扱う手法としては結構典型的なsmooting/regularizerだと思うけど、どうなんだろう。
  • そもそも明示的にタイムステージgivenの場合、こういうデータ解析(推薦)がしたいのだろうか。