基于社交网络的推荐--包括给用户推荐好友的原理及代码实现

简介: 基于社交网络的推荐--包括给用户推荐好友的原理及代码实现

获取社交网络数据途径


社交网络数据的来源有下面几个:

电子邮件

用户注册信息:比如公司、学校等 (用于冷启动问题)

用户的位置数据:IP地址或者GPS数据

论坛和讨论组 (这个获取的一般是兴趣爱好)

即时聊天工具:QQ

社交网站: Facebook (社交图谱) Twitter (兴趣图谱)


社交网络数据简介


我们用图G(V,E,W)定义一个社交网络:


V是顶点集合,每个顶点是一个用户id

E是边集合,如果Va和Vb有社交关系,即存在E(a,b)

W(a,b)表示边的权重


一般来说,有3种不同的社交网络数据:


双向确认的社交网络数据:一般通过无向图表示

单向关注的社交网络数据:用户关系是单向的,可以通过有向图表示

基于社区的社交网络数据:比如豆瓣小组


基于社交网络的推荐


利用用户的社交网络数据进行推荐优点:

1.好友推荐可以增加推荐的信任度

2.社交网络可以解决冷启动问题

(缺点:由于用户的好友关系可能不是基于共同兴趣产生的,例如a-b是基于b的颜值??所以用户好友的兴趣与用户兴趣不一致)


基于领域的社会化推荐


1)最简单的方法是给用户推荐好友喜欢的物品集合,用户u对物品i的兴趣pui可以通过如下公式计算:

1.png

其中out(u)是用户u的好友集合,如果用户v喜欢物品i,则rvi=1,否则为0


2)当然,不同好友之间的熟悉度和兴趣相似度是不一样的,因此应该在推荐的时候把这个考虑在内:2.png


这里的wuv由两部分相似度构成,一部分是用户u和用户v的熟悉程度,另一部分是用户u和用户v的兴趣相似度。

其中,用户u和用户v的熟悉程度由如下公式度量,即他们之间的共同好友比例:

而用户u和用户v的兴趣相似度由如下公式度量,即他们喜欢的物品重合度:

3.png


从两方面改进基于邻域的社会化推荐算法


两处截断:


第一处截断:哪用户好友集合时只拿出和用户相似度最高的N个好友

第二处截断:查询用户行为做兴趣相似度时,只返回最近1个月的行为

重新设计数据库


给用户推荐好友


基于内容的匹配


常用内容属性包括:

用户的人口统计学属性(年龄、职业、性别等);

用户的兴趣(喜欢的物品和发布过的言论);

用户的位置信息(用户住址、邮编、IP等);


基于共同兴趣的好友推荐


利用UserCF的思想,如果两个用户喜欢相同的物品(比如同一条微博),就说明他们具有相似的兴趣;此外,也可以根据用户在社交网络中的评论提取用户的兴趣标签,来计算用户的兴趣相似度。


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


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

out(u)是在社交网络图中用户u指向的其他好友的集合

in(u)是在社交网络图中指向用户u的用户集合


通过用户u和用户v的出度和入度,定义W。根据相似度W进行推荐


计算相似度方法的解释在最后代码里

有下面几种方法计算相似度:

1.用户u,v的共同好友比例来计算相似度

5.png

def FriendSuggestion_out(u,G_out,G_in):
    suggestions = dict()
    G_out.setdefault(u,set())
    G_in.setdefault(u,set())
    friends = G_out[u]
#     i = 0
    for u_friend in G_out[u]:
#         i += 1
        for u_friend_friend in G_in[u_friend]:
            if u_friend_friend in friends:
                continue
            suggestions.setdefault(u_friend_friend,0)
            suggestions[u_friend_friend] += 1
    for i,j in suggestions.items():
        if i == u:
            continue
        if len(G_out[i]) == 0:
            suggestions[i] = 0
        else:
            suggestions[i] = j / math.sqrt(len(G_out[u]) * len(G_out[i])) 
