用 NMF 建立推薦系統

Unsupervised Learning in Python

Benjamin Wilson

Director of Research at lateral.io

尋找相似文章

  • 大型線上報社的工程師
  • 任務:推薦與使用者正在閱讀文章相似的文章
  • 相似文章應有相近主題
Unsupervised Learning in Python

策略

  • 對文字頻率陣列套用 NMF
  • NMF 特徵值描述主題
  • …因此相似文件會有相近的 NMF 特徵值
  • 要比較 NMF 特徵值嗎?
Unsupervised Learning in Python

對文字頻率陣列套用 NMF

  • articles 為文字頻率陣列
from sklearn.decomposition import NMF
nmf = NMF(n_components=6)
nmf_features = nmf.fit_transform(articles)
Unsupervised Learning in Python

策略

  • 對文字頻率陣列套用 NMF
  • NMF 特徵值描述主題
  • …因此相似文件會有相近的 NMF 特徵值
  • 要比較 NMF 特徵值嗎?
Unsupervised Learning in Python

文章的不同版本

  • 同一文件的不同版本有相同的主題比例
  • …但精確的特徵值可能不同!
  •  
  •  

強版本:Dog bites man! Attack by terrible canine leaves man paralyzed...

Unsupervised Learning in Python

文章的不同版本

  • 同一文件的不同版本有相同的主題比例
  • …但精確的特徵值可能不同!
  • 例如某版本使用了許多無意義的字詞
  •  

弱版本:You may have heard, unfortunately it seems that a dog has perhaps bitten a man...

Unsupervised Learning in Python

文章的不同版本

  • 同一文件的不同版本有相同的主題比例
  • …但精確的特徵值可能不同!
  • 例如某版本使用了許多無意義的字詞
  • 但所有版本都落在通過原點的同一直線上

主題 pets 與主題 danger 的散佈圖,強版與弱版同在一條通過原點的直線上

Unsupervised Learning in Python

餘弦相似度

  • 使用向量間的夾角
  • 值越高代表越相似
  • 角度為 0 度時最大為 1

文件 A 與文件 B 的散佈圖,兩條自原點出發、角度不同的直線

Unsupervised Learning in 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]
Unsupervised Learning in 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)
Unsupervised Learning in 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
Unsupervised Learning in Python

一起來練習吧!

Unsupervised Learning in Python

Preparing Video For Download...