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

该博客介绍了如何使用Python构建一个简单的电影推荐系统。首先,通过随机生成用户对多部电影的评分数据并存储到Excel文件中。然后,读取这些数据并进行分析,找出与新用户A评分习惯最相似的用户。相似度计算基于两个标准:共同评分的电影数量和评分一致性。推荐规则是选择与用户A最相似的用户B,推荐B评分最高但用户A未看过的电影。最终,演示了如何找出并推荐评分最高的电影给用户A。
摘要由CSDN通过智能技术生成

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 randomfrom openpyxl import Workbookuser = ['用户1', '用户2', '用户3', '用户4', '用户5', '用户6', '用户7', '用户8',        '用户9', '用户10', '用户11', '用户12', '用户13', '用户14', '用户15']# 实例化wb = Workbook()# 激活 worksheetws = 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
用户10440520315
用户21114541330
用户33423245222
用户43550422122
用户520 干部培训 http://www.ctbuedp.com/ 12130551
用户61000015145
用户75100431211
用户80521324554
用户93323000453
用户102231053434
用户112011531053
用户125121334434
用户135255433103
用户142450320240
用户152142510544

数据分析推荐

读取数据
  • 读取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] = fimescoreprint("评分字典:{}".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] = filmSamenumprint(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] = scoreprint("相似用户的得分字典为:{}".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 = 0finallFime = ""for fime in finallFimeName:    # 找到这个电影的索引    index = fimeName.index(fime)    # 根据索引找到分数    score = fimeDict[selecteName][index]    # 比较哪那个高    if finallScore < score:        finallScore = score        finallFime = fime    # 如果是最高评分则无需继续查找了    if score == 5:        breakprint("最终推荐的电影为:{}".format(finallFime))

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

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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值