ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python 根据打分数据对某用户进行推荐

2022-02-28 12:04:11  阅读:181  来源: 互联网

标签:index Python 电影 用户 user print 打分


Python 根据打分数据对某用户进行推荐

代码仓库:https://github.com/SKPrimin/PythonCrawler/tree/master/%E7%94%B5%E5%BD%B1%E6%8E%A8%E8%8D%90

编写程序,生成数据模拟(也可以使用网上爬取的真实数据)多人对多部定影的打分(1~5分),然后根据这些数据对某用户A进行推荐。

推荐规则为:在已有的数据中选择与该用户A的爱好最相似的用户B,然后从最相似的用户B已看过但用户A还没看过的电影中选择B打分最高的电影推荐给用户A。其中,相似度的计算标准:

(1)两个用户共同打分过的电影越多,越相似;

(2)两个用户对共同打分的电影的打分越接近,越相似。

实现

生成数据模拟

import random

from openpyxl import Workbook

user = ['用户1', '用户2', '用户3', '用户4', '用户5', '用户6', '用户7', '用户8',
        '用户9', '用户10', '用户11', '用户12', '用户13', '用户14', '用户15']
# 实例化
wb = Workbook()
# 激活 worksheet
ws = wb.active
# 设置表头

ws.append(['用户', '电影1', '电影2', '电影3', '电影4', '电影5', '电影6', '电影7', '电影8', '电影9', '电影10'])

# i 为用户数 j为电影数
for i in range(15):
    numscore = []
    numscore.append(user[i])
    for j in range(10):
        # 生成电影j的分数
        numscore.append(random.randint(0, 5))
    # 生成第i行数据
    ws.append(numscore)

wb.save('电影用户评价信息.xlsx')

通过这种方式,我们可以一个随机出来的打分表

用户 电影1 电影2 电影3 电影4 电影5 电影6 电影7 电影8 电影9 电影10
用户1 0 4 4 0 5 2 0 3 1 5
用户2 1 1 1 4 5 4 1 3 3 0
用户3 3 4 2 3 2 4 5 2 2 2
用户4 3 5 5 0 4 2 2 1 2 2
用户5 2 0 1 2 1 3 0 5 5 1
用户6 1 0 0 0 0 1 5 1 4 5
用户7 5 1 0 0 4 3 1 2 1 1
用户8 0 5 2 1 3 2 4 5 5 4
用户9 3 3 2 3 0 0 0 4 5 3
用户10 2 2 3 1 0 5 3 4 3 4
用户11 2 0 1 1 5 3 1 0 5 3
用户12 5 1 2 1 3 3 4 4 3 4
用户13 5 2 5 5 4 3 3 1 0 3
用户14 2 4 5 0 3 2 0 2 4 0
用户15 2 1 4 2 5 1 0 5 4 4

数据分析推荐

读取数据

  • 读取excel表格数据,并存放于一个字典中
from openpyxl import load_workbook

# 打开文件及表
wb = load_workbook('电影用户评价信息.xlsx')
ws = wb["Sheet"]

'''使用演员作为键,使用包含该演员参演电影名称的集合作为“值”'''
fimeDict = dict()
i = 0
# 遍历Excel文件中的所有行
for index, row in enumerate(ws.rows):
    # 跳过表头,对于每一行有效数据,获取每一行的电影名称和演员清单,
    if index == 0:
        continue
    # 获取电影名称和演员列表
    user = row[0].value
    fimescore = [row[i].value for i in range(1, 11)]
    # 得到评分字典,评价用户作为键,评分列表作为值
    fimeDict[user] = fimescore

print("评分字典:{}".format(fimeDict))

