'python案列(电影推荐)'
python的第五次作业
这个是python课的一个小案列,不涉及大数据推荐等等。
只是一个简单的集合应用
问题描述
假设已有大量用户对若干电影的评分数据,现有某用户,也看过一些电影并进行过评分,要求根据已有打分数据为该用户进行推荐。
基本思路
基本思路:用基于用户的协同过滤算法,也就是根据用户喜好来确定与当前用户最相似的用户,然后再根据最相似用户的喜好为当前用户进行推荐。本例采用字典来存放打分数据,格式为{用户1:{电影名称1:打分1, 电影名称2:打分2,...}, 用户2:},首先在已有数据中查找与当前用户共同打分电影(使用集合的交集运算)数量最多的用户,如果有多个这样的用户就再从中选择打分最接近(打分的差距最小)的用户。代码中使用到了random模块中的randrange()函数,用来生成指定范围内的一个随机数。
效果图如下:
解法一
from random import randrange
# 历史电影打分数据,一共10个用户,每个用户对3到9个电影进行评分
# 每个电影的评分最低1分最高5分,这里是字典推导式和集合推导式的用法
data = {'user' + str(i): {'film' + str(randrange(1, 15)): randrange(1, 6)
for j in range(randrange(3, 10))}
for i in range(10)}
# 模拟当前用户打分数据,为5部随机电影打分
user = {'film' + str(randrange(1, 15)): randrange(1, 6) for i in range(5)}
# 最相似的用户及其对电影打分情况
# 两个用户共同打分的电影最多
# 并且所有电影打分差值的平方和最小
f = lambda item: (-len(item[1].keys() & user),
sum(((item[1].get(film) - user.get(film)) ** 2
for film in user.keys() & item[1].keys())))
similarUser, films = min(data.items(), key=f)
# 在输出结果中,第一列表示两个人共同打分的电影的数量
# 第二列表示二人打分之间的相似度,数字越小表示越相似
# 然后是该用户对电影的打分数据
print('known data'.center(50, '='))
for item in data.items():
print(len(item[1].keys() & user.keys()),
sum(((item[1].get(film) - user.get(film)) ** 2
for film in user.keys() & item[1].keys())),
item,
sep=':')
print('current user'.center(50, '='))
print(user)
print('most similar user and his films'.center(50, '='))
print(similarUser, films, sep=':')
print('recommended film'.center(50, '='))
# 在当前用户没看过的电影中选择打分最高的进行推荐
print(max(films.keys() - user.keys(), key=lambda film: films[film]))
解法二
from random import randrange
def diff_value(use, fil):
score = 0
for filmName in fil:
# 计算两个用户的打分差距
score += abs(data[use][filmName] - user[filmName])
return score
# 模拟获取数据
data = {'user' + str(i): {'film' + str(randrange(1, 15)): randrange(1, 6) for j in range(randrange(3, 10))}
for i in range(1, 11)}
print("=====模拟数据=====")
print(data)
# 模拟用户喜好
user = {'film' + str(randrange(1, 15)): randrange(1, 6) for j in range(randrange(3, 10))}
print("=====模拟当前用户喜好=====")
print(user)
film_len = 0 # 共同打分的数目
film_user = "" # 最接近的那个用户
film_score = 0 # 记录分数差距
for key, value in data.items():
film = set(value) & set(user) # 共同打分的电影
# print(key, film)
# 共同电影打分数目相同,则比较分数。
if len(film) == film_len:
if diff_value(key, film) < film_score:
film_len = len(film)
film_user = key
film_score = diff_value(key, film)
if len(film) > film_len:
film_len = len(film)
film_user = key
film_score = diff_value(key, film)
print("=====最相似的用户和他的电影====")
print(film_user, data[film_user])
print("=====推荐的电影如下:======")
def max_score(film):
return data[film_user][film]
# 推荐评分最高的电影
print(max(set(data[film_user]) - set(user), key=max_score))
评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果