エムスリーテックブログ

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

CNNと協調フィルタリングを使った日本語文書のリコメンド

機械学習エンジニアの西場(@m_nishba)です。主に自然言語処理を使ったリコメンドや文書分類、ユーザー分析を行っています。

最近、開発中のリコメンデーションのアルゴリズムについて紹介します。

コンテンツ

モチベーション

弊社では様々な形態の医療系コンテンツ(テキスト、動画、画像)を扱っています。

様々なコンテンツを同時にリコメンデーションをしたいと考えています。そこで協調フィルタリングを使用しようと思っているのですが、アイテム・コールド・スタート問題を解決する必要があります。 (※ ユーザーからの評価が少なく、リコメンドするためのデータが十分に蓄積されていないことをコールド・スタートと呼びます)

弊社ではニュース記事等の配信も行っており、全く評価されていない(クリックされていない)アイテムをリコメンドする必要があります。

このようなアイテム・コールド・スタート問題に対応するために、内容ベース・フィルタリングとのハイブリッドにしたいのですが、短い文書に対応する必要があります。というのもニュース記事等は十分な文章量がありますが、動画コンテンツの場合、テキストはタイトルのみ場合もあるからです。

そこでConvolutional Matrix Factorization for Document Context-Aware Recommendationを実装して実データで試してみようと思います。(論文の内容は後述します。)

問題の概要

詳細に入る前にリコメンドアルゴリズム作成時の問題点とアプローチをまとめます。

  • アイテム・コールド・スタート問題
  • 内容ベースで使用できるテキストが短い。
  • 未知の単語のへ対応
  • 不均衡データ・Implicit feedbackデータ
    • 訓練データのサンプリングを工夫

問題の検証結果

リコメンドの前段階として、短いテキスト情報だけを使って似ているテキストを見つける問題でアルゴリズムを検証したところ doc2vec, word2vecを使った方法やword2vec+TFIDFを使った方法より非常に良さそうな結果になりました。詳細は後述します。

文書分類

文書分類の論文の紹介

本題に入る前にテキストに対してCNNを使う方法を紹介したいと思います。

ここで紹介するアルゴリズムは"Convolutional Neural Networks for Sentence Classification"(Yoon Kim, 2014)に従っています。(弊社の工夫は後述する日本語のTokenizeのみです。)

この論文はタイトルの通りCNNを使って文書分類を行っています。 モデルはシンプルで下記の図のようになります。 f:id:nsb248:20180306112507p:plain

(Yoon Kim, 2014)より引用

Word embedding ⇒ Convolution ⇒ Max pooling ⇒ Fully connected layer の流れで処理しています。最後のFully connected layerでdropoutを使っています。

またフィルターを作るときにwindow sizeを複数使用し、n-gramのような処理を実現しています。 さらにchannelとして、ランダムに初期化されたembeddingとwikipedia等を使って学習したword2vec等のembeddingを同時に使用することも提案されています。

精度検証

論文では様々なデータ・セットに対して他のアルゴリズムと比較しています。 f:id:nsb248:20180306112608p:plain

(Yoon Kim, 2014)より引用

ここではMovie reviewsのデータ・セットを使って、そのreviewがpositive/negativeかどうか分類する問題で、論文の結果を再現します。

ソースコードはここにあります(が、検証用でぐちゃぐちゃです)。 https://github.com/nishiba/tf_cnn_mf

事前に学習したword embeddingを使用せず、word-embeddingをrandomに初期化し、分類問題と同時に学習するCNN-randモデルを実装し、検証しました。

結果は下記のようになり、論文の76.1を概ね再現できています。

test: step 4200, loss 0.654164, acc 0.758201

社内データを用いた検証

弊社では医療関連のニュースの配信を行っており、配信するニュースに強く関連するタグを付けて、リコメンドに活かしています。現状、それらのタグは人手で付けており、それを自動化できるか検証します。今回はニュースのタイトルから「地域」タグがつくかどうかの2値問題を考えます。一般にニュース記事に関連する地域の特定は、ニュース配信サービス等では重要な課題となっています。(実際は都道府県等のタグを付けたいのですが、これは他の業務への布石なので簡単なケースにしています。)

Tokenizeの方法

上で紹介したCNNでの手法を使用するために日本語をトークンに分割する必要があります。ここに英語と違って日本語の自然言語処理の難しさがあります。

方法① 普通にMeCabを使う。

今回は地域ニュースかどうかなので、医療専門用語の重要性も低いので医療系のユーザー辞書を使わずにmecab-ipadic-NEologdをそのまま使います。

方法② 文字ベースとMeCabの組合せを使う。

ちょっと工夫した方法でトークン化したいと思います。今後は文字ベースでの自然言語処理を進めていたいと考えています。というのは「肺癌」「胃癌」という単語は状況によっては非常に似ている分散表現を得たいです。

