电影推荐实例--基于协同过滤和DL特征提取的比较

最近读到了一篇有意思的文章:如何用深度学习推荐电影,我顺着文章的思路实现了一遍,补全了原文中缺失的code,也加入了一些避免重复操作的code,亦做记录亦作分享。本项目主要实现了基于「1」协同过滤「2」DL特征提取进行电影推荐。

数据集

来源于 MovieLens 中的ml-latest-small.zip,当然也可以从本文最后我的github中找到。
本项目主要用到其中的两个csv文件:

  • ml-latest-small/ratings.csvz:包含671个用户,共100004个打分
  • ml-latest-small/links.csv:包含9125个电影及其IMDBid和TMDBid

分别长这样:

#ratings.csvz:
   userId  movieId  rating   timestamp
0       1       31     2.5  1260759144
1       1     1029     3.0  1260759179
2       1     1061     3.0  1260759182
3       1     1129     2.0  1260759185
4       1     1172     4.0  1260759205
......

#links.csv:
   movieId  imdbId   tmdbId
0        1  114709    862.0
1        2  113497   8844.0
2        3  113228  15602.0
3        4  114885  31357.0
4        5  113041  11862.0
......

扒电影海报的网站:
Movie Database,网站提供API,申请不麻烦。不过你们要是能够保证不做坏事的话,可以悄悄告诉你在github里我没有删掉我的API。

理论背景

粗略地说,推荐系统有三种类型(不包括简单的评级方法):

  • 基于内容的推荐
  • 协同过滤
  • 混合模型

“基于内容的推荐”是一个回归问题,我们把电影内容作为特征,对用户对电影的评分做预测。

“协同过滤”中,一般无法提前获得内容特征。是通过用户之间的相似度(用户们给了用一个电影相同的评级)和电影之间的相似度(有相似用户评级的电影)来学习潜在特征,同时预测用户对电影的评分。在学习了电影的特征之后,我们便可以衡量电影之间的相似度,并根据用户历史观影信息,向他/她推荐最相似的电影。

“基于内容的推荐”和“协同过滤”是10多年前最先进的技术。很显然,现在有很多模型和算法可以提高预测效果。比如,针对事先缺乏用户电影评分信息的情况,可以使用隐式矩阵分解,用偏好和置信度取代用户电影打分——比如用户对电影推荐有多少次点击,以此进行协同过滤。另外,我们还可以将“内容推荐”与“协同过滤”的方法结合起来,将内容作为侧面信息来提高预测精度。这种混合方法,可以用“学习进行排序”(”Learning to Rank” )算法来实现。

在该项目中,采用的方法是“协同过滤”。首先,用电影和用户相似度来找出相似度最高的海报,并基于相似度做电影推荐。然后,我将讨论如何Deep Learning学习潜在特征、做电影推荐。最后会谈谈如何在推荐系统中使用深度学习。

电影相似性

对于基于协同过滤的推荐系统,首先要建立评分矩阵。其中,每一行表示一个用户,每一列对应其对某一电影的打分。建立的评分矩阵如下:

#!/usr/bin/env python3
import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error

rating_f = 'ml-latest-small/ratings.csv'
link_f   = 'ml-latest-small/links.csv'

df    = pd.read_csv(rating_f,sep=',')
df_id = pd.read_csv(link_f,sep=',')
df    = pd.merge(df,df_id,on=['movieId'])

rating_matrix = np.zeros((df.userId.unique().shape[0],max(df.movieId)))
for row in df.itertuples():
    rating_matrix[row[1]-1,row[2]-1] = row[3]
rating_matrix = rating_matrix[:,:9000] #get first 9000 movies

“ratings.csv”包含用户id,电影id, 评级,和时间信息,其中同一个用户id可能对多个电影进行打分;“links.csv”包含电影id, IMDB id,和TMDB id。这两个文件中包含的电影总数是不同的(rating.csv: 9066, links.csv: 9125)。我们将两个文件依movieId合并,并在此基础上得到评分矩阵rating_matrix[userId:movieId]=grade。

计算评分矩阵的稀疏性:

#Evaluate sparsity of matrix
sparsity = float(len(rating_matrix.nonzero()[0]))
sparsity /= (rating_matrix.shape[0]*rating_matrix.shape[1])
sparsity *= 100
print('Sparsity is {0}%'.format(sparsity))

可以得到sparsity=1.4%,认为是稀疏矩阵。
现在,为了训练和测试,我们将评分矩阵分解成两个矩阵,从每行(userId)评分矩阵中抠出了10个评分,将其放入测试集。

#Splite to train/test matrix
train_matrix = rating_matrix.copy()
test_matrix  = np.zeros(rating_matrix.shape)

for i in range(rating_matrix.shape[0]):
        rating_index = np.random.choice(rating_matrix[i].nonzero()[0],size=10,replace=True) #return a list
        train_matrix[i,rating_index] = 0.0
        test_matrix[i,rating_index] = rating_matrix[i,rating_index]

根据余弦相似性计算两个特征间的夹角(具体过程参见另外一篇博文:余弦相似定理和新闻分类):

cos(θ)=<b,c>bc

即:

cos(θ)=x1y1+x2
  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值