# 电影推荐系统
本次课程作业在 `small-movielens` 数据集的基础上,对用户、电影、评分数据进行了处理,然后根据 `Pearson` 相关系数计算出用户与其他用户之间的相似度,根据相似度进行推荐和预测评分,最后再根据数据集中的测试数据,计算该推荐系统的[`MAE`](https://baike.baidu.com/item/%E5%B9%B3%E5%9D%87%E7%BB%9D%E5%AF%B9%E8%AF%AF%E5%B7%AE/9383373?fr=aladdin)等。
## **1. 数据描述**
数据集来源于 [MovieLens|GroupLens](https://grouplens.org/datasets/movielens/) 网站。完整的数据集是由 `943` 个用户对 `1682` 个项目的 `100000` 个评分组成。每位用户至少对 `20` 部电影进行了评分。用户和项从 `1` 开始连续编号。数据是随机排列的。这是一个以选项卡分隔的:`用户id`|`项id`|`分级`|`时间戳` 列表。从 `1970年1月1日` UTC 开始,时间戳是[`unix时间戳`](https://baike.baidu.com/item/unix%E6%97%B6%E9%97%B4%E6%88%B3/2078227?fr=aladdin)。在这些数据集的基础上,`small-movielens` 还包括 `u1-u5`,`ua`,`ub` 等七组测试集 `(*.base)`/训练集 `(*.test)` 数据。其中,`u1-u5` 是以 `8:2` 的比例随机生成互斥的训练集和测试集;`ua`、`ub` 是按照 `9:1` 的比例随机生成的互斥的训练集和测试集,不同的是,这两组数据的测试集中每个用户是对正好 `10` 部不同电影进行了评分。数据集如下图所示。
![](https://www.writebug.com/myres/static/uploads/2021/12/8/62186a06127bc5c76d5fc8c843b4729d.writebug)
## **2. 变量说明**
+ **users** :保存所有用户,不重复 `list` 类型
存储结构:`[user1, user2,...]`
+ **userWatchedMovie** :保存所有用户看过的所有电影,字典嵌套字典类型
存储结构:`{user1:{movie1:rating1, movie2:rating2, ...}, user2:{...},...}`
+ **movieUser** :保存用户与用户之间共同看过的电影,字典嵌套字典嵌套 `list`
存储结构:`{user1:{user2:[movie1,...],user3:[...],...},user2:{user3:[...],...},...}`
+ **userSimilarity** :保存用户与用户之间的相似度(皮尔逊相似度)
存储结构:`{user1:{user2:sim, user3:sim,...}, user2:{user3:sim, ...}, ...}`
+ **allUserTopNSim** :保存每个用户都取前 `n=10` 个最相似的用户,以及相似度
存储结构:`{user1:{user01:sim,user02:sim,...},user2:{user01:sim,...},...}`
+ **recommendedMovies** :从最相似的用户中推荐,每个相似用户推荐两部,同时计算出预测值并保存在这个变量里
存储结构:`{user1:{user01:{movie01:predictionRating,...},user02:[...],...},user2:{user01:[...],...},...}`
+ **usersTest** :测试集文件中的所有用户
存储结构:同 `users`
+ **userWatchedMovieTest** :测试集文件中所有用户看过的所有电影
存储结构:同 `userWatchedMovie`
+ **movieAlsoInTest** :保存推荐的电影正好也在用户测试数据中看过的那一些电影,以便后面进行 MAE 计算
存储结构:`{user1:[movie1,movie2,...],...}`
+ **averageRating** :保存每个用户对被推荐的电影的预测平均分
存储结构:`{user1:{movie01:[count,sumPreRating,averageRating],...},...}`
+ **eachUserMAE** :保存对每个用户而言计算出的 `MAE`
存储结构:`{user1:MAE,user2:MAE,...}`
## **3. 程序介绍**
+ **首先对数据进行处理**,可以看到原始数据文件 `u1.base` 中的数据如下图所示
![](https://www.writebug.com/myres/static/uploads/2021/12/8/7c580c0c9957b193cc7d5684e1ce1fd2.writebug)
数据是由 `(userId, movieId, rating,timestamp)` 四个部分组成,我们这里使用的是前三个数据属性。用变量 `users` 保存所有的用户 `ID`,`userWatchedMovie` 保存所有的用户看过的所有的电影
![](https://www.writebug.com/myres/static/uploads/2021/12/8/fdc229ff5cd14640e48db22fb583b60b.writebug)
然后是对测试数据文件的读取,同上面做类似的处理
+ **计算用户与用户之间共同看过的电影**
![](https://www.writebug.com/myres/static/uploads/2021/12/8/306db3f4ab8cd61182ea5a9c7477c854.writebug)
+ **计算用户与用户之间的相似度**
在这个部分我们利用 `Pearson` 相关系数计算出两两用户之间的相似度
```
avgUserA = 0
avgUserB = 0
numerator = 0
denominatorA = 0
denominatorB = 0
count = len(movieUser[a][b])
factor = 0
if count > 20:
factor = 1.0
else:
if count < 0:
factor = 0
else:
factor = (-0.0025 * count * count) + (0.1 * count)
for movie in movieUser[a][b]:
avgUserA += float(userWatchedMovie[a][movie])
avgUserB += float(userWatchedMovie[b][movie])
avgUserA = float(avgUserA / count)
avgUserB = float(avgUserB / count)
for m in movieUser[a][b]:
tempA = float(userWatchedMovie[a][m]) - avgUserA
tempB = float(userWatchedMovie[b][m]) - avgUserB
numerator += tempA * tempB
denominatorA += pow(tempA, 2) * 1.0
denominatorB += pow(tempB, 2) * 1.0
if denominatorA != 0 and denominatorB != 0:
userSimilarity[a][b] = factor * (numerator / (sqrt(denominatorA * denominatorB)))
else:
userSimilarity[a][b] = 0
```
+ **每个用户都取前 `n` 个最相似的用户,以便后续进行推荐,例如 `n=10`**
```
for compareUserId in users:
if currentUserId == compareUserId:
break
else:
singleUserSim[compareUserId] = userSimilarity[compareUserId][currentUserId]
if int(currentUserId) != len(users):
singleUserSim.update(userSimilarity[currentUserId])
singleSortedSim = sorted(singleUserSim.items(), key=lambda item: item[1], reverse=True)
singleTopN = singleSortedSim[:n]
for single in singleTopN:
allUserTopNSim[currentUserId][single[0]] = single[1]
```
![](https://www.writebug.com/myres/static/uploads/2021/12/8/536c63d6a417e10dd1a9f053b81f1cbf.writebug)
+ **从最相似的用户中推荐 number 部电影**,例如每个相似用户推荐两部,那么每个用户就能得到推荐的 `20` 部电影
```
if movie not in userWatchedMovie[oneUser].keys():
if int(oneUser) < int(simUser):
length = len(movieUser[oneUser][simUser])
sumOne = 0.0
sumSim = 0.0
for i in movieUser[oneUser][simUser]:
sumOne += userWatchedMovie[oneUser].get(i)
sumSim += userWatchedMovie[simUser].get(i)
sumSim += userWatchedMovie[simUser].get(movie)
avgOneUser = sumOne / length
avgSimUser = sumSim / (length + 1)
predictionRating = avgOneUser + (userWatchedMovie[simUser][movie] - avgSimUser)
recommendedMovies[oneUser][simUser][movie] = predictionRating
number += 1
```
![](https://www.writebug.com/myres/static/uploads/2021/12/8/33c8551ef41036b71d2f9e947860b721.writebug)
+ **从推荐的电影和测试集中找到一起看过的电影**
```
movieAlsoInTest = {}
for oneUser in usersTest:
movieAlsoInTest.setdefault(oneUser, [])
for simUser in recommendedWithRating[oneUser].keys():
for movie in recommendedWithRating[oneUser][simUser].keys():
if movie in userWatchedMovieTest[oneUser].keys():
movieAlsoInTest[oneUser].append(movie)
else:
continue
```
![](https://www.writebug.com/myres/static/uploads/2021/12/8/e599ee6f29b0af7dcfdf773f19b92bad.writebug)
+ **计算每个用户被推荐的每部电影的次数和平均分**
```
averageRating = {}
for oneUser in usersTest:
averageRating.setdefault(oneUser, {})
for simUser in recommendedWithRating[oneUser].keys():
for movie in recommendedWithRating[oneUser][simUser].keys():
averageRating[oneUser].setdefault(movie, [0, 0.0, 0.0])
averageRating[oneUser][movie][0] += 1
averageRating[oneUser][movie][1] += recommendedWith
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
本次课程作业在 small-movielens 数据集的基础上,对用户、电影、评分数据进行了处理,然后根据 Pearson 相关系数计算出用户与其他用户之间的相似度,根据相似度进行推荐和预测评分,最后再根据数据集中的测试数据,计算该推荐系统的MAE等。
资源推荐
资源详情
资源评论
收起资源包目录
100011307-基于Python电影推荐系统.zip (50个子文件)
movierecom
pictures
result2_0513.png 14KB
recsysMAE.png 14KB
table01.png 49KB
result4_0513.png 14KB
averageRating01.png 48KB
movieAlsoInTest.png 38KB
chart1_highRating.png 12KB
movieAlsoInTest02.png 36KB
resultMAE_052701.png 14KB
movieAlsoInTest01.png 36KB
result5_0513.png 13KB
eachUserMAE.png 31KB
resultMAE_0513.png 17KB
userWatchedMovie.png 14KB
similarity_highRating.png 50KB
dataSet.png 23KB
resultMAE_052702.png 14KB
result3_0513.png 14KB
averageRating.png 35KB
eachUserMAE01.png 17KB
allUserTop10Sim_highRating.png 49KB
result7_0513.png 14KB
chart1.png 17KB
MAE_highRating.png 14KB
movieUser_highRating.png 41KB
result6_0513.png 15KB
baseData.png 22KB
movieUser.png 42KB
allUserTop10Sim.png 35KB
recoMovieWithRating.png 50KB
README.md 1B
chart2.png 13KB
chart01.png 20KB
result1_0513.png 15KB
codeFiles
dataProcess.py 11KB
computerMAE.py 5KB
README.md 1B
LICENSE 1KB
OtherConsiderations
README.md 7KB
textFiles
allUserTop10Sim.txt 245KB
movieAlsoInTest.txt 12KB
averageRating.txt 230KB
eachUserMAE.txt 8KB
userWatchedMovie.txt 924KB
README.md 1B
recoMovieWithRating.txt 520KB
README.md 11KB
dataFiles
u1.test 383KB
u1.base 1.51MB
README.md 1B
共 50 条
- 1
神仙别闹
- 粉丝: 3796
- 资源: 7471
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 1732537263117202.000000.jpg
- vb.net开发安卓软件的方法
- 江苏省普通高校“专转本”选拔考试专业综合科目考试大纲(试行)
- C语言实现基于华为LiteOS的智慧楼宇消防系统源码+电路图+全部资料
- 基于CMLM的语义一致性数据增强方法python实现源码(提高神经机器翻译的性能、IWSLT14 DE-EN数据集验证).zip
- 静态网站首页制作,纯手工,没有使用框架
- 机器学习大作业-Python实现基于线性回归的PM2.5预测项目源码(高分期末大作业)
- 基于java开发的绿色出行的个人碳排放积分系统+源码(毕业设计&课程设计&项目开发)
- 数据结构--实验报告2.docx
- 基于python的开源文本到语音转换项目+小白使用教程(支持批量英语、中文、多情感语音合成,web界面).zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页