しかし、これらを学習させるには医療系のテキストが大量に必要になります。癌なら多く手に入りますが、希少疾患だと大量のテキストを得るのは難しいです。

そもそも癌という文字が含まれているので、文字ベースのほうが効率的に分散表現が得られるのではないかと考えられます。

そこで下記のようなルールでトークン化を行います。

  1. 連続するカタカナ・アルファベット・数字に対してのみMeCabで単語に分割する
  2. 漢字・ひらがなは一文字ごとに分割する

例えば下記のように分割することになります。

in: かゆみ減らす抗体に有効性 アトピー皮膚炎
out: か, ゆ, み, 減, ら, す, 抗, 体, に, 有, 効, 性, アトピー, 皮, 膚, 炎,

検証結果

(詳細なデータは出すことができません。)

0:地域タグがついていない
1:地域タグが付いている

として分類問題を解いています。

方法①の結果
precision recall f1-score support
0 0.88 0.93 0.90 2039
1 0.76 0.65 0.70 716
avg / total 0.85 0.85 0.85 2755

1のrecallがかなり悪いですね。

方法②の結果
precision recall f1-score support
0 0.97 0.82 0.89 2039
1 0.65 0.93 0.76 716
avg / total 0.89 0.85 0.86 2755

1のrecallは良くなりました! 逆にprecisionが下がっています。

実際は地域タグが付いていないのに、地域タグ付きだと分類してしまった例は下記のようなものがあります。

1  督促状の金額は「0円」 滋賀・彦根市、国保料などミス
2  中村哲さんに旭日双光章 アフガンで人道支援
3  病院内で相次ぎトラブル 飲料に異物、エプロン切断
4  性能不足、新たに90棟 関与4人、組織ぐるみ 東洋ゴムの免震不正拡大
5  在宅生活、支援の動き 治療薬開発、急ピッチ
6  アスベスト被害で無料相談 公営住宅の状況把握へ
7  母子4000組情報流出の可能性…富山大
8  患者死亡事故、再び不起訴 介助の54歳准看護師、札幌
9 【愛知】1位名古屋第ニ赤十字病院、2位愛知医科大学病院、2017マッチング中間
10 東京都千代田区、インフル予防接種、高校生まで無料化

この中で明らかにおかしいの4番、5番、6番ですね。 他は地名や施設名が含まれていますし、3番のタイトルも"病院"となっており、特定の病院を指しているので、地域性が高い可能性があります。

教師ラベルは擬似的に作ったということもありノイズが多そうです。(このモデルを使って教師データの作り直しをそのうちしようかと思います)

コンテンツのリコメンド

本題のコンテンツのリコメンドを考えます。 動画やニュース記事等を一緒にリコメンドしたいのですが、問題が2つあります。

  • 公開期限付きのものや情報鮮度が大事なのもが多く基本的にはアイテム・コールド・スタート問題になります。
  • 動画の原稿はなく、使えるテキストはタイトル(短い文章)しかありません。

そこで、コンテンツ・ベース・フィルタリングと協調フィルタリングのハイブリッドを考えます。 Convolutional Matrix Factorization for Document Context-Aware Recommendation を参考にしました。

ざっくり論文を説明すると、Matrix Factorizationにより、ユーザーとアイテムの潜在ファクターを求め、CNNを使ってアイテムの潜在ファクターをテキストから再現するように学習します。 そうすることで、テキストの情報も組み込んだMatrix Factorizationの潜在ファクターを求めることができます。

詳細は論文を見てほしいのですが、最小化する数式を紹介します。 
\mathcal{L}(U, V, W) = \sum_i \sum_j \frac{I_{ij}}{2}(r_{ij} - u_i^T v_j)^2
+ \frac{\lambda_U}{2} \sum_i ||u_i||^2
+ \frac{\lambda_V}{2} \sum_j ||v_j - \text{cnn}(W, X_j)||^2
+ \frac{\lambda_W}{2} \sum_k || w_k||^2

ここで、 u_i がユーザーの潜在ファクター、 v_j がアイテムの潜在ファクター、cnn(W, X_j) がアイテムの潜在ファクターをテキストから再現するCNN、w_k はCNNのパラメータです。

これは同時に解くことが困難で、ユーザーの潜在ファクター、アイテムの潜在ファクター、CNNと順に学習させることを収束するまで繰り返します。

弊社のデータに関する課題

上記のアルゴリズムを適用したいデータは、動画や記事のクリックログといったimplicit feedbackのデータです。 またユーザー数、アイテム数も論文内で実験に使われていたデータよりも多いです。

そこでアルゴリズムを少し変更します。

SGDを利用する。

論文では潜在ファクターの最適化の際、近似解を逆行列を通して計算していました。これは状況によっては非常に時間がかかります。

ImplicitFeedbackなので、MovieLensのようなレーティングされたデータのように"評価されたペアのみを考える"ことができません。

