基于用户的最近邻算法(User-Based Neighbor Algorithms),是一种非概率性的协同过滤算法,也是推荐系统中最最古老,最著名的算法。

我们称那些兴趣相似的用户为邻居,如果用户n相似于用户u,我们就说n是u的一个邻居。起初算法,对于未知目标的预测是根据该用户的相似用户的评分作出预测的。

本文中运用的是MovieLens数据集,关于这个数据集的介绍可以参看http://www.grouplens.org/node/73

算法主要包括两个步骤:

(1). 找到与用户兴趣相似的用户(邻居)集合。

(2). 根据这个邻居集合,计算出该用户对未曾评分的物品的预测评分。并列出获得最高的预测评分N项物品,推荐给该用户。

本文,用皮尔逊相关系数(pearon correlation coefficient)计算用户之间的相似性。如formula1

计算用户u对物品i的预测值,使用的formula2

formula1:

formula-2:

具体实现代码如下:

'''''
Created on Nov 17, 2012 @Author: Dennis Wu
@E-mail: hansel.zh@gmail.com
@Homepage: http://blog.csdn.net/wuzh670 Data set download from : http://www.grouplens.org/system/files/ml-100k.zip MovieLens data sets were collected by the GroupLens Research Project
at the University of Minnesota.The data was collected through the MovieLens web site
(movielens.umn.edu) during the seven-month period from September 19th,
1997 through April 22nd, 1998. This data set consists of:
* 100,000 ratings (1-5) from 943 users on 1682 movies.
* Each user has rated at least 20 movies.
* Simple demographic info for the users u.data -- The full u data set, 100000 ratings by 943 users on 1682 items.
Each user has rated at least 20 movies. Users and items are
numbered consecutively from 1. The data is randomly
ordered. This is a tab separated list of
user id | item id | rating | timestamp.
The time stamps are unix seconds since 1/1/1970 UTC
u.item -- Information about the items (movies); this is a tab separated
list of
movie id | movie title | release date | video release date |
IMDb URL | unknown | Action | Adventure | Animation |
Children's | Comedy | Crime | Documentary | Drama | Fantasy |
Film-Noir | Horror | Musical | Mystery | Romance | Sci-Fi |
Thriller | War | Western |
The last 19 fields are the genres, a 1 indicates the movie
is of that genre, a 0 indicates it is not; movies can be in
several genres at once.
The movie ids are the ones used in the u.data data set.
''' from operator import itemgetter, attrgetter
from math import sqrt def load_data(): filename_user_movie = 'data/u.data'
filename_movieInfo = 'data/u.item' user_movie = {}
for line in open(filename_user_movie):
(userId, itemId, rating, timestamp) = line.strip().split('\t')
user_movie.setdefault(userId,{})
user_movie[userId][itemId] = float(rating) movies = {}
for line in open(filename_movieInfo):
(movieId, movieTitle) = line.split('|')[0:2]
movies[movieId] = movieTitle return user_movie, movies def average_rating(user):
average = 0
for u in user_movie[user].keys():
average += user_movie[user][u]
average = average * 1.0 / len(user_movie[user].keys())
return average def calUserSim(user_movie): # build inverse table for movie_user
movie_user = {}
for ukey in user_movie.keys():
for mkey in user_movie[ukey].keys():
if mkey not in movie_user:
movie_user[mkey] = []
movie_user[mkey].append(ukey) # calculated co-rated movies between users
C = {}
for movie, users in movie_user.items():
for u in users:
C.setdefault(u,{})
for n in users:
if u == n:
continue
C[u].setdefault(n,[])
C[u][n].append(movie) # calculate user similarity (perason correlation)
userSim = {}
for u in C.keys(): for n in C[u].keys(): userSim.setdefault(u,{})
userSim[u].setdefault(n,0) average_u_rate = average_rating(u)
average_n_rate = average_rating(n) part1 = 0
part2 = 0
part3 = 0
for m in C[u][n]: part1 += (user_movie[u][m]-average_u_rate)*(user_movie[n][m]-average_n_rate)*1.0
part2 += pow(user_movie[u][m]-average_u_rate, 2)*1.0
part3 += pow(user_movie[n][m]-average_n_rate, 2)*1.0 part2 = sqrt(part2)
part3 = sqrt(part3)
if part2 == 0:
part2 = 0.001
if part3 == 0:
part3 = 0.001
userSim[u][n] = part1 / (part2 * part3)
return userSim def getRecommendations(user, user_movie, movies, userSim, N):
pred = {}
interacted_items = user_movie[user].keys()
average_u_rate = average_rating(user)
sumUserSim = 0
for n, nuw in sorted(userSim[user].items(),key=itemgetter(1),reverse=True)[0:N]:
average_n_rate = average_rating(n)
for i, nrating in user_movie[n].items():
# filter movies user interacted before
if i in interacted_items:
continue
pred.setdefault(i,0)
pred[i] += nuw * (nrating - average_n_rate)
sumUserSim += nuw for i, rating in pred.items():
pred[i] = average_u_rate + (pred[i]*1.0) / sumUserSim # top-10 pred
pred = sorted(pred.items(), key=itemgetter(1), reverse=True)[0:10]
return pred if __name__ == "__main__": # load data
user_movie, movies = load_data() # Calculate user similarity
userSim = calUserSim(user_movie) # Recommend
pred = getRecommendations('', user_movie, movies, userSim, 20) # display recommend result (top-10 results)
for i, rating in pred:
print 'film: %s, rating: %s' % (movies[i], rating)