#     return dict(sorted(suggestions.items(),key=itemgetter(1),reverse=True)[:k])
    return suggestions

2.关注u,v的用户的集合交集计算相似度

6.png

def FriendSuggestion_in(u,G_out,G_in):
    suggestions = dict()
    G_out.setdefault(u,set())
    G_in.setdefault(u,set())
    friends = G_out[u]
#     i = 0
    for u_friend in G_in[u]:
#         i += 1
        for u_friend_friend in G_out[u_friend]:
            if u_friend_friend in friends:
                continue
            suggestions.setdefault(u_friend_friend,0)
            suggestions[u_friend_friend] += 1
#         print(i)
#         suggestions[u_friend] = suggestions[u_friend_friend]
    for i,j in suggestions.items():
        if i == u:
            continue
        if len(G_in[i]) == 0:
            suggestions[i] = 0
        else:
            suggestions[i] = j / math.sqrt(len(G_in[u]) * len(G_in[i])) 
    return suggestions

3.u关注的用户中,有多大比例也关注用户v,同时施加惩罚in(v)来计算相似度

(考虑到某一名人,存在很多粉丝,导致每个人都与名人有很大相似度 例如有一亿粉丝的何老师~)

7.png

def FriendSuggestion_mix(u,G_out,G_in):
    suggestions = dict()
    G_out.setdefault(u,set())
    G_in.setdefault(u,set())
    friends = G_out[u]
    for u_friend in G_out[u]:
        for u_friend_friend in G_out[u_friend]:
            if u_friend_friend in friends:
                continue
            suggestions.setdefault(u_friend_friend,0)
            suggestions[u_friend_friend] += 1
#         suggestions[u_friend] = suggestions[u_friend_friend]
    for i,j in suggestions.items():
        if len(G_in[i]) == 0:
            suggestions[i] = 0
        else:
            suggestions[i] = j / math.sqrt(len(G_out[u]) * len(G_in[i])) 
    return suggestions


实现给用户推荐好友的完整过程代码


import os
import math
from operator import itemgetter
from sklearn.model_selection import train_test_split
import random
#获取文件列表 取前200个文件¶
edges = [name for name in os.listdir('twitter/')
         if name.endswith(".edges")]
#edges[:5]
train_G_out = dict()
test_G_out = dict()
train_G_in = dict()
test_G_in = dict()
#获取文件名的ID 以及.edges文件里的id 得到out in 两个字典
for file in edges[:200]:
    with open('twitter/' + file) as f:
        lines = f.readlines()
    for line in lines:
        a,b = line.split(" ")
        b = b.strip("\n")
        if random.random() < 0.8: #划分数据集
            train_G_out.setdefault(file[:-6],set())
            train_G_out.setdefault(a,set())
            train_G_out.setdefault(b,set())
            train_G_out[file[:-6]].add(a)
            train_G_out[file[:-6]].add(b)
            train_G_out[a].add(b)
            train_G_in.setdefault(file[:-6],set())
            train_G_in.setdefault(a,set())
            train_G_in.setdefault(b,set())
            train_G_in[a].add(file[:-6])
            train_G_in[b].add(a)
            train_G_in[b].add(file[:-6]) #str
        else:
            test_G_out.setdefault(file[:-6],set())
            test_G_out.setdefault(a,set())
            test_G_out.setdefault(b,set())
            test_G_out[file[:-6]].add(a)
            test_G_out[file[:-6]].add(b)
            test_G_out[a].add(b)
            test_G_in.setdefault(file[:-6],set())
            test_G_in.setdefault(a,set())
            test_G_in.setdefault(b,set())
            test_G_in[a].add(file[:-6])
            test_G_in[b].add(a)
            test_G_in[b].add(file[:-6]) #str