そこで、確率的勾配降下法(SGD)を使用します。

② Positive/Negative数が等しくなるようにサンプリングを行う。

学習時にクリックされたデータ(positive)と同じデータ数のクリックされていないデータ(negative)を使用します。 negativeデータはepochごとにサンプリングしなおします。

Collaborative Filtering for Implicit Feedback Datasetsのように確信度を導入してもいいのですが、今回SGDを使っているのデータ数調整で同様な効果を得ることにしました。

③ Matrix Factorizationにbiasを導入する。

よく使用される方法ですが、Matrix Factorization時にbiasを導入します。 つまり、 
\sum_i \sum_j \frac{I_{ij}}{2}(r_{ij} - u_i^{T} v_j)^{2}
ではなく、 
\sum_i \sum_j \frac{I_{ij}}{2}(r_{ij} - u_i^{T} v_j - p_i - q_j)^{2}
とします。ここでp_iq_j は それぞれユーザーとアイテムのバイアスを表すスカラー値です。

この導入はパフォーマンスに大きな影響がありました。 というのもニュース記事等は時期や公開時間等のタイミングによってアクセス数が大きく異なります。 それは同じようなタイトルの記事でも全然違うアクセス数になるということです。

最初の式の場合、アクセス数が多いと ||v_j|| が大きくなり、逆に少ないと小さくなります。

同じようなタイトルでこのようなことが生じるとCNNの学習が進まなくなります。それは同じような短いテキストから ||v_j|| の大小まで判断つかないからです。

そこで、このようなタイミング等によるアクセスの大小を表現するためにバイアスを導入し、CNNは同じように \sum_j ||v_j -
\text{cnn}(W, X_j)||^2 を最小にするように学習させます。

④ 文字ベースと単語ベースの組み合わせ

最初の文書分類のときに紹介した方法を使います。 この方法により未知の単語へ少しは対応できるようになります。短い文章の中に未知の単語が含まれると致命的になります。

例えば"子宮動脈塞栓術"という単語が始めて出てきたとしても、文字ベースだとそれなりの分散表現を得ることができます。

リコメンド方法

いったんCNNを学習させるとクリックが全く無いようなアイテムに対しても潜在ファクター v_j を計算することができます。

ここで得られる v_j は同じような傾向の人がクリックするかどうか(協調フィルタリング)と同じような文字がふくまれているかどうか(CNN)といった情報を持ったベクトルになります。

また  u_i^{T} v_j により、ユーザーがアイテムを好むかどうかのスコアが得られます。

何らかの方法で q_j を予測することができれば、新しいアイテムをリコメンドすることができます。 その方法はまた別の機会に紹介したいと思います。

実験

上記の方法で学習されたCNNを使い、短い文章をベクトル化し、文章の似ている度合いを計算してみます。類似度はコサイン類似度を使いました。

ターゲットとする文章は訓練時に使用していない文章を使用しています。

(ちなみに、doc2vec, word2vecを使った方法、word2vec+TFIDFを使った方法より非常に良さそうな結果になりました。)

========================================================================
EGFR変異陽性肺がん薬剤耐性研究の最新情報/実際の症例から学ぶT790M検査のための再生検
--- 似ている記事 ---------------------------------------------------------
  score                              title
0.918537  タグリッソがEGFR変異陽性NSCLCの1次治療で優先審査品目指定
0.913470          ベダキリンフマル酸塩、多剤耐性肺結核適応で承認取得
0.901056                  イラリス、バイアル入り液剤追加承認
0.892470            RET融合遺伝子陽性肺癌の新薬剤耐性機構を発見
0.890703           後発薬241品目を承認、降圧剤アイミクスに20社
========================================================================

これらの記事は

  • 肺癌に関連している
  • 同じユーザーに読まれている

といった特徴があります。 協調フィルタリングだけの場合、2番めの”同じユーザーに読まれている”しか考慮されませんが、 CNNを組み合わせることにより、”肺癌に関連している”記事を選ぶことができます。

最後に

弊社では、医療分野における

といったコンテンツが豊富にあり、分析によってビジネスを加速することができます。 (医療分野に特化した翻訳や動画からの特徴量抽出にも取り組もうとしています)

弊社のデータ分析・機械学習業務の特徴として、

  • ビジネスに直結している
  • メインサービスにアルゴリズムの導入ができる。
  • アルゴリズムのABテストをビジネスサイドが受け入れてくれる
  • 動画等に対する長期的なアルゴリズム開発にも挑戦できる。
  • 外部API等では実現できない面白い課題に専念できる。(外部APIでできる問題は外部APIを使います。)
  • 新卒・中途関係なく、自分が担当する案件のメイン開発者になれる。

といったところがあります。

もし興味のある方は応募フォームまたは@m_nishibaまでご連絡ください。