本例通过943名用户对1664部电影的评分数据,构建协同过滤模型,进而推荐电影供用户观看。通过本例,可以了解协同过滤算法在电子商务智能推荐领域的应用方法,帮助用户更加便捷的获取想要的信息,进而提升用户体验、促进推荐转化。
步骤
1、获取数据;
2、数据探索分析;
3、构建智能推荐模型;
4、评估推荐系统模型。
NO.1 获取数据
数据包含943名用户对1664部电影的打分,评分在1-5分之间,超出规定范围的算异常值。
NO.2 数据探索分析
导入的数据共有99416行,3列,第一列为用户id,第二列为电影名字,第三列为打分。
经过基本的数据验证,发现三列数据均存在缺失的情况(取值为空),且根据打分列,发现数据存在异常值(打分结果不在1-5范围内),因此将存在缺失值和异常值的行删除,删除后,数据剩下99392行。同时,为了进行每部电影的打分数据探索分析,将movie列中的电影名转换为列名,转换后,可观察每部电影的评分用户数及分数的基本分布。
NO.3 构建基于物品的协同过滤推荐模型
基于物品的协同过滤模型(ItemCF)通过分析群体用户的历史偏好,找到相似物品,然后根据个体用户的历史行为为其进行推荐,主要分为计算物品间相似度和生成推荐列表两个步骤。ItemCF可以离线计算,从而提高推荐效率,且利用历史行为进行推荐解释,结果更容易信服,但是推荐精度相对有限,且对于用户偏好的变化不敏感,实时推荐能力较弱。关于ItemCF的更多介绍可参考往期文章推荐算法概述。
在实际应用时,用户的历史行为包含是否浏览网页、是否购买、是否评论、是否转发点赞等,本例中,仅涉及用户对电影的打分,因此不存在其他的行为。得到的电影相似度矩阵如下:
构建ItemCF模型后,得到用户1.0的推荐清单如下:
NO.4 评估推荐系统模型
模型结果评价主要有三种方式,分别为离线测试、用户调查和在线实验。
实现代码
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import math
import operator
from sklearn import model_selection as ms
#step1:获取数据
print("#step1:获取数据")
datafile = pd.read_csv('dataMovieLense.csv')
#print(datafile.head(10))
#step2:数据探索分析
print("#step2:数据探索分析")
datafile.info()#数据基本信息
datafile.score.isna().sum()#数据缺失值数量
datafile = datafile.dropna(axis=0)#删除存在缺失值的行
datafile.loc[datafile['score'] > 5]#存在异常值
datafile = datafile.drop(datafile[datafile.score >5].index)#删除异常值
#print(datafile.shape)#输出数据维数
datafile_trans = pd.pivot(datafile, index='user', columns='movie', values='score')#将movie中的电影名转换为列名
#print(datafile_trans.head())
datafile_trans.describe()
df_index = datafile_trans.index
df_columns = datafile_trans.columns
datafile_trans = datafile_trans.fillna(0).to_numpy()
#step3:构建智能推荐模型
print("#step3:构建智能推荐模型")
from sklearn.metrics.pairwise import cosine_similarity
item_similarity = cosine_similarity(datafile_trans.T)#电影间的相似度矩阵
pd.DataFrame(item_similarity,index=df_columns,columns = df_columns).head()
class ItemCf():
########获得初始化数据,字典格式
def __init__(self,data):
data_dic = {}
#self.itemSim = dict()
for line in data.itertuples():
if not line[1] in data_dic.keys():
data_dic[line[1]]={line[2]:line[3]}
else:
data_dic[line[1]][line[2]]=line[3]
self.data = data_dic
self.ItemSimilarity()
def ItemSimilarity(self):
self.itemSim = dict()
movie_popular = dict() #item_user_count{item: likeCount} the number of users who like the item
count = dict() #count{i:{j:value}} the number of users who both like item i and j
for user,movies in self.data.items():
for movie in movies:
if movie not in movie_popular:
movie_popular[movie] = 0
movie_popular[movie] += 1
movie_count = len(movie_popular)
print('Total movies: %d'% movie_count)
for user,movies in self.data.items():
for m1 in movies:
for m2 in movies:
if m1 == m2:
continue
self.itemSim.setdefault(m1,{})
self.itemSim[m1].setdefault(m2,0)
self.itemSim[m1][m2] += 1/math.log(1+len(movies))
print('Build co-rated users matrix success!')
for m1,related_movies in self.itemSim.items():
for m2,count in related_movies.items():
if movie_popular[m1] == 0 or movie_popular[m2] == 0:
movie_sim_matrix[m1][m2] = 0
else:
self.itemSim[m1][m2] = count / math.sqrt(movie_popular[m1]*movie_popular[m2])
print('Calculate movie similarity matrix success!')
max_w = 0
for m1,related_movies in self.itemSim.items():
for m2,_ in related_movies.items():
if self.itemSim[m1][m2] > max_w:
max_w = self.itemSim[m1][m2]
for m1,related_movies in self.itemSim.items():
for m2,_ in related_movies.items():
self.itemSim[m1][m2] = self.itemSim[m1][m2]/max_w
def Recomand(self,user,n_sim_movie=10,n_rec_movie=5):
K = n_sim_movie
N = n_rec_movie
rank = {}
watched_movies = self.data[user]
for movie,rating in watched_movies.items():
for related_movie,w in sorted(self.itemSim[movie].items(),key=operator.itemgetter(1),reverse=True)[:K]:
if related_movie in watched_movies:
continue
rank.setdefault(related_movie,0)
rank[related_movie] += w*float(rating)
return sorted(rank.items(),key=operator.itemgetter(1),reverse=True)[0:N]
if __name__=='__main__':
datafile['user']=datafile['user'].astype(str)
print(datafile.head())
itemCf=ItemCf(data=datafile)
recommandList=itemCf.Recomand('1.0',20,10)
print('用户1.0的推荐结果为:' + str(recommandList))
参考内容:
1、《R语言商务数据分析实战》