评分字典:{'用户1': [0, 4, 4, 0, 5, 2, 0, 3, 1, 5], '用户2': [1, 1, 1, 4, 5, 4, 1, 3, 3, 0],...

用户A读入
# 假设来了个新用户
username = "用户A"
user = [4, 0, 4, 4, 0, 0, 2, 0, 0, 5]
print(f"新来的用户为{username}:{user}")

共同打分过的电影多的用户

  • 先找出第一个最高分用户

filmSamenum = 0  # 共同打分的数目
filmSameNumDict = {}
for key, value in fimeDict.items():
    # 共同打分的电影分析
    filmiswatch = []
    for i in range(len(user)):
        # 如果双方都看了 ,便为True
        filmiswatch.append(bool(value[i]) & bool(user[i]))
    # 统计True的个数,即双方都看的个数
    filmSamenum = filmiswatch.count(True)
    # 将此用户名用户名与共同观看个数放入字典
    filmSameNumDict[key] = filmSamenum
print(filmSameNumDict)
# 调用max函数找出最大值对应的键 但此方法只会找到返回一个值
keyName = max(filmSameNumDict, key=filmSameNumDict.get)
print("第一个最高匹配人为:{}".format(keyName))

# 再次遍历查看有没有其他的用户观看次数一样
userSame = []
maxScore = filmSameNumDict[keyName]
for key, value in filmSameNumDict.items():
    # 如果观看次与最大值相同添加进列表
    if value == maxScore:
        userSame.append(key)
print("共同打分过的电影多的用户为:{}".format(userSame))

第一个最高匹配人为:用户3

  • 根据最高分找出其他观看次数一样的用户
# 再次遍历查看有没有其他的用户观看次数一样
userSame = []
maxScore = filmSameNumDict[keyName]
for key, value in filmSameNumDict.items():
    # 如果观看次与最大值相同添加进列表
    if value == maxScore:
        userSame.append(key)
print("共同打分过的电影多的用户为:{}".format(userSame))

共同打分过的电影多的用户为:['用户3', '用户10', '用户11', '用户12', '用户13']

打分越接近的用户

# 开始对相同次数的用户进行第二轮推荐
userScoreDifferentDict = {}
for username in userSame:
    score = 0
    for index, userscore in enumerate(fimeDict[username]):
        # 计算两个用户的打分差距
        if userscore != 0 and user[index] != 0:
            score += abs(userscore - user[index])
    # 将计算出的
    userScoreDifferentDict[username] = score
print("相似用户的得分字典为:{}".format(userScoreDifferentDict))

相似用户的得分字典为:{'用户3': 10, '用户10': 8, '用户11': 11, '用户12': 9, '用户13': 6}

转换出电影名

# 统计出其观看电影的清单fimeName = ['电影1', '电影2', '电影3', '电影4', '电影5', '电影6', '电影7', '电影8', '电影9', '电影10']
selectefimeName = []
selecteName = min(userScoreDifferentDict, key=userScoreDifferentDict.get)
for index, fime in enumerate(fimeDict[selecteName]):
    if fime != 0:
        selectefimeName.append(fimeName[index])
print("最高匹配人为:{0},他所观看的电影为{1}".format(selecteName, selectefimeName))

最高匹配人为:用户13,他所观看的电影为['电影1', '电影2', '电影3', '电影4', '电影5', '电影6', '电影7', '电影8', '电影10']

找出用户未看过的电影

# 求出用户观看的电影列表
userfimeName = []
for index, fime in enumerate(user):
    if fime != 0:
        userfimeName.append(fimeName[index])

# 转成集合求差集
selectefimeName = set(selectefimeName)
userfimeName = set(userfimeName)
finallFimeName = selectefimeName.difference(userfimeName)
print("推荐的电影如下:{}".format(finallFimeName))

推荐的电影如下:{'电影6', '电影5', '电影8', '电影2'}

推荐评分最高电影

# 求出这些电影中评分最高的一个
finallScore = 0
finallFime = ""
for fime in finallFimeName:
    # 找到这个电影的索引
    index = fimeName.index(fime)
    # 根据索引找到分数
    score = fimeDict[selecteName][index]
    # 比较哪那个高
    if finallScore < score:
        finallScore = score
        finallFime = fime
    # 如果是最高评分则无需继续查找了
    if score == 5:
        break
print("最终推荐的电影为:{}".format(finallFime))

最终推荐的电影为:电影5

本次模拟的推荐算法是当今社会常见的算法应用,平台的大数据推荐在我们生活中屡见不鲜。本次我在计算标准的指引下,也亲身实际设计了一次大数据推荐算法,本次生成的数据先保存至excel表格,用户作为行,电影名称作为列,实现了评分的存储。在数据读取时,通过同样的方式,以用户名作为键,评分列表作为值进行读取,这也与我们实际应用中的表单传值使用的json数据有异曲同工之处,都是字典搭配列表。读取时首先要统计其他用户与用户A共同打分过的电影数,这里我采用的bool的方式,进行&运算,便得到了一个是否都打过分的布尔列表,然后统计True的个数便可以得出。接下来第二轮比较评分差异时,便通过双循环算出各用户与用户A打分之差,统计时需要将有人未看的电影去除。在最后的找出要推荐的电影阶段,先是通过索引找出对应的电影名称,再将列表转为集合求出差集,最后再次根据索引去查找分数,找出其打分最高的那个电影。

标签:index,Python,电影,用户,user,print,打分
来源: https://www.cnblogs.com/skprimin/p/15944964.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有