推荐系统(八)协同过滤之ItemCF

上一篇推荐系统(七)协同过滤之UserCF中UserCF的原理以及实验步骤,本篇着重讲述与之类似的ItemCF。

基本原理

  • 核心思想

    找到和用户A看过物品相似的物品,向A推荐这些物品。

  • 物品相似度
    w i , j = ∣ N ( i ) ⋂ N ( j ) ∣ ∣ N ( i ) ∣ ∣ N ( j ) ∣ w_{i,j} = \frac{|N(i)\bigcap N(j)|}{\sqrt{|N(i)||N(j)|}} wi,j=N(i)N(j) N(i)N(j)

    计算物品相似度,就需要构建每个用户的对称物品矩阵,之后将这些对称物品矩阵都叠加在一起,就可以得到物品的喜欢记录,之后就能求出物品的相似度了,过程如下图所示。

    由于有的用户同时喜欢很多个物品,因而这种用户可能会影响物品相似度的计算,屏蔽掉对物品感兴趣用户的多样性,因而相似度改写为如下公式:
    w i , j = ∑ u ∈ N ( i ) ⋂ N ( j ) 1 l o g ( 1 + L i k e ( u ) ) ∣ N ( i ) ∣ ∣ N ( j ) ∣ w_{i,j}=\frac{\sum_{u \in N(i)\bigcap N(j)} \frac{1}{log(1+Like(u))}}{\sqrt{|N(i)||N(j)|}} wi,j=N(i)N(j) uN(i)N(j)log(1+Like(u))1

    其中Like(u)代表的是用户u的喜欢物品的个数。

具体实现

  1. 计算物品相似度

    1. 计算每个item的热度,存放在movie_popular中
    2. 计算item的相似度矩阵,存放在movie_sim_matrix中
    3. 对相似度矩阵进行归一化
    def calc_movie_sim(self):
    	# 计算每个item的热度
    	for user, items in self.train_set.items():
    	    for item in items:
    	        if item not in self.movie_popular:
    	            self.movie_popular[item] = 0
    	        self.movie_popular[item] += 1
    	self.movie_count = len(self.movie_popular)
    	# 计算item-item pair 在user的点击中出现了多少次,存放在self.movie_sim_matrix中
    	for user, items in self.train_set.items():
    	    for item1 in items:
    	        for item2 in items:
    	            if item1 == item2:
    	                continue
    	            self.movie_sim_matrix.setdefault(item1, {})
    	            self.movie_sim_matrix[item1].setdefault(item2, 0)
    	            self.movie_sim_matrix[item1][item2] += 1
    	# 计算归一化item-item pair的相似度,分子为item-item pair共现次数
    	# 分母为sqrt(item1的热度 * item2的热度)
    	for item1, related_items in self.movie_sim_matrix.items():
    	    for item2, count in related_items.items():
    	        if self.movie_popular[item1] == 0 or self.movie_popular[item2] == 0:
    	            self.movie_sim_matrix[item1][item2] = 0
    	            continue
    	        self.movie_sim_matrix[item1][item2] = \
    	                count / math.sqrt(self.movie_popular[item1] * self.movie_popular[item2])
    	print("calc_movie_sim done")
    
  2. 针对某一输入用户,推荐资源
    选择该用户看过的物品列表,对于物品列表的每个物品,都找到K个与之最相似的物品,将这些相似物品放在一起,取前N个物品进行最终的推荐。

    def recommend(self, user):
    	K = self.n_sim_movie
    	N = self.n_rec_movie
    	rank = {}
    	if user not in self.train_set:
    	    return []
    	watched_movie = self.train_set[user]
    	for movie, rating in watched_movie.items():
    	    if movie not in self.movie_sim_matrix:
    	        continue
    	    related_movie_info = sorted(self.movie_sim_matrix[movie].items(), key=itemgetter(1), reverse=True)[:K]
    	    for related_movie, w in related_movie_info:
    	        if related_movie in watched_movie:
    	            continue
    	        rank.setdefault(related_movie, 0.0)
    	        rank[related_movie] += w * float(rating)
    	return sorted(rank.items(), key=itemgetter(1), reverse=True)[:N]
    
  3. 构建评价函数
    可以参见推荐系统(七)协同过滤之UserCF

优缺点

优点

  1. 个性化推荐效果好,因为其原理是针对用户自身的行为进行推荐
  2. 新用户快热:对于新用户的冷启动效果好,因为只要新用户有行为,一定会推送类似的物品
  3. 可解释性较强:直接推送播放历史的相似物品,因而令人信服

缺点

  1. 如果物品很多,则计算量很大

ItemCF VS UserCF

原理层面

一图抵千言
UserCF:

ItemCF:

实践层面

  1. 点击率
    ItemCF召回资源的点击率要比UserCF的点击率要高,因为ItemCF的实时性要比UserCF的实时性要强,而且个性化推荐的效果要比UserCF要好。UserCF相当于把用户的行为给平滑掉了,不注重个性化因素,因为其原理是给输入用户推荐其邻居喜欢的物品,但邻居想看的物品并不一定是输入用户喜欢的。
  2. 操控性
    ItemCF的操控性较强,因为其可解释,因而大多数推荐系统都会优先保证ItemCF的召回要稳定。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值