超级详细的协同过滤推荐系统+完整Python实现及结果 |
您所在的位置:网站首页 › python推荐算法库 › 超级详细的协同过滤推荐系统+完整Python实现及结果 |
协同过滤推荐系统在我们的日常生活之中无处不在,例如,在电子商城购物,系统会根据用户的记录或者其他的 信息来推荐相应的产品给客户,是一种智能的生活方式。之所以交协同过滤,是因为在实现过滤推荐的时候是根据 其他人的行为来做预测的,基于相似用户的喜好来实现用户的喜好预测。 简要介绍: 通过找到兴趣相投,或者有共同经验的群体,来向用户推荐感兴趣的信息。 举例,如何协同过滤,来对用户A进行电影推荐? 答:简要步骤如下 找到用户A(user_id_1)的兴趣爱好 找到与用户A(user_id_1)具有相同电影兴趣爱好的用户群体集合Set 找到该群体喜欢的电影集合Set 将这些电影Set推荐给用户A(user_id_1) 具体实施步骤如何? 答:简要步骤如下 (1)画一个大表格,横坐标是所有的movie_id,纵坐标所有的user_id,交叉处代表这个用户喜爱这部电影
Move_id_1 Move_id_2 Move_id_3 Move_id_4 Move_id_5 …… Move_id_110w User_id_1 1 1 1
User_id_2 1 1 1 1
User_id_3 1 1 1
1
………….
………….
User_id_10w 1
1
1
如上表: 横坐标,假设有10w部电影,所以横坐标有10w个movie_id,数据来源自数据库 纵坐标,假设有100w个用户,所以纵坐标有100w个user_id,数据也来自数据库 交叉处,“1”代表用户喜爱这部电影,数据来自日志 画外音:什么是“喜欢”,需要人为定义,例如浏览过,查找过,点赞过,反正日志里有这些数据 (2)找到用户A(user_id_1)的兴趣爱好 如上表,可以看到,用户A喜欢电影{m1, m2, m3} (3)找到与用户A(user_id_1)具有相同电影兴趣爱好的用户群体集合Set 如上表,可以看到,喜欢{m1, m2, m3}的用户,除了u1,还有{u2, u3} (4)找到该群体喜欢的电影集合Set 如上表,具备相同喜好的用户群里{u2, u3},还喜好的电影集合是{m4, m5} 画外音:“协同”就体现在这里。 (5)未来用户A(use_id_1)来访问网站时,要推荐电影{m4, m5}给ta。 具体实现步骤:第一步:计算两者之间的相似度 通常会先把二维表格绘制在一个图中总,每个用户数据表示一个点。 度量相似度计算的方法:a.曼哈顿距离计算(计算迅速,节省时间) b.欧氏距离计算(计算两个点之间的直线距离) 数据预处理: 去网站:https://grouplens.org/datasets/movielens/ 下载movieLen数据集 或者 ml-latest-small(1MB): http://files.grouplens.org/datasets/movielens/ml-latest-small.zip ml-latest(234.2MB): http://files.grouplens.org/datasets/movielens/ml-latest.zip 解压读取movies.csv和ratings.csv文件 两个文件的数据格式如下: 结果: 结果(部分): 计算任何两位用户之间的相似度,由于每位用户评论的电影不完全一样,所以兽先要找到两位用户共同评论过的电影 然后计算两者之间的欧式距离,最后算出两者之间的相似度。 #!/usr/bin/env python # encoding: utf-8 """ @Company:华中科技大学电气学院聚变与等离子研究所 @version: V1.0 @author: YEXIN @contact: [email protected] or [email protected] 2018--2020 @software: PyCharm @file: movie_rating_user.py @time: 2018/8/19 17:50 @Desc:采用python字典来表示每位用户评论的电影和评分 """ file = open("E:\PycharmWorks\ML\CollaborativeFiltering\ml-latest\data.csv",'r', encoding='UTF-8')#记得读取文件时加‘r’, encoding='UTF-8' ##读取data.csv中每行中除了名字的数据 data = {}##存放每位用户评论的电影和评分 for line in file.readlines()[1:100]: #注意这里不是readline() line = line.strip().split(',') #如果字典中没有某位用户,则使用用户ID来创建这位用户 if not line[0] in data.keys(): data[line[0]] = {line[3]:line[1]} #否则直接添加以该用户ID为key字典中 else: data[line[0]][line[3]] = line[1] #print(data) """计算任何两位用户之间的相似度,由于每位用户评论的电影不完全一样,所以兽先要找到两位用户共同评论过的电影 然后计算两者之间的欧式距离,最后算出两者之间的相似度 """ from math import * def Euclidean(user1,user2): #取出两位用户评论过的电影和评分 user1_data=data[user1] user2_data=data[user2] distance = 0 #找到两位用户都评论过的电影,并计算欧式距离 for key in user1_data.keys(): if key in user2_data.keys(): #注意,distance越大表示两者越相似 distance += pow(float(user1_data[key])-float(user2_data[key]),2) return 1/(1+sqrt(distance))#这里返回值越小,相似度越大 #计算某个用户与其他用户的相似度 def top10_simliar(userID): res = [] for userid in data.keys(): #排除与自己计算相似度 if not userid == userID: simliar = Euclidean(userID,userid) res.append((userid,simliar)) res.sort(key=lambda val:val[1]) return res[:4] RES = top10_simliar('1') print(RES)用户之间相似度结果:0表示两位的影评几乎一样,1表示没有共同的影评 根据相似度来推荐用户: ######################################################################## #根据用户推荐电影给其他人 def recommend(user): #相似度最高的用户 top_sim_user = top10_simliar(user)[0][0] #相似度最高的用户的观影记录 items = data[top_sim_user] recommendations = [] #筛选出该用户未观看的电影并添加到列表中 for item in items.keys(): if item not in data[user].keys(): recommendations.append((item,items[item])) recommendations.sort(key=lambda val:val[1],reverse=True)#按照评分排序 #返回评分最高的10部电影 return recommendations[:10] Recommendations = recommend('1') print(Recommendations)推荐结果: ================================================================================== 但有时我们会碰到因为两个用户之间数据由于数据膨胀,一方数据大,一方数据小,但是两者称明显的线性关系 我们引入Pearson相关系数来衡量两个变量之间的线性相关性。 Pearson:-1~1 -1:完全负相关 1:完全正相关 0:不相关 相关系数 0.8-1.0 极强相关 0.6-0.8 强相关 0.4-0.6 中等程度相关 0.2-0.4 弱相关 0.0-0.2 极弱相关或无相关 公式: python代码: ######################################################################### ##计算两用户之间的Pearson相关系数 def pearson_sim(user1,user2): # 取出两位用户评论过的电影和评分 user1_data = data[user1] user2_data = data[user2] distance = 0 common = {} # 找到两位用户都评论过的电影 for key in user1_data.keys(): if key in user2_data.keys(): common[key] = 1 if len(common) == 0: return 0#如果没有共同评论过的电影,则返回0 n = len(common)#共同电影数目 print(n,common) ##计算评分和 sum1 = sum([float(user1_data[movie]) for movie in common]) sum2 = sum([float(user2_data[movie]) for movie in common]) ##计算评分平方和 sum1Sq = sum([pow(float(user1_data[movie]),2) for movie in common]) sum2Sq = sum([pow(float(user2_data[movie]),2) for movie in common]) ##计算乘积和 PSum = sum([float(user1_data[it])*float(user2_data[it]) for it in common]) ##计算相关系数 num = PSum - (sum1*sum2/n) den = sqrt((sum1Sq-pow(sum1,2)/n)*(sum2Sq-pow(sum2,2)/n)) if den == 0: return 0 r = num/den return r R = pearson_sim('1','3') print(R)pearson系数结果:
|
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |