协同过滤推荐(Collaborative Filtering Recommendation)主要包括基于用户的协同过滤算法与基于物品的协同过滤算法。

下面,以movielens数据集为例,分别实践这两种算法。

movielens数据集包含四列,【用户ID|电影ID|打分|时间戳】,根据用户的历史评分向用户召回电影候选集。

UserCF

基于用户的协同过滤算法主要包括两个步骤。

(1) 找到和目标用户兴趣相似的用户集合。

(2) 找到这个集合中的用户喜欢的,且目标用户没有听说过的物品推荐给目标用户

步骤(1)的关键就是计算两个用户的兴趣相似度。可以通过Jaccard(杰卡德)公式或者通过余弦相似度计算。代码中主要使用了余弦相似度:

\[W(u,v) = \frac{N(u) \bigcap N(v)} {\sqrt{|N(u)| |N(v)|}}
\]

主函数为recommend(self,userID,K,N,useIIF):

def recommend(self,userID,K,N,useIIF):
W, user_item = self._UserSimilarity(self.X, self.y, useIIF)
rank = {}
interacted_items = user_item[userID]
for v, wuv in sorted(W[userID].items(), reverse=True)[:K]:
for i in user_item[v]:
if i not in interacted_items:
rank.setdefault(i, 0)
rank[i] += wuv
return sorted(rank.items(), key=lambda d: d[1], reverse=True)[:N]

其中,userID是将要为其推荐的用户ID,\(K\)代表要考虑多少个相似用户,\(N\)代表输出多少个推荐item。

函数_UserSimilarity用于计算用户之间的相似度,通过用户物品表与物品用户表计算出两个用户观看的相同的电影数量,当设定useIIF=True时,相同的电影数量变为加\(1 / math.log(1 + len(users))\),原因是惩罚用户\(u\)和用户\(v\)共同兴趣列表中的热门物品。

然后,会挑选出\(K\)名最相似的用户,选出这些用户下的\(N\)部电影作为推荐目标。这里涉及到两个排序,一个是用户的相似度排序,一个是item与用户的权重排序。注意,这里的电影的权重是由用户相似度累加决定的。

全部代码如下所示:

import math
import pandas as pd class UserCF:
def __init__(self,X,y):
self.X,self.y = X,y def recommend(self,userID,K,N,useIIF):
"""
Args:
userID:user id
k: K users closest to the user's interest
N:the number of recommendable item
userIIF:whether or not use userIIF
Returns:
top N recommendation
rank:[(item_id1,interest1),(item_id2,interest2)...]
"""
W, user_item = self._UserSimilarity(self.X, self.y, useIIF)
rank = {}
interacted_items = user_item[userID]
for v, wuv in sorted(W[userID].items(), reverse=True)[:K]:
for i in user_item[v]:
if i not in interacted_items:
rank.setdefault(i, 0)
rank[i] += wuv
return sorted(rank.items(), key=lambda d: d[1], reverse=True)[:N] def _UserSimilarity(self,X,Y,useIIF=False):
"""
Args:
X: user id list
Y: item id list
userIIF: whether or not use userIIF
Returns:
W : user's interest correlation
user_item: a dict:{user_id1:[item1,item2,...],..user_idn:[]}
"""
# 建立倒排表
item_user=dict()
for i in range(X.count()):
user=X.iloc[i]
item=Y.iloc[i]
if item not in item_user:
item_user[item]=set()
item_user[item].add(user) user_item=dict()
for i in range(Y.count()):
user=X.iloc[i]
item=Y.iloc[i]
if user not in user_item:
user_item[user]=set()
user_item[user].add(item) C={}
N={}
# C:输出用户u与v共同的物品数目矩阵
for i,users in item_user.items():
for u in users:
N.setdefault(u,0)
N[u]+=1
C.setdefault(u,{})
for v in users:
if u==v:
continue
C[u].setdefault(v,0)
if not useIIF:
C[u][v]+=1
else:
C[u][v]+=1 / math.log(1 + len(users))# 惩罚用户u和用户v共同兴趣列表中热门物品
W=C.copy()
for u,related_users in C.items():
for v,cuv in related_users.items():
W[u][v]=cuv/math.sqrt(N[u]*N[v])
return W,user_item if __name__ == '__main__':
moviesPath = '../data/ml-1m/movies.dat'
ratingsPath = '../data/ml-1m/ratings.dat'
usersPath = '../data/ml-1m/users.dat' ratingsDF = pd.read_csv(ratingsPath, index_col=None, sep='::', header=None,names=['user_id', 'movie_id', 'rating', 'timestamp'])
X=ratingsDF['user_id'][:100000]
Y=ratingsDF['movie_id'][:100000]
rank = UserCF(X,Y).recommend(1,K=10,N=10,useIIF=True)# 输出对用户1推荐的 top10 item
print('UserCF result',rank)

ItemCF

基于物品的协同过滤(item-based collaborative filtering)算法是目前业界应用最多的算法。基于物品的协同过滤算法主要分为两步。

(1) 计算物品之间的相似度。

(2) 根据物品的相似度和用户的历史行为给用户生成推荐列表

与UserCF类似,下面也使用了余弦相似度作用item相似度的衡量。另外,也对活跃用户做了一种软性的惩罚。

全部代码如下所示:

#-*-coding:utf-8-*-
"""
author:jamest
date:20190306
ItemCF function
"""
import math
import pandas as pd class ItemCF:
def __init__(self,X,y):
self.X,self.y = X,y def recommend(self,userID,K,N,useIUF):
"""
Args:
userID:user id
k: K items closest to the user's items
N:the number of recommendable item
useIUF:whether or not use useIUF
Returns:
top N recommendation
rank:[(item_id1,interest1),(item_id2,interest2)...]
"""
W, user_item = self._ItemSimilarity(self.X, self.y, useIUF)
rank = {}
interacted_items = user_item[userID]
for i in interacted_items:
for j, wij in sorted(W[i].items(), reverse=True)[0:K]:
if j not in interacted_items:
rank.setdefault(j, 0)
rank[j] += wij
return sorted(rank.items(), key=lambda d: d[1], reverse=True)[:N] def _ItemSimilarity(self,X,Y,useIUF=False):
"""
Args:
X: user id list
Y: item id list
useIUF: whether or not use useIUF
Returns:
W : item's correlation
user_item: a dict:{user_id1:[item1,item2,...],..user_idn:[]}
"""
# 建立倒排表
user_item = dict()
for i in range(Y.count()):
user = X.iloc[i]
item = Y.iloc[i]
if user not in user_item:
user_item[user] = set()
user_item[user].add(item) C = {}
N = {}
for u, items in user_item.items():
for i in items:
N.setdefault(i, 0)
N[i] += 1
C.setdefault(i, {})
for j in items:
if i == j:
continue
C[i].setdefault(j, 0)
if not useIUF:
C[i][j] += 1
else:
C[i][j] += 1 / math.log(1 + len(items)) # 对活跃用户做了一种软性的惩罚
W = C.copy()
for i, related_items in C.items():
for j, cij in related_items.items():
W[i][j] = cij / math.sqrt(N[i] * N[j])
return W, user_item if __name__ == '__main__':
moviesPath = '../data/ml-1m/movies.dat'
ratingsPath = '../data/ml-1m/ratings.dat'
usersPath = '../data/ml-1m/users.dat' # usersDF = pd.read_csv(usersPath,index_col=None,sep='::',header=None,names=['user_id', 'gender', 'age', 'occupation', 'zip'])
# moviesDF = pd.read_csv(moviesPath,index_col=None,sep='::',header=None,names=['movie_id', 'title', 'genres'])
ratingsDF = pd.read_csv(ratingsPath, index_col=None, sep='::', header=None,names=['user_id', 'movie_id', 'rating', 'timestamp'])
X=ratingsDF['user_id'][:10000]
Y=ratingsDF['movie_id'][:10000]
rank = ItemCF(X,Y).recommend(1,K=10,N=10,useIUF=True)#输出对用户1推荐的 top10 item
print('ItemCF result',rank)

参考:

推荐系统概述(一)

Github

