译者:AI研习社(季一帆)
双语原文链接:https://www.yanxishe.com/TextTranslation/2968
一个基于深度学习的电影推荐系统
你看过《盗梦空间》吗?是否被影片中的梦中梦烧脑,或是想象现实世界中物品能否像电影中那样漂浮在空中?至少目前我们没有办法使物体悬浮在空中,但是,数据科学家可以将python向量映射到多维空间。
本文将为介绍一个电影推荐系统,在推荐系统中,有许多电影向量悬浮于多维空间。同时,本文介绍的推荐系统无需租用服务器、编写代码、抓取数据或网页维护等繁杂的工作,非常容易上手。此外,你还可以将其扩展到社交网络、股票、运动员、电视节目、书籍等领域。想象一下,众多实例都会被映射到多维矢量空间,一览无余,那时多么直观啊。
你可以点击该链接预览我们的电影推荐系统。
学习本文需要满足以下条件:对新概念的好奇心,渴望部署自己的Web应用程序。
同时,你最好对这些知识有所了解:word2vec嵌入,神经网络,Tensorflow,Github和推荐系统。
工具/概念:
1.Embedding:将高维向量投射到低维稠密向量空间。由于表示图像/单词的像素或标记特征可能需要数百万个参数,因此我们需要定义一种受限统一结构,以此作为ML模型的输入。在对高维或大量特征进行建模以导出受限数据大小模式时,通常会遇到维数灾难,即模型无法从输入数据中提取相关模式。通常我们会使用主成分分析(PCA),TSNE或L1正则化等方法进行降维,但是对于极高维度和稀疏数据集(如Wikipedia语料库中的数百万个标记),基于神经网络的嵌入可以很好的提取相关属性。
嵌入能够捕获标记或像素之间的语义相似性,并将其投影到向量空间中。例如,我们知道“费德勒”和“网球”之间存在密切关联,那么在100维嵌入空间中,“费德勒”比“特朗普”更接近“网球”。
图示如下:
word2vec向量相似性- Tensorboard Projector:Tensorflow开源的Web应用,可以接收模型嵌入并在低维空间进行渲染,实现可视化交互。在tensorboard主页上可以查看Wikipedia和MNIST语料库的示例投影。建议读者花时间具体了解下映射、滤波、嵌入空间以及各种降维算法。
3.降维算法:尽管模型嵌入维度为100,但人眼只能看到3维物品,为此,我们需要将矢量压缩为2维或3维形式。
方法a:主成分分析PCA。一种常用的降维算法,可提高模型的可解释性,同时最大程度地减少信息丢失。其主要思想是,构建新的互不相关的主成分,最大程度地提高方差,即将包含最大信息的特征转化为低维主成分。根据主成分增量方差(如90%的方差)确定截止值。
方法b:t分布随机邻域嵌入TSNE。一种用于探索高维数据的非线性降维算法,将多维数据映射到适合于人类观察的两个或多个维度。该算法的关键在于最小化两个分布之间的差异,即测量输入对象的成对相似性的分布以及相应低维嵌入点的成对相似性的分布。
PCA和TSNE之间的主要区别为:一是PCA为线性降维,而TSNE是非线性度降维;二是目标函数不同,PCA试图保留全局数据结构,而TSNE保留局部结构。
Geeks For Geeks更详细的指出了TSNE和PCA之间的八项区别,为人们提供了很好的参考。
4.MovieLens数据集:作为电影推荐系统的标准数据集,该数据集提供[userid-movieid]数据,包含58,000电影和2,600万评分。自1997年以来,该数据对于推动推荐系统的发展起着重要作用。在Google books搜索“ movielens”得到2,750个结果,在Google Scholar搜索得到7,580个结果,MovieLens数据集的影响可见一斑。应用该数据集可基于SVD矩阵或神经网络构建面向电影条目或是用户的推荐系统,并根据过去的偏好预测新用户评分。
根据上述这些概念,我们可以创建一个电影推荐的Web应用,使用的电影数据包括3700Netflix电影和上述数据集中的58k电影。(数据源见此)
就像word2vec嵌入将相近单词映射到向量空间后距离较小,我们在100维向量空间中对电影进行嵌入,这样就将数据维度从58k(类似one-hot表示)减少到100k(嵌入表示)。
输入MovieLens数据集,该数据集包含用户对电影的评分,分值从0到5。为避免噪声,MovieLens剔除了评分次数低于20且统计不准确的用户。同时,该数据集有诸多版本,范围从[1k用户* 1.7k电影]到[280k用户* 58k电影],使用时请注意查看。对基于用户的协同过滤,可以忽略分级质量,以0/1表示用户是否对电影进行评分。
根据之前的介绍,电影推荐可分为以下三种类型:
1.基于流行度:标识过去X时段内最受欢迎(观看最多)的电影,将这些电影推荐给所有用户。
2.基于电影属性:根据电影的元标记(如演员,导演,语言,发行年份等)进行推荐。但这样的缺点是,电影的属性不会随时间改变,无法考虑用户行为进行实时推荐。
3.基于用户:根据用户的观看模式和喜好,对用户进行分组,为用户推荐同组内其他用户观看的电影。例如,如果我观看了Inception和Dark Knight,其他看过这两部电影的人也喜欢看Prestige,那么推荐给我Prestige是较好的选择。
关于基于电影的协同过滤创建推荐系统,我之前写过一篇详细的博客。感兴趣的读者可以点此查看,并将推荐结果与基于用户的推荐结果进行比较。
对于新兴的OTT平台,由于没有资源生成元标签和标注电影,同时希望用户与平台进行隐式交互,因此基于用户的协同过滤(CF)方法是最适合的。至于像Netflix,Youtube这样的大公司,实际上使用Prime-Video混合推荐方法。在本文中,我们仅讨论基于用户的协同过滤,即通过用户矢量表征电影。数据集结构如下:
MovieLens输入数据格式与word2vec嵌入类似,我们通过用户ID训练浅层神经网络。经过训练,我们在用户ID嵌入中实现类似“网球-费德勒”的关系。至此,我们可以找到相似的用户,并可以将用户分为几类,通过推送或电子邮件发送有针对性的讯息。除了基于相似用户的推荐方法,我们还可以根据电影进行推荐,这就需要对电影信息进行类似操作了。
接下来是句子嵌入,即将用户视为句子,捕获句子的语义相似性。通过BERT,Elmo,Doc2Vec和Universal Sentence Encoder等方式均可方便的实现句子嵌入,具体选择哪种方式主要取决于模型的速度,根据我的测试,Fast_Sentence_Embeddings(FSE)是我比较推荐的方法,该方法直接根据各词的word2vec生成复合向量。对于BERT这样的SOTA系统而言,用户ID很难表现出语义相似性,因此,即使使用经过Wikipedia或GoogleNews预训练的模型,也不会有太大差异,这样,模型的速度就成为唯一的衡量标准。FSE每秒可处理约500K句子,而预训练编码模型低于每秒100句。
之后,将句子向量投影到多维空间中。例如,"Obama speaks to the media in Illinois" 和"The President greets the press in Chicago"表达的意思相近,在多维空间中距离就比较近。
基于上下文的句子相似性Movielens数据的电影嵌入代码:
from datetime import datetime
from gensim.models import Word2Vec
from fse import IndexedList
Data Inputs
movies=pd.read_csv('ml-latest/movies.csv')
links=pd.read_csv('ml-latest/ratings.csv')
links=links.sample(frac=0.05)
links['movieId']=links['movieId'].astype('str')
links['userId']=links['userId'].astype('str')
def combine(kw):
a=1
kw=kw.tolist()
size=len(kw)
base=[]
for i in range(0,size):
print(kw[0][i].split(" "))
string=kw[i].split(",")
print(string)
base=base+string
if(len(base)>2):
base = ','.join(base)
return base
s_test=links
s_test=s_test[['userId','movieId']].drop_duplicates()
s_test['keywords_comb']=s_test.groupby(['movieId'])['userId'].transform(combine)
print("Start of Word2Vec",datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
data=s_test[['movieId','keywords_comb']].drop_duplicates()
data['word_count'] = data.keywords_comb.str.count(',')+1
data=data[data['word_count']>5]
data['tokenise'] = data['keywords_comb'].astype('str').apply(lambda x: [x for x in x.split(',')])
a1=data['tokenise'].tolist()
model_items = Word2Vec(a1, size=100)
data=data.dropna()
print("Start of Sentence To vec",datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
sent=data['keywords_comb'].astype('str').apply(lambda x: [x for x in x.split(',')]).tolist()
s = IndexedList(sent)
from fse.models import uSIF
model = uSIF(model_items, lang_freq="en")
model.train(s)
完成影片嵌入后,我们将结合tensorboard和Github完成电影推荐系统的部署。特别感谢Google对tensorboard开源的工作。
使用嵌入结构构建web步骤如下:
1.将嵌入数据上传到GitHub gist,并在config JSON中进行更新。对于初学者,可以直接使用我在此托管的嵌入数据。
2.将元数据上传到Github gist上,以便图示节点带有标签。
3.创建一个JSON文件并将URI提供给TensorflowL,见JSON配置示例。
Github输入配置文件4.部署Web应用程序!
web应用包括以下两种:a. Floating recommender without images and b. Floating recommender with images
Ratatouille示例5.使用tensorboard可视化交互,单击某一电影即可查找类似的电影,还提供TSNE或PCA降维操作。
总结:本文介绍了如何处理Movielens数据集,矢量嵌入(文中指用户ID),基于FSE的句子相似度矩阵以及使用Google的TensorFlow部署web电影推荐应用。
带有电影海报的推荐页面希望读者自行在电影或其他相关数据集上DIY自己的Web应用程序。如果您遇到任何问题或有其他有趣的想法,欢迎交流。
其他可用于推荐的数据集:
1. 图书 https://www.kaggle.com/zygmunt/goodbooks-10k
2. 电子商务产品 https://www.kaggle.com/c/instacart-market-basket-analysis
4. 美食 https://github.com/hasan-kamal/Cuisine-Prediction
AI研习社是AI学术青年和AI开发者技术交流的在线社区。我们与高校、学术机构和产业界合作,通过提供学习、实战和求职服务,为AI学术青年和开发者的交流互助和职业发展打造一站式平台,致力成为中国最大的科技创新人才聚集地。
如果,你也是位热爱分享的AI爱好者。欢迎与译站一起,学习新知,分享成长。
网友评论