エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

Factorization Machineの実装と数値検証

はじめに

あけましておめでとうございます。エンジニアGの西場です(@m_nishiba)。AI・機械学習チームで自然言語処理や推薦システムの開発を行っています。 Gunosyのデータ分析ブログのDeepなFactorization Machinesの最新動向 (2018)を読んでFactorization Machineに興味を持ち調査しました。

f:id:nsb248:20181231215048p:plain

Factorization Machine

Factorization Machine(FM)はSVMとFactorization methodを組み合わせたような手法です。 詳しくは下記の論文を読んでください。

Factorization Machine

FMを用いることで、スパースなユーザー属性情報等の交差項の重みを効率的に計算することができます。 つまり、下記のような回帰モデルを考えたときに

[tex: y(x)=w_0 + \sum{i=1}^n w_i x_i + \sum{i=1}^n \sum{j=i+1}^n w{ij} x_i x_j ]

 w_{ij} を効率的に計算する方法です。カテゴリデータ等を扱うので  x は非常にスパースになります。

※ 理論的に3次以降の項も考えることができます。

調べてみるとKaggleをしている人には馴染みのある手法のようです。私はKaggleを全然していないのでGunosyの記事で初めて知りました。今年はちゃんとKaggleもしようと思います。

問題意識

実務での問題として下記の2つの問題に応用できないかを考えています。

1. ニュースの推薦システムへの応用

医療関係のニュースのリコメンドを行っています。現在のアルゴリズムは10年近く昔に出た論文を参考にして作っています。この論文の手法では過去のクリック履歴のみ使用しており、ユーザーの属性データを使用していません。

Personalized News Recommendation Based on Click Behavior

そこで、Factorization Machineを用いてユーザー属性情報を活用することでアルゴリズムを改善できるのでは?と考えています。

2. コンテンツの類似度計算への応用

コンテンツのキーワードの組み合わせを使って上手く類似度を計算できるでは?と考えています。 例えば、下記2つの記事について考えます。

  1. 子宮頸がんの新薬発売
  2. 子宮頸がんのメカニズム解明

素人目線ではどちらも同じユーザー層に興味が持たれる記事に見えるのですが専門家に聞くと、前者は産婦人科、後者は癌の専門医が興味を持つ記事ようです。

この違いは「癌+新薬」と「癌+メカニズム」から来ています。そこでFMを使ってキーワードの交差項を考慮することで上手く類似度を計算できるのではないかと考えています。

検証

実際の問題に適用する前に公開データでFMの検証を行います。 (社内データでの検証結果については後日公開します。)

アルゴリズムはLibFMなど色々と公開されてる実装がありますが、今回は自分で実装をします。 公開されている実装を使おうとはしたのですが環境構築に失敗しました... また今後はFFM、DeepFM、xDeepFM等の検証を行う予定ないので同じインターフェイスで使えたほうが便利なので自前で実装します。

データと前処理

データ

criteoのclick予測データを使います。 このデータ・セットはDeepFM: A Factorization-Machine based Neural Network for CTR Predictionの数値実験でも使われており、自分の実装を確かめるベンチマークとなるので採用しました。この論文での数値実験でのAUCの値 0.789 を目安として検証します。 ただデータ量が非常に大きいので全体の10%をサンプリングして使用します。

前処理

このデータセットには予測時の特徴量として、13個のintegerの特徴量と26個のcategoryの特徴量があります。 integerの特徴量は欠損もあるため下記のように各カラムごとに変換します。

 m=\min(x_1, ..., x_n)

欠損していない場合:

 x_i \leftarrow \log(x_i - m + 2)

これは最小値の値が \log(2)になるようにしています。

欠損している場合:

 x_i \leftarrow \log(1)=0

実装

tensorflowを使って実装します。

※ 最近、tensorflowを使っていないので効率的な書き方など指摘していただけると助かります。

結果

AUC=0.786 となり、正しく実装できていそうです。

データをダウンロードしてexamples/resources/train.txtに置いて、下記のコードを実行すると再現できるはずです。 master/examples/factorization_machine_example.py

まとめ

今回使ったソースコードは全て公開しています。 まだまだ整備中なのですが、今まで業務で使っていた徐々に公開していく予定です。今後はOSSとして開発していく部分を増やしていく予定です。

実務で使っているニュースの推薦システム等を公開したら面白いのでは?と思っています。

  • gokart ... luigiをラップし、タスクの定義を簡単にしている。
  • redshells ... gokartを使って様々なタスクが定義されている。

まぁこういうことですね

We are hiring

機械学習エンジニアを募集中です!

jobs.m3.com