个性化召回算法实践(一)——CF算法的更多相关文章

  1. 个性化排序算法实践(五)——DCN算法

    wide&deep在个性化排序算法中是影响力比较大的工作了.wide部分是手动特征交叉(负责memorization),deep部分利用mlp来实现高阶特征交叉(负责generalizatio ...

  2. 个性化排序算法实践(三)——deepFM算法

    FM通过对于每一位特征的隐变量内积来提取特征组合,最后的结果也不错,虽然理论上FM可以对高阶特征组合进行建模,但实际上因为计算复杂度原因,一般都只用到了二阶特征组合.对于高阶特征组合来说,我们很自然想 ...

  3. 个性化召回算法实践(三)——PersonalRank算法

    将用户行为表示为二分图模型.假设给用户\(u\)进行个性化推荐,要计算所有节点相对于用户\(u\)的相关度,则PersonalRank从用户\(u\)对应的节点开始游走,每到一个节点都以\(1-d\) ...

  4. 个性化召回算法实践(四)——ContentBased算法

    ContentBased算法的思想非常简单:根据用户过去喜欢的物品(本文统称为 item),为用户推荐和他过去喜欢的物品相似的物品.而关键就在于这里的物品相似性的度量,这才是算法运用过程中的核心. C ...

  5. 个性化召回算法实践(二)——LFM算法

    LFM算法核心思想是通过隐含特征(latent factor)联系用户兴趣和物品,找出潜在的主题和分类.LFM(latent factor model)通过如下公式计算用户u对物品i的兴趣: \[ P ...

  6. 个性化排序算法实践(一)——FM算法

    因子分解机(Factorization Machine,简称FM)算法用于解决大规模稀疏数据下的特征组合问题.FM可以看做带特征交叉的LR. 理论部分可参考FM系列,通过将FM的二次项化简,其复杂度可 ...

  7. 个性化排序算法实践(二)——FFM算法

    场感知分解机(Field-aware Factorization Machine ,简称FFM)在FM的基础上进一步改进,在模型中引入类别的概念,即field.将同一个field的特征单独进行one- ...

  8. 算法实践--最小生成树(Kruskal算法)

    什么是最小生成树(Minimum Spanning Tree) 每两个端点之间的边都有一个权重值,最小生成树是这些边的一个子集.这些边可以将所有端点连到一起,且总的权重最小 下图所示的例子,最小生成树 ...

  9. [迷宫中的算法实践]迷宫生成算法——递归分割算法

    Recursive division method        Mazes can be created with recursive division, an algorithm which wo ...

随机推荐

  1. 【Tools】PDF编辑软件-pdfelement 6.8 官网文件中文+破解版本

    试用了下,感觉还不错分享给大家. 有币的求赏,小弟下载缺币.没币的从附件下载. 赏币地址:https://download.csdn.net/download/qq_18187161/10744059 ...

  2. Debian10.1用wine打开Windows工具乱码总结

    由于之前的deepin15.11莫名其妙挂了(就是使用一般没做啥特殊操作就挂了,不过有可能是我的移动固态硬盘也有锅),所以这次决定装Debian10.1版本, 由于安装时选择语言环境是中文的话创建的一 ...

  3. oracle 常用sql 经典sql函数使用 sql语法

    各种树操作, 用来查询表中带有子父节点的信息 Oracle 树操作(select-start with-connect by-prior) select m.org_id from sm_organ ...

  4. Mybatis笔记4

    mybatis中多对多的步骤 示例:用户和角色,一个用户可以有多个角色,一个角色可以赋予多个用户 步骤: 建立两张表:用户表,角色表,让用户表和角色表具有多对多的关系,需要使用中间表,中间表中包含两张 ...

  5. python 的django项目复制方法

    python 的django项目复制方法 django_pyecharts_1修改为django_pyecharts_1_cs1.拷贝项目(确保原有项目是关闭状态下)2.粘贴项目并删除idea文件夹和 ...

  6. C#中使用XML存储数据

    创建XML文档 首先引用System.Xml命名空间 1.初始化一个实例 XmlDocument xd = new XmlDocument(); 2.创建XML头文件声明 XmlDeclaration ...

  7. 【dfs】Sequence Decoding

    Sequence Decoding 题目描述 The amino acids in proteins are classified into two types of elements, hydrop ...

  8. 2019杭电多校三 C. Yukikaze and Demons (点分治)

    大意: 给定树, 每个点有一个十进制数位, 求有多少条路径组成的十进制数被$k$整除. 点分治, 可以参考CF715C, 转化为求$10^a x+b\equiv 0(mod\space k)$的$x$ ...

  9. DG环境恢复同步遇到报错ORA-00353ORA-00334以及ORA-00600[2619], [47745]

    问题说明 客户环境主库4节点RAC11.2.0.4,单实例DG环境,DG由于空间不足,导致同步中断,由于DG备库未应用的归档主库都再,本次恢复的方式,是开启dg mrp进程,自动同步追上主库. 以下遇 ...

  10. java 读取文件流

    搬运自速学堂:https://www.sxt.cn/Java_jQuery_in_action/ten-iqtechnology.html JAVA中IO流体系: 四大IO抽象类 ·InputStre ...