《推荐系统实践》算法纯享(附代码链接)(四)—— UGC推荐篇

在上一篇博客里面分享的是《推荐系统实践》中冷启动相关的处理算法,对此还不熟悉的读者可以戳这里

关于这个系列会分为如下几个部分:

《推荐系统实践》算法纯享(附代码链接)(一)—— 评价指标篇
《推荐系统实践》算法纯享(附代码链接)(二)—— 协同过滤篇
《推荐系统实践》算法纯享(附代码链接)(三)—— 冷启动篇
《推荐系统实践》算法纯享(附代码链接)(四)—— UGC推荐篇
《推荐系统实践》算法纯享(附代码链接)(五)—— 借助上下文信息推荐篇
《推荐系统实践》算法纯享(附代码链接)(六)—— 借助社交网络推荐篇
《推荐系统实践》算法纯享(附代码链接)(七)—— 评分预测篇

完整代码链接:https://github.com/Magic-Bubble/RecommendSystemPractice

下面将开始本系列的第四部分——UGC推荐篇

4 UGC推荐

用户的标签行为数据集一般由(u, i, b)三元组组成,表示用户u给物品i打上了标签b的行为。

4.1 基于用户UGC标签进行推荐

代码链接:https://github.com/Magic-Bubble/RecommendSystemPractice/blob/master/Chapter4/基于用户标签的推荐系统.ipynb

4.1.1 最简单的算法(SimpleTagBased)

在拿到用户标签行为数据之后,一个最容易想到的方法就是:

  1. 统计每个用户最常用的标签
  2. 对于每个标签,统计被打过这个标签次数最多的物品
  3. 对于每个用户,首先找到他常用的标签,然后找到具有这些标签的最热门物品进行推荐

用公式表示用户u对物品i的兴趣为,其中, n u , b n_{u,b} nu,b是用户u打过标签b的次数, n b , i n_{b,i} nb,i是物品i被打过标签b的次数。

p ( u , i ) = ∑ b n u , b n b , i p(u, i) = \sum_b n_{u,b}n_{b,i} p(u,i)=bnu,bnb,i

4.1.2 利用TF-IDF进行改进(TagBasedTFIDF和TagBasedTFIDF++)

上面的公式倾向于给热门标签对应的热门物品很大的权重,从而不能反映用户个性化的兴趣,因此可以借鉴TF-IDF思想,对上述公式进行改进(TagBasedTFIDF):

p ( u , i ) = ∑ b n u , b l o g ( 1 + n b ( u ) ) n b , i p(u,i)=\sum_b \frac{n_{u,b}}{log(1+n_b^{(u)})} n_{b,i} p(u,i)=blog(1+nb(u))nu,bnb,i

其中 n b ( u ) n_b^{(u)} nb(u)记录了标签b被多少个不同的用户使用过。

可见这个公式是对热门标签进行惩罚,当然对于热门物品也可以进行同样的惩罚(TagBasedTFIDF++):

p ( u , i ) = ∑ b n u , b l o g ( 1 + n b ( u ) ) n b , i l o g ( 1 + n i ( u ) ) p(u,i)=\sum_b \frac{n_{u,b}}{log(1+n_b^{(u)})} \frac{n_{b,i}}{log(1+n_i^{(u)})} p(u,i)=blog(1+nb(u))nu,blog(1+ni(u))nb,i

其中 n i ( u ) n_i^{(u)} ni(u)记录了物品i被多少个不同的用户打过标签

4.1.3 标签扩充改进

前面的算法中,用户兴趣和物品的联系是通过 B ( u ) ⋂ B ( i ) B(u) \bigcap B(i) B(u)B(i)中的标签建立的。但对于新用户或新物品,这个集合中的标签数量会很少,因此可以考虑对标签集合进行扩展。

一种简单的扩充方法是基于邻域的做法,即通过计算标签之间的相似度进行扩充。对于标签的相似度计算可以从数据中统计,当两个标签同时出现在很多物品的标签集合中时,就可以认为它们具有较大的相似度。

对于标签b,令 N ( b ) N(b) N(b)为有标签b的物品的集合, n b , i n_{b,i} nb,i为给物品i打上标签b的用户数,可以用如下的余弦相似度计算标签b和标签b’的相似度:

s i m ( b , b ′ ) = ∑ i ∈ N ( b ) ⋂ N ( b ′ ) n b , i n b ′ , i ∑ i ∈ N ( b ) n b , i 2 ∑ i ∈ N ( b ′ ) n b ′ , i 2 sim(b, b')=\frac{\sum_{i\in {N(b) \bigcap N(b')}}n_{b,i}n_{b',i}}{\sqrt{\sum_{i \in N(b)} n_{b,i}^2 \sum_{i \in N(b')} n_{b', i}^2}} sim(b,b)=iN(b)nb,i2iN(b)nb,i2 iN(b)N(b)nb,inb,i

后续就可以根据这种标签的相似度进行聚合排序,而后作为用户新的标签集合。

4.1.4 基于图的推荐

相比较于协同过滤算法中提到的(User, Item)二元组,这里的数据是(User, Item, Tag)三元组,因此也可以构建成如下的图:

其中ABC表示用户,abc表示物品,123表示标签。在建立了这种图之后,就可以用协同过滤部分提到的PersonalRank算法进行随机游走计算了。

而对于前面的简单算法来说,用户对物品的兴趣公式为:

P ( i ∣ u ) = ∑ b P ( i ∣ b ) P ( b ∣ u ) P(i|u)=\sum_b P(i|b)P(b|u) P(iu)=bP(ib)P(bu)

其实这个可以用简化的图模型来建模,即SimpleTagGraph,如下图所示,它将前面的三条边(User,Item),(Item, Tag),(User, Tag)改成了两条边,去掉了(User, Item)边,并且改为了有向图。

这时用PersonalRank算法, 设 K = 1 K=1 K=1,就等价于前面提到的简单推荐算法SimpleTagBased。

4.2 给用户推荐标签

代码链接:https://github.com/Magic-Bubble/RecommendSystemPractice/blob/master/Chapter4/给用户推荐标签.ipynb

给用户推荐标签的好处在于:1)方便用户输入;2)提升标签质量

4.2.1 基于统计的方法

当用户u给物品i打标签时,有如下4种方法给用户推荐和物品i相关的标签:

  1. PopularTags:给用户u推荐整个系统里面最热门的标签
  2. ItemPopularTags:给用户u推荐物品i上面被打的最热门标签
  3. UserPopularTags:给用户u推荐他自己经常打的标签
  4. HybridPopularTags:线性加权融合方式2、3,对两个列表进行线性相加之前,需要对其按照各自的最大值进行归一化

4.2.2 基于图的标签推荐

在根据用户打标签的行为生成图之后(4.1.4),同样可以利用PersonalRank方法进行排名。这次的问题是,当用户u遇到物品i时,会给物品i打什么样的标签。因此,需要重新定义顶点的启动概率:

P R ( v ) = r v ( k ) = { α v ( k ) = = v ( u ) 1 − α v ( k ) = = v ( i ) 0 o t h e r PR(v)=r_{v(k)} = \left\{ \begin{array}{lr} \alpha & v(k)==v(u) \\ 1- \alpha & v(k)==v(i)\\ 0 & other \end{array} \right. PR(v)=rv(k)=α1α0v(k)==v(u)v(k)==v(i)other

也就是说,只有用户u和物品i对应的顶点有非0的启动概率,而其他顶点的启动概率都为0。在上面的定义中, v ( u ) v(u) v(u) v ( i ) v(i) v(i)的启动概率并不相同, v ( u ) v(u) v(u)的启动概率是 α \alpha α,而 v ( i ) v(i) v(i)的启动概率是 1 − α 1-\alpha 1α。参数 α \alpha α可以通过离线实验选择。

对于UGC推荐部分的介绍就到这里,下面将继续分享第五部分——借助上下文信息推荐篇

  • 4
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
# -*- coding: utf-8 -*- import pandas as pd import numpy as np from math import sqrt critics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5, 'The Night Listener': 3.0}, 'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0, 'You, Me and Dupree': 3.5}, 'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0, 'Superman Returns': 3.5, 'The Night Listener': 4.0}, 'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'The Night Listener': 4.5, 'Superman Returns': 4.0, 'You, Me and Dupree': 2.5}, 'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0, 'You, Me and Dupree': 2.0}, 'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5}, 'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0}} df_critics=pd.DataFrame(critics) ##欧氏距离 def sim_distance(prefs,person1,person2): si={} for item in prefs[person1]: if item in prefs[person2]: si[item]=1 if len(si)==0: return 0 sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2) for item in prefs[person1] if item in prefs[person2]]) return 1/(1+sqrt(sum_of_squares)) ##numpy pandas 方法 def sim_distance2(prefs,person1,person2): return 1/(1+np.linalg.norm(prefs[person1]-prefs[person2])) ##皮尔逊相关系数 def sim_pearson(prefs,p1,p2): si={} for item in prefs[p1]: if item in prefs[p2]: si[item]=1 n=len(si) if n==0: return 1 ##对所有偏好求和 sum1=sum([prefs[p1][it] for it in si]) sum2=sum([prefs[p2][it] for it in si]) ##求平方和 sum1Sq=sum([pow(prefs[p1][it]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值