References

1. J.Ben Schafer, Dan Frankowski, Jon Herlocker, and Shilad Sen : Collaborative Filtering Recommender System

2. 项亮: 推荐系统实践 2012

基于用户的最近邻协同过滤算法(MovieLens数据集)的更多相关文章

  1. SVD++:推荐系统的基于矩阵分解的协同过滤算法的提高

    1.背景知识 在讲SVD++之前,我还是想先回到基于物品相似的协同过滤算法.这个算法基本思想是找出一个用户有过正反馈的物品的相似的物品来给其作为推荐.其公式为:

  2. 基于用户相似性的协同过滤——Python实现

    代码基本来自项亮的<推荐系统实践>,把书上的伪代码具体实现,还参考了https://www.douban.com/note/336280497/ 还可以加入对用户相似性的归一化操作,效果会 ...

  3. 【机器学习笔记一】协同过滤算法 - ALS

    参考资料 [1]<Spark MLlib 机器学习实践> [2]http://blog.csdn.net/u011239443/article/details/51752904 [3]线性 ...

  4. Slope one—个性化推荐中最简洁的协同过滤算法

    Slope One 是一系列应用于 协同过滤的算法的统称.由 Daniel Lemire和Anna Maclachlan于2005年发表的论文中提出. [1]有争议的是,该算法堪称基于项目评价的non ...

  5. Mahout实现基于用户的协同过滤算法

    Mahout中对协同过滤算法进行了封装,看一个简单的基于用户的协同过滤算法. 基于用户:通过用户对物品的偏好程度来计算出用户的在喜好上的近邻,从而根据近邻的喜好推测出用户的喜好并推荐. 图片来源 程序 ...

  6. 基于Python协同过滤算法的认识

    Contents    1. 协同过滤的简介    2. 协同过滤的核心    3. 协同过滤的实现    4. 协同过滤的应用 1. 协同过滤的简介 关于协同过滤的一个最经典的例子就是看电影,有时候 ...

  7. Spark 基于物品的协同过滤算法实现

    J由于 Spark MLlib 中协同过滤算法只提供了基于模型的协同过滤算法,在网上也没有找到有很好的实现,所以尝试自己实现基于物品的协同过滤算法(使用余弦相似度距离) 算法介绍 基于物品的协同过滤算 ...

  8. 基于物品的协同过滤算法(ItemCF)

    最近在学习使用阿里云的推荐引擎时,在使用的过程中用到很多推荐算法,所以就研究了一下,这里主要介绍一种推荐算法—基于物品的协同过滤算法.ItemCF算法不是根据物品内容的属性计算物品之间的相似度,而是通 ...

  9. 使用Python3.7配合协同过滤算法(base on user,基于人)构建一套简单的精准推荐系统(个性化推荐)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_136 时至2020年,个性化推荐可谓风生水起,Youtube,Netflix,甚至于Pornhub,这些在互联网上叱咤风云的流媒体 ...

随机推荐

  1. nginx 知识

    nginx如何实现高并发? 启动nginx服务器后,输入 ps -ef |grep nginx,会发现nginx有一个master进程 和若干个worker进程, 这些worker进程是平等的,都是被 ...

  2. javaScript 习题总结(持续更新)

    判定偶数 function collect_all_even(collection) { return collection.filter(item => item%2 == 0); } 两个集 ...

  3. 数据库实例性能调优利器:Performance Insights

    Performance Insights是什么 阿里云RDS Performance Insights是RDS CloudDBA产品一项专注于用户数据库实例性能调优.负载监控和关联分析的利器,以简单直 ...

  4. 专访阿里云MVP王俊杰:开发者的超能力是用技术让世界更美好

    [王俊杰:阿里云MVP,陕西创博网络科技有限公司总经理.大数据与物联网的爱好者与实践者. 8年以上互联网从业经验,曾从事军工相关仿真分析软件研发与集成.4年以上大数据系统开发经验.目前正与天水市秦州区 ...

  5. 括号匹配——cf1095E

    正解应该是求后缀和前缀 但是多情况讨论好像也能过.. 大概分为: 首先排除不能改的情况 1.改左括号 2.改右括号 /* 将一个位置的括号反过来,使原序列变成合法序列 */ #include<b ...

  6. java基本类型映射表

  7. (转)小白科普, netty 有啥用?

      随着移动互联网的爆发性增长,小明公司的电子商务系统访问量越来越大,由于现有系统是个单体的巨型应用,已经无法满足海量的并发请求,拆分势在必行. 在微服务的大潮之中, 架构师小明把系统拆分成了多个服务 ...

  8. MySQL 调优/优化的 101 个建议!

    原文:http://www.monitis.com/blog/101-tips-to-mysql-tuning-and-optimization/ MySQL是一个强大的开源数据库.随着MySQL上的 ...

  9. Python中好用的模块们

    目录 Python中好用的模块们 datetime模块 subprocess模块 matplotlib折线图 importlib模块 Python中好用的模块们 datetime模块 ​ 相信我们都使 ...

  10. Carthage使用

    # carthage 包管理 ## 安装过程 1) 安装homebrew ``` ruby$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githu ...