用 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 中的无监督学习

文章的不同版本

  • 同一文档的不同版本有相同的主题比例
  • …但具体特征值可能不同!
  • 例如某个版本用了很多无意义词
  • 但所有版本都在过原点的同一直线上

主题"宠物"与"危险"的散点图,强/弱版本位于同一条过原点的直线上

Python 中的无监督学习

余弦相似度

  • 使用两条直线之间的夹角
  • 数值越大越相似
  • 最大为 1(角度为 0°)

文档 A 与文档 B 的散点图,各有一条过原点的直线,夹角不同

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 中的无监督学习

Passons à la pratique !

Python 中的无监督学习

Preparing Video For Download...