基于用户的协同过滤算法

本文数据集和代码参考该博客https://blog.csdn.net/qq_25948717/article/details/81839463

算法思想:

1. 找到与目标用户兴趣相似的用户集合,计算用户——电影矩阵的行向量之间的欧式距离(或者皮尔逊系数、余弦相似度)

2. 找到这个集合中用户喜欢的、并且目标用户没有听说过的物品推荐给目标用户

数据集:   ml-latest-small(1MB): http://files.grouplens.org/datasets/movielens/ml-latest-small.zip

数据集中本次用到的两个文件为 movies.csv和ratings.csv

使用pandas中的merge函数将两个文件按照userID合并到一起,生成data.csv

import pandas as pd
# movies = pd.read_csv("F:\ml-latest-small\movies.csv")
# ratings = pd.read_csv("F:\ml-latest-small\\ratings.csv")##这里注意如果路径的中文件名开头是r,要转义。
# data = pd.merge(movies,ratings,on = 'movieId')#通过两数据框之间的movieId连接
# data[['userId','rating','movieId','title']].sort_values('userId').to_csv('F:\ml-latest-small\data.csv',index=False)
# left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
#                              'A': ['A0', 'A1', 'A2', 'A3'],
#                              'B': ['B0', 'B1', 'B2', 'B3']})
# right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
#                               'C': ['C0', 'C1', 'C2', 'C3'],
#                               'D': ['D0', 'D1', 'D2', 'D3']})
# data = pd.merge(left,right,on='key')
# print(left)
# print(data)
file = open("F:\ml-latest-small\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]


for line in file.readlines()[1:22]:
    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])
    print(res)
    return res[:10]


# RES = top10_simliar('1')
# print(RES)

########################################################################
# 根据用户推荐电影给其他人
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)

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
用户协同过滤算法是一种常见的推荐算法,它通过分析用户之间的相似性,来给用户推荐相似用户喜欢的物品。具体实现方式是,首先根据用户之间的历史行为数据(如购买记录、评分记录等),计算用户之间的相似度,然后利用相似用户的历史行为数据,推荐给目标用户他们喜欢的物品。 下面是一个简单的基于用户协同过滤算法的Python代码: ```python import numpy as np # 历史行为数据 data = np.array([ [5, 3, 0, 1, 4], [1, 0, 0, 5, 1], [4, 3, 0, 0, 5], [0, 1, 5, 4, 4], [5, 4, 4, 0, 0] ]) # 计算用户相似度 def similarity(user1, user2): return np.dot(user1, user2) / (np.linalg.norm(user1) * np.linalg.norm(user2)) # 给定目标用户id,计算推荐物品列表 def recommend(target_id): target_user = data[target_id] similarities = [] for i in range(len(data)): if i != target_id: sim = similarity(target_user, data[i]) similarities.append((i, sim)) similarities.sort(key=lambda x: x, reverse=True) top_similarities = similarities[:2] recommended_items = [] for item_id in range(len(target_user)): if target_user[item_id] == 0: score = 0 count = 0 for sim_id, sim_score in top_similarities: if data[sim_id][item_id] != 0: score += sim_score * data[sim_id][item_id] count += sim_score if count > 0: recommended_items.append((item_id, score/count)) recommended_items.sort(key=lambda x: x, reverse=True) return recommended_items # 测试代码 print(recommend(0)) # 给id为0的用户推荐物品 ``` 代码中的`data`是历史行为数据矩阵,其中每一行表示一个用户对各个物品的行为数据,0表示未有行为。`similarity`函数用于计算两个用户之间的相似度,这里采用的是余弦相似度计算方法。`recommend`函数则是用于给定目标用户id,计算出推荐的物品列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值