def FriendSuggestion_out(u,G_out,G_in):
    suggestions = dict()
    G_out.setdefault(u,set())
    G_in.setdefault(u,set())
    friends = G_out[u]
#     i = 0
    for u_friend in G_out[u]:  #遍历用户u关注的好友
#         i += 1
        for u_friend_friend in G_in[u_friend]: #u关注的好友中的粉丝列表
            if u_friend_friend in friends: #若粉丝是u关注的好友就跳过
                continue
            suggestions.setdefault(u_friend_friend,0) 
            suggestions[u_friend_friend] += 1 #对于u关注的好友的粉丝与u有一个交集 进行+1
    for i,j in suggestions.items():
        if i == u:  #去除本身
            suggestions[i] = 0
        elif len(G_out[i]) == 0:
            suggestions[i] = 0
        else:
            suggestions[i] = j / math.sqrt(len(G_out[u]) * len(G_out[i])) 
#     return dict(sorted(suggestions.items(),key=itemgetter(1),reverse=True)[:k])
    return suggestions
def FriendSuggestion_in(u,G_out,G_in):
    suggestions = dict()
    G_out.setdefault(u,set())
    G_in.setdefault(u,set())
    friends = G_out[u]
#     i = 0
    for u_friend in G_in[u]: #遍历关注用户u的粉丝
#         i += 1
        for u_friend_friend in G_out[u_friend]: #u的粉丝的关注列表好友
            if u_friend_friend in friends:
                continue
            suggestions.setdefault(u_friend_friend,0)
            suggestions[u_friend_friend] += 1  #uv的粉丝交集 +1
#         print(i)
#         suggestions[u_friend] = suggestions[u_friend_friend]
    for i,j in suggestions.items():
        if i == u:
            suggestions[i] = 0
        elif len(G_in[i]) == 0:
            suggestions[i] = 0
        else:
            suggestions[i] = j / math.sqrt(len(G_in[u]) * len(G_in[i])) 
    return suggestions
def FriendSuggestion_mix(u,G_out,G_in):
    suggestions = dict()
    G_out.setdefault(u,set())
    G_in.setdefault(u,set())
    friends = G_out[u]
    for u_friend in G_out[u]: #遍历u关注的好友列表
        for u_friend_friend in G_out[u_friend]: #遍历u好友的关注列表 即u关注的好友是u_friend_friend的粉丝 
            if u_friend_friend in friends:
                continue
            suggestions.setdefault(u_friend_friend,0)
            suggestions[u_friend_friend] += 1  #即u关注的好友有多大比例是用户v的粉丝 交集+1
#         suggestions[u_friend] = suggestions[u_friend_friend]
    for i,j in suggestions.items():
        if i == u:
            suggestions[i] = 0
        elif len(G_in[i]) == 0:
            suggestions[i] = 0
        else:
            suggestions[i] = j / math.sqrt(len(G_out[u]) * len(G_in[i])) 
    return suggestions
def recommend(u,G_out,G_in,k,choice):
    if choice == 'out':
        suggestions = FriendSuggestion_out(u,G_out,G_in)
    elif choice == 'in':
        suggestions = FriendSuggestion_in(u,G_out,G_in)
    else:
        suggestions = FriendSuggestion_mix(u,G_out,G_in)
    return dict(sorted(suggestions.items(),key=itemgetter(1),reverse=True)[:k])
def precision(k,choice):
    right = 0
    predict = 0
    for u in test_G_out.keys():
        x = recommend(u,train_G_out,train_G_in,k,choice)
        for i in x.keys():
            if i in test_G_out[u]:
                right += 1
        predict += k
    ans = right / (predict * 1.0)
    return ans * 100
