NMFを使ったレコメンドシステムの構築

Pythonで学ぶ教師なし学習

Benjamin Wilson

Director of Research at lateral.io

類似記事の検索

  • 大手オンライン新聞社のエンジニア
  • タスク:読者が読んでいる記事に類似した記事をおすすめする
  • 似た記事は似たトピックを持つべき
Pythonで学ぶ教師なし学習

方針

  • 単語出現頻度の配列にNMFを適用
  • NMF特徴量はトピックを表す
  • そのため、類似したドキュメントは類似したNMF特徴量を持つ
  • NMF特徴値を比較するには?
Pythonで学ぶ教師なし学習

単語出現頻度の配列にNMFを適用

  • articles =単語出現頻度の配列
from sklearn.decomposition import NMF
nmf = NMF(n_components=6)
nmf_features = nmf.fit_transform(articles)
Pythonで学ぶ教師なし学習

方針

  • 単語出現頻度の配列にNMFを適用
  • NMF特徴量はトピックを表す
  • そのため、類似したドキュメントは類似したNMF特徴量を持つ
  • NMF特徴値を比較するには?
Pythonで学ぶ教師なし学習

記事のバージョン

  • 同じドキュメントは異なるバージョンでも、同じトピックを持つ
  • しかし特徴量の値は異なる場合がある

強い表現: 犬が人を噛む!恐ろしいイヌによる襲撃で男性が麻痺に…

Pythonで学ぶ教師なし学習

記事のバージョン

  • 同じドキュメントは異なるバージョンでも、同じトピックを持つ
  • しかし特徴量の値は異なる場合がある
  • 例:無意味な単語が多用されているバージョンがある

弱い表現: おそらくご存知かもしれませんが、残念ながら犬が男性を噛んだようです…

Pythonで学ぶ教師なし学習

記事のバージョン

  • 同じドキュメントは異なるバージョンでも、同じトピックを持つ
  • しかし特徴量の値は異なる場合がある
  • 例:無意味な単語が多用されているバージョンがある
  • しかし、すべてのバージョンが原点を通る1本の直線上に並ぶ

ペットというトピックと危険というのトピックの散布図。強いバージョンと弱いバージョンが原点を通る同じ直線上にある

Pythonで学ぶ教師なし学習

コサイン類似度

  • 2本の直線の間の角度を利用する
  • 値が高いほど、類似性が高い
  • 2つの直線の間の角度が0°のとき、コサイン類似度は最大1

ドキュメントAとドキュメントBの散布図。原点から異なる角度で2本の直線が引かれている

Pythonで学ぶ教師なし学習

コサイン類似度の計算

from sklearn.preprocessing import normalize

norm_features = normalize(nmf_features)
# if has index 23 current_article = norm_features[23,:] similarities = norm_features.dot(current_article)
print(similarities)
[ 0.7150569   0.26349967 ..., 0.20323616  0.05047817]
Pythonで学ぶ教師なし学習

DataFrameとラベル

  • DataFrameを使って記事のタイトルに類似度のラベルを付ける
  • タイトルのリスト:titles
import pandas as pd

norm_features = normalize(nmf_features)
df = pd.DataFrame(norm_features, index=titles)
current_article = df.loc['Dog bites man']
similarities = df.dot(current_article)
Pythonで学ぶ教師なし学習

DataFrameとラベル

print(similarities.nlargest())
Dog bites man                            1.000000
Hound mauls cat                          0.979946
Pets go wild!                            0.979708
Dachshunds are dangerous                 0.949641
Our streets are no longer safe           0.900474
dtype: float64
Pythonで学ぶ教師なし学習

練習しましょう!

Pythonで学ぶ教師なし学習

Preparing Video For Download...