基于用户的最近邻算法(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. Apache Spark 2.2.0 中文文档 - Spark SQL, DataFrames and Datasets

    Spark SQL, DataFrames and Datasets Guide Overview SQL Datasets and DataFrames 开始入门 起始点: SparkSession ...

  2. markdown 表情包大法

    前段时间偶然发现了markdown竟然可以插入表情,而且竟然如此的简单 表情包网站 (有可能是官网):点击跳转 这些东西真的是有点意思啊,容我举个栗子

  3. redis随记

    CONFIG REWRITE  将config文件  将服务器当前所使用的配置记录到 redis.conf 文件中.

  4. The linux command 之权限

    一.修改权限 只有文件主或者超级用户才可以修改文件或者目录的权限. 符号表示法分为三种: Who the change will affect Which operation will be perf ...

  5. Odoo Javascript 参考

    本文介绍了odoo javascript框架.从代码行的角度来看,这个框架不是一个大的应用程序,但它是非常通用的,因为它基本上是一个将声明性接口描述转换为活动应用程序的机器,能够与数据库中的每个模型和 ...

  6. (转)自定义ClassLoader ----可以加载第三方jar包

    package com.classloader.util; import java.io.IOException; import java.net.MalformedURLException; imp ...

  7. C#实现程序开机启动

    如何用c#实现开机启动?其实用c#实现程序的开机启动大致有两种方法,就是写入注册表或者采用服务程序,最近一直研究着用C#来操作注册表,下面介绍的方法便是用注册表来实现程序随开机启动(高手就不用看了,嘿 ...

  8. 搭建CA颁发证书做https加密网站

    92.168.10.187 CA服务器 192.168.10.190 web服务器 (1)搭建CA cd /etc/pki/CA 在这个目录下创建serial和index.txt两个文件 echo 0 ...

  9. TStringList常用操作

    TStringList常用操作 //TStringList 常用方法与属性: var List: TStringList; i: Integer; begin List := TStringList. ...

  10. div中包着文字,div出现隐藏的时候,文字总是在div外面。

    背景: 给博客加一个侧边栏,点击出现隐藏,每次点击出现或者隐藏,文字总是很突兀的就出来了. 解决: overflow:hidden