这学期选了一门名叫《web智能与社会计算》的课,老师最后偷懒,最后的课程project作业直接让我们参加百度的一个电影推荐系统算法大赛,然后以在这个比赛中的成绩作为这门课大作业的成绩。不过,最终的结果并不需要百度官方的评估,只需要我们的截图即可(参看百度云平台),例如下面这个:
上面最重要的就是RMSE的数值,数值越小代表偏差越小,百度排行榜就是按值从小到大来排列的,这些人使用的可能是比SVD更好的算法,即使这样达到一定范围后再想进步就很难了,估计不会有人低于0.6这个值。
言归正传,下面来说说针对百度这个比赛如何如何用SVD来实现推荐系统,为了了解基本原理可以看看这篇文章:推荐系统相关算法(1):SVD (后面提到的三篇论文也值得一读)
1、数据预处理
本课程的要求是只完成任务一即可,做任务一的时候只需要用到两个数据集,一个是训练数据training_set,一个是待预测的数据predict,百度的要求如下:
l 任务一
n training_set.txt用户评分数据共三列,从左到右依次为userId、movieId、rating。即用户id、电影id、该用户对该电影的评分。列之间以’\t’分隔,行之间以’\r\n’分隔。
n predict.txt为预测集合,共两列。从左到右依次是userId,movieId。即用户id,电影id.列之间以’\t’分隔,行之间以’\r\n’分隔。参赛者需要预测出第三列,即该用户对该电影的评分,作为第三列,并提交给评测平台。需要注意的是,参赛者最终提的predict.txt是三列,列之间以’\t’分隔,行之间以’\r\n’分隔。行之间的顺序不能乱,行的总数不能少。
下载下来以后发现数据并不是从0开始计数的,training_set格式如下:7245481 962729 4.07245481 356405 4.07245481 836383 4.07245481 284550 4.07245481 723581 4.07245481 827305 4.07245481 572786 4.07245481 473690 4.0...............................................................
predict集数据格式如下:
7245481 7941717245481 3810607245481 7760027245481 9807057245481 3542927245481 7387357245481 6245617245481 9858087245481 3783497245481 7782697245481 242057.........................................................
在使用SVD的时候需要用数组存储每一个用户和每一个电影,这里用户的ID都是7位,电影的都是6位,如果直接开个七八位大数组来存储内存估计不够,而且还浪费空间,为此需要先把用户和电影ID进行映射到从0开始一个较小的范围内。
userMap = {}movieMap = {}with open('training_set.txt') as fp: fp_user = open('usermap.txt', 'w') fp_movis = open('moviemap.txt', 'w') fp_out = open('smallMatrix.txt', 'w') fp_prediction = open('test.txt', 'r') fp_out2 = open('small