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数やもっと複雑な課題があると、試す価値がありますね。