协同过滤推荐(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. 【GStreamer开发】GStreamer基础教程09——收集媒体信息

    目标 有时你需要快速的了解一个文件(或URI)包含的媒体格式或者看看是否支持这种格式.当然你可以创建一个pipeline,设置运行,观察总线上的消息,但GStreamer提供了一个工具可以帮你做这些. ...

  2. 反馈神经网络Hopfield网络

    一.前言 经过一段时间的积累,对于神经网络,已经基本掌握了感知器.BP算法及其改进.AdaLine等最为简单和基础的前馈型神经网络知识,下面开启的是基于反馈型的神经网络Hopfiled神经网络.前馈型 ...

  3. 第1章:LeetCode--基础部分

    LeetCode刷题指导(不能只实现功能就行需要尽量写最优解): 不可能刷遍所有题,只能通过刷题来恢复写代码的功力,熟悉常用算法(暴力算法.冒泡排序/快速排序.strStr KMP算法.二叉树遍历DF ...

  4. conda命令入坑记

    conda命令入坑记 本人使用的软件版本: TypeError: LoadLibrary() argument 1 must be str, not None 网上太多的资料,大多都是在讲path的设 ...

  5. 微软商店一直安装不上Intel Media SDK DFP

    具体表现为一直安装失败,但是下载进度条一直在,无法去除. 此方法来自 https://answers.microsoft.com/en-us/windows/forum/all/error-code- ...

  6. vs2017环境下python包的安装

    1)---vs已经下载了的才适用 1,鼠标放在右侧窗口python环境那里(如没有窗口,可点击最上方的“窗口”-“重置窗口”) 2,右键然后点击“查看所有python环境”,会弹出当前默认的环境(高亮 ...

  7. Quartz入门以及相关表达式使用

    目的: 1.Quartz简介及应用场景 2.Quartz简单触发器 SimpleTrigger介绍 3.Quartz表达式触发器CronTirgger介绍 4.Quartz中参数传递 5.Spring ...

  8. linux学习之路(二)--centos7安装Redis(单点)

    一.安装redis 1.进入/usr/local/,新建services目录,进入该目录,下载redis wget http://download.redis.io/releases/redis-4. ...

  9. openfeign与gateway中的httpClient类声明冲突

    启动spring cloud中的网关,报错: ***************************APPLICATION FAILED TO START*********************** ...

  10. VS.NET(C#)--2.9_HTML服务器控件案例

    HTML服务区控件案例 UI设计视图 UI源码视图 <>