Wide&Deep Learning for Recommender Systems using TensorFlow

CJNANです。

この間、お客様から「深層学習でレコメンドエンジンできるの」って聞かれましたので、ちょうど研究室時代にやってたWide&Deep Learningと言う推薦アルゴリズムを軽く紹介します。

NOTICE:本編は機械学習やTensorFlowの紹介であり、クラウド技術が含まれていません。前半はWide&Deepモデル説明、後半はTensorFlowのTutorialになります。

レコメンドでの機械学習技術の課題

一般のレコメンドシステムはメモリベース(統計マトリクス、例:協調フィルタリング)が多く、Itemが多くなる(100万以上とか)と、一つのデータに対して、全件のマトリックスを演算しなければならないので、パフォーマンスが下がる課題があります。

レコメンドにDeep Learningできるの?

できます。正直、個人の経験では、レコメンド系のデータはユーザのコメントや行動は主観意識が強く、取れるデータ属性も限るため、ニューラルネットワークには向いてないし、画像や音声ほどには研究されていないですが、この五年間に成果が出始めていました。例えば画像類似度によるLINEスタンプの推薦、コンテンツベースのYoutubeビデオ推薦、AlibabaのTaobaoアイテム推薦など、色々事例があります。特にAndroidユーザならGoogle playのAPP推薦ではDeep Learning技術を使っています。

ここで紹介するのがこのGoogle playに導入されたWide&Deep Learningです。

Wide&Deep Learning for Recommender Systems

(Reference: Google AI Blog)

このモデルの考え方は、「記憶(Memorization)」と「一般化(Generalization)」です。「ペンギンは飛べるか」を例に説明すると、

(Reference: Google AI Blog)

Wide:linear regression。Sparseな特徴値、拡張しやすい、説明モデル、Feature engineeringが大変。

記憶:ヒストリデータから事実を学習して推論する。「当たり前の事実」を予測

:「イーグルは飛べる」、「スズメは飛べる」、「ペンギンは飛べない」など

数式:Linear Regression

この数式は[0,1]の値で、2つのItemが相関性がある場合は1,相関性がない場合は0になりますので、入力データから自動に特徴に変換するのに使われます。

(Reference: Google AI Blog)

Deep:Deep Neural Network。Denseな特徴値、一般化できる、パラメタの説明ができない。

一般化:特徴間組み合わせ、相関性を自動に学習し、推薦の多様性ができる。

:「羽がついてる鳥類は全部飛べる」

数式

こちらはよく知られている、DNNのhiden layerの計算式になります。

(Reference: Google AI Blog)

Wide&Deep:アイディアはシンプルで、「記憶」と「一般化」の特徴を活かす、だけです。つまり「羽がついてる鳥類は全部飛べる(Deep)が、ペンギンは飛べない(Wide)」が理想的な回答になる。

数式

Joint Training vs. Ensemble

(Reference: Google AI Blog)

  • Joint Traning: 同時に学習、WideとDeepの弱みをカバーする
  • Ensemble:独立に学習してコンバインされる、学習コストが高い

Ensembleは各モデルが独立に学習しますので、各モデルのパラメタが共有できないし、サイズを確保する必要があります。つまり、学習コストが高い問題があります。しかし、Joint Traniningはお互いにパラメタがひとつのモデルに反映され、全体的の最適化ができます。

OptimizationはWideにFTRL、DeepにAdaGradを適応しました。

TensorFlowでやってみる

サーバ:Alibaba Cloud ECS GN5シリーズ(Nvidia P100)

環境: Ubuntu16.0.4、Jupyter Notebook

データセット:こちらのデータセット(アメリカの所得調査結果)を使います。

https://archive.ics.uci.edu/ml/datasets/Census+Income

中に所得額(>50K or <=50K)がLableとして使いますので、典型的な二項分類問題になります。

事前準備:

# Ubuntu/Linux 64-bit
$ sudo apt-get install python-pip python-dev
$ sudo pip install pandas
$ sudo pip install tensorflow
$ sudo pip install git
$ sudo git clone git@github.com:tensorflow/models.git

そして、下記の通りにmodelディレクトリをPYTHONPATHとPATHに環境変数を反映します。

$ export PYTHONPATH="$PYTHONPATH:/path/to/models"

実行:

$ python census_dataset.py #データセットをダウンロード
$ python census_main.py #TFを実行

これで、間違いがなければ、Accuracy 83%が出るはずです。詳細コードはGithubで参考できますので、ここでは割愛します。

(TFのWide&Deepモデル参照リンク)

https://github.com/tensorflow/models/blob/master/official/#running-the-models

向いてる&向いてない

ここからは個人の経験ベースの内容です。Wide&Deepのバランスをどう設計するかによって、性能が左右されます。Item数によって、Wide&Deepの優位性(Item>100万)が出ると知られてますが、正直どこまで差分があるのかは試したことがありません。

今後の試し

Deep側のDNNの所がずっと気になっていました。DNNの代わりに、Resnetを使い、階層の数を増えたり、一般化の効果が上がるはずなので、今後Item数やもっと複雑な課題があると、試す価値がありますね。

この記事をシェアする