推荐系统8——利用社交网络数据推荐

在之前我也看了很多人写的推荐系统的博客,理论的、算法的都有,多是个人的理解和感悟,虽然很深刻,但是对于自己而言还是不成系统,于是我参考大牛项亮编著的《推荐系统实践》将该领域知识系统整理一遍,与大家一起学习。
本系列对应的代码请查看https://github.com/wangyuyunmu/Recommended-system-practice
前面总结了:
1)基于用户行为数据的推荐方法——协同过滤、隐语义、图模型;
2)冷启动——基于物品内容、用户注册信息等;
3)基于标签的推荐方法;
4)利用上下文信息推荐方法;
本篇总结利用社交网络数据进行推荐


1,社交网络数据简介

一般来说,有3种不同的社交网络数据。
1)双向确认的社交网络数据
用户A和B之间形成好友关系需要通过双方的确认。
2)单向关注的社交网络数据
用户A可以关注用户B而不需要得到用户B的允许
3)基于社区的社交网络数据
用户之间并没有明确的关系,但是这种数据包含了用户属于不同社区的数据

2,基于社交网络的推荐

优点:
1)好友推荐可以增加推荐的信任度。
2)社交网络可以解决冷启动问题。
缺点:
很多时候并不一定能提高推荐算法的离线精度(准确率和召回率),因为用户的好友关系并不是通过共同兴趣产生的,比如子女与父母。

2.1 基于邻域的社会化推荐算法

其中社交网络定义了用户之间的好友关系,而用户行为数据集定义了不同用户的历史行为和兴趣数据。

那么我们想到的最简单算法是给用户推荐好友喜欢的物品集合。
p u i = ∑ v ∈ o u t ( u ) r v i p_{ui}=\sum_{v\in out(u)}r_{vi} pui=vout(u)rvi用户u对物品i的兴趣 = 用户u的出度用户v对物品i的兴趣之和。考虑到不同好友的权重不一样: p u i = ∑ v ∈ o u t ( u ) w u v r v i p_{ui}=\sum_{v\in out(u)}w_{uv}r_{vi} pui=vout(u)wuvrviw 由两部分相似度构成,一部分是用户u和用户v的熟悉程度,另一部分是用户u和用户v的兴趣相似度。
熟悉度可以用用户之间的共同好友比例来度量。也就是说如果用户u和用户v很熟悉,那么一般来说他们应该有很多共同的好友。
f a m i l i a r i t y = ∣ o u t ( u ) ∩ o u t ( v ) ∣ ∣ o u t ( u ) ∪ o u t ( v ) ∣ familiarity=\frac{|out(u) \cap out(v)|}{|out(u) \cup out(v)|} familiarity=out(u)out(v)out(u)out(v)兴趣相似度可以通过userCF类似的计算方法度量。
s i m i l i a r i t y = ∣ N ( u ) ∩ N ( v ) ∣ ∣ N ( u ) ∪ N ( v ) ∣ similiarity=\frac{|N(u)\cap N(v)|}{|N(u)\cup N(v)|} similiarity=N(u)N(v)N(u)N(v)

2.2 基于图的社会化推荐算法

前几章都提到了如何在推荐系统中使用图模型,比如用户物品二分图、用户-物品-标签图模型等。从前面几章的介绍可以看到,图模型的优点是可以将各种数据和关系都表示到图上去。在社交网站中存在两种关系,一种是用户对物品的兴趣关系,一种是用户之间的社交网络关系。本节主要讨论如何将这两种关系建立到图模型中,从而实现对用户的个性化推荐。

用户的社交网络可以表示为社交网络图,用户对物品的行为可以表示为用户物品二分图,而这两种图可以结合成一个图。
在这里插入图片描述
在定义完图中的顶点和边后,需要定义边的权重。其中用户和用户之间边的权重可以定义为用户之间相似度的α 倍(包括熟悉程度和兴趣相似度),而用户和物品之间的权重可以定义为用户对物品喜欢程度的β 倍。α 和β 需要根据应用的需求确定。如果我们希望用户好友的行为对推荐结果产生比较大的影响,那么就可以选择比较大的α 。相反,如果我们希望用户的历史行为对推荐结果产生比较大的影响,就可以选择比较大的β 。

在定义完图中的顶点、边和边的权重后,我们就可以利用前面几章提到的PersonalRank图排序算法给每个用户生成推荐结果。

在社交网络中,除了常见的、用户和用户之间直接的社交网络关系,还有一种关系,即两个用户属于同一个社群。Quan Yuan等详细研究了这两种社交网络关系,他们将第一种社交网络关系称为friendship,而将第二种社交网络关系称为membership。
在这里插入图片描述

2.3 实际系统中的社会化推荐算法

大型网站中用户数目非常庞大,用户的历史行为记录也非常庞大,如果一个算法再给一个用户做推荐时,需要他所有好友的历史行为数据,这在实际环境中是比较困难的。
一般有两种解决方案:一是采用截断,在拿用户好友集合时并不拿出用户所有的好友,而是只拿出和用户相似度最高的N个好友。另外在查询每个用户的历史行为时,可以只返回用户最近1个月的行为。二是重新设计数据库,加快查询速度。

2.4 社会化推荐系统和协同过滤推荐系统

社会化推荐系统的效果往往很难通过离线实验评测,因为社会化推荐的优势不在于增加预测准确度,而是在于通过用户的好友增加用户对推荐结果的信任度,从而让用户单击那些很冷门的推荐结果。此外,很多社交网站(特别是基于社交图谱的社交网站)中具有好友关系的用户并不一定有相似的兴趣。因此,利用好友关系有时并不能增加离线评测的准确率和召回率。