#为用户‘100318079’推荐
print(recommend('100318079',train_G_out,train_G_in,5,'out'))
#验证测试集正确率
print("正确率:%.2f%%"%(precision(4,'mix')))
#{'217796457': 0.36794648440311994, 
#  '261753869': 0.3611730459561101, 
#  '92336981': 0.3611730459561101, 
#  '77618627': 0.35781322366606716, 
#  '540912889': 0.3517811819867572}
#正确率:19.80%
相关文章
|
3月前
|
网络协议 安全 5G
网络与通信原理
【10月更文挑战第14天】网络与通信原理涉及众多方面的知识,从信号处理到网络协议,从有线通信到无线通信,从差错控制到通信安全等。深入理解这些原理对于设计、构建和维护各种通信系统至关重要。随着技术的不断发展,网络与通信原理也在不断演进和完善,为我们的生活和工作带来了更多的便利和创新。
82 3
|
2天前
|
机器学习/深度学习 算法 PyTorch
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
软演员-评论家算法(Soft Actor-Critic, SAC)是深度强化学习领域的重要进展,基于最大熵框架优化策略,在探索与利用之间实现动态平衡。SAC通过双Q网络设计和自适应温度参数,提升了训练稳定性和样本效率。本文详细解析了SAC的数学原理、网络架构及PyTorch实现,涵盖演员网络的动作采样与对数概率计算、评论家网络的Q值估计及其损失函数,并介绍了完整的SAC智能体实现流程。SAC在连续动作空间中表现出色,具有高样本效率和稳定的训练过程,适合实际应用场景。
20 7
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
|
11天前
|
前端开发 网络协议 安全
【网络原理】——HTTP协议、fiddler抓包
HTTP超文本传输,HTML,fiddler抓包,URL,urlencode,HTTP首行方法,GET方法,POST方法
|
11天前
|
域名解析 网络协议 关系型数据库
【网络原理】——带你认识IP~(长文~实在不知道取啥标题了)
IP协议详解,IP协议管理地址(NAT机制),IP地址分类、组成、特殊IP地址,MAC地址,数据帧格式,DNS域名解析系统
|
11天前
|
存储 JSON 缓存
【网络原理】——HTTP请求头中的属性
HTTP请求头,HOST、Content-Agent、Content-Type、User-Agent、Referer、Cookie。
|
11天前
|
安全 算法 网络协议
【网络原理】——图解HTTPS如何加密(通俗简单易懂)
HTTPS加密过程,明文,密文,密钥,对称加密,非对称加密,公钥和私钥,证书加密
|
11天前
|
XML JSON 网络协议
【网络原理】——拥塞控制,延时/捎带应答,面向字节流,异常情况
拥塞控制,延时应答,捎带应答,面向字节流(粘包问题),异常情况(心跳包)
|
13天前
|
网络协议 安全 网络安全
探索网络模型与协议:从OSI到HTTPs的原理解析
OSI七层网络模型和TCP/IP四层模型是理解和设计计算机网络的框架。OSI模型包括物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,而TCP/IP模型则简化为链路层、网络层、传输层和 HTTPS协议基于HTTP并通过TLS/SSL加密数据,确保安全传输。其连接过程涉及TCP三次握手、SSL证书验证、对称密钥交换等步骤,以保障通信的安全性和完整性。数字信封技术使用非对称加密和数字证书确保数据的机密性和身份认证。 浏览器通过Https访问网站的过程包括输入网址、DNS解析、建立TCP连接、发送HTTPS请求、接收响应、验证证书和解析网页内容等步骤,确保用户与服务器之间的安全通信。
62 1
|
11天前
|
网络协议 算法 Java
【JavaEE】——初始网络原理
局域网,广域网,局域网连接方式,交换机,集线器,路由器,网络通信,五元组(源IP,源端口,目的IP,目的端口,协议),协议分层,TCP/IP五层网络协议,封装和分用,交换机和路由器的封装和分用
|
2月前
|
运维 物联网 网络虚拟化
网络功能虚拟化(NFV):定义、原理及应用前景
网络功能虚拟化(NFV):定义、原理及应用前景
119 3

热门文章

最新文章