3,给好友推荐好友

好友推荐系统的目的是根据用户现有的好友、用户的行为记录给用户推荐新的好友,从而增加整个社交网络的稠密程度和社交网站用户的活跃度。

3.1 基于内容的匹配

利用内容信息计算用户的相似度和我们前面讨论的利用内容信息计算物品的相似度类似。

3.2 基于共同兴趣的好友推荐

用户往往不关心对于一个人是否在现实社会中认识,而只关心是否和他们有共同的兴趣爱好。因此,在这种网站中需要给用户推荐和他有共同兴趣的其他用户作为好友。可以通过类似userCF计算的饿用户兴趣相似度的方法。

3.3 基于社交网络图的好友推荐

在社交网站中,我们会获得用户之间现有的社交网络图,然后可以基于现有的社交网络给用户推荐新的好友,比如可以给用户推荐好友的好友。

基于好友的好友推荐算法可以用来给用户推荐他们在现实社会中互相熟悉,而在当前社交网络中没有联系的其他用户。
w u , v = ∣ o u t ( u ) ∣ ∣ o u t ( v ) ∣ ∣ o u t ( u ) ∣ ∣ o u t ( v ) ∣ w_{u,v}=\frac{|out(u)||out(v)|}{\sqrt{|out(u)||out(v)|}} wu,v=out(u)out(v) out(u)out(v) G表示user的出度out,GT表示user的in。这里在计算相似度的分母部分,可能会有疑问,不过已经注释了,后面三个公式同理。

    G, GT = train # 分别为out和in

    def GetRecommendation(user):
        if user not in G: return []
        # 根据相似度推荐N个未见过的
        user_sim = {}
        user_friends = set(G[user])
        for u in G[user]:
            if u not in GT: continue
            for v in GT[u]:# 如果u的朋友是x(out[u]=x),寻找相似user v,v的好友也是x(out[v]=x),那么搜索in[x]=v
                if v != user and v not in user_friends:
                    if v not in user_sim:
                        user_sim[v] = 0
                    user_sim[v] += 1
        user_sim = {v: user_sim[v] / math.sqrt(len(G[user]) * len(G[v])) for v in user_sim}
        return list(sorted(user_sim.items(), key=lambda x: x[1], reverse=True))[:N]

我们也可以定义in(u)是在社交网络图中指向用户u的用户的集合。在无向社交网络图中,out(u)和in(u)是相同的集合。但在微博这种有向社交网络中,这两个集合就不同了,因此也可以通过in(u)定义另一种相似度:
w u , v = ∣ i n ( u ) ∣ ∣ i n ( v ) ∣ ∣ i n ( u ) ∣ ∣ i n ( v ) ∣ w_{u,v}=\frac{|in(u)||in(v)|}{\sqrt{|in(u)||in(v)|}} wu,v=in(u)in(v) in(u)in(v)

    G, GT = train

    def GetRecommendation(user):
        if user not in GT: return []
        # 根据相似度推荐N个未见过的
        user_sim = {}
        user_friends = set(G[user]) if user in G else set()
        for u in GT[user]:
            if u not in G: continue
            for v in G[u]:
                if v != user and v not in user_friends:
                    if v not in user_sim:
                        user_sim[v] = 0
                    user_sim[v] += 1
        user_sim = {v: user_sim[v] / math.sqrt(len(GT[user] * len(GT[v]))) for v in user_sim}
        return list(sorted(user_sim.items(), key=lambda x: x[1], reverse=True))[:N]

这两种相似度的定义有着不同的含义,我们用微博中的关注来解释这两种相似度。如果用户u关注了用户v,那么v就属于out(u),而u就属于in(v)。因此, outw (u,v)越大表示用户u和v关注的用户集合重合度越大,而inw (u,v)越大表示关注用户u和关注用户v的用户的集合重合度越大。

还有第三种邮箱的相似度:
w u , v = ∣ o u t ( u ) ∣ ∣ i n ( v ) ∣ ∣ o u t ( u ) ∣ w_{u,v}=\frac{|out(u)||in(v)|}{\sqrt{|out(u)|}} wu,v=out(u) out(u)in(v)不过,这个相似度的含义是用户u关注的用户中,有多大比例也关注了用户v。考虑到名人的影响,在该相似度的定义下所有人都和名人有很大的相似度,进行改进:
w u , v = ∣ o u t ( u ) ∣ ∣ i n ( v ) ∣ ∣ o u t ( u ) ∣ ∣ i n ( v ) ∣ w_{u,v}=\frac{|out(u)||in(v)|}{\sqrt{|out(u)||in(v)|}} wu,v=out(u)in(v) out(u)in(v)

    G, GT = train

    def GetRecommendation(user):
        if user not in G: return []
        # 根据相似度推荐N个未见过的
        user_sim = {}
        user_friends = set(G[user])
        for u in G[user]:
            if u not in G: continue
            for v in G[u]:
                if v != user and v not in user_friends:
                    if v not in user_sim:
                        user_sim[v] = 0
                    user_sim[v] += 1
        user_sim = {v: user_sim[v] / math.sqrt(len(G[user]) * len(GT[v])) for v in user_sim}
        return list(sorted(user_sim.items(), key=lambda x: x[1], reverse=True))[:N]
  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值