社交⽹络数据
数据获取
社交网络数据的获取方式:
- 电子邮件
- 用户注册信息
- 用户位置信息
- 论坛和讨论组
- 及时聊天工具
- 社交网站
数据类型
社交⽹络定义了⽤户之间的联系,因此可以⽤图定义社交⽹络。
⽤图 G(V,E,w)定义⼀个社交⽹络,其中V 是顶点集合,每个顶点代表⼀个⽤户,E是边集合,如果⽤户va 和vb 有社交⽹络关系,那么就有⼀条 e(va,vb)连接这两个⽤户,⽽ w(va,vb)定义了边的权重。对图G 中的⽤户顶点 u,定义 out(u)为顶点 u指向的顶点集合,定义为int(u)指向顶点 u的顶点集合。
-
双向确认的社交⽹络数据,无向边连接
-
单向关注的社交⽹络数据,有向边连接
-
基于社区的社交⽹络数据
基于社交网络的推荐
基于邻域的社会化推荐
给定一个社交网络和一份用户数据集,我们就可以利用社交网络来查询好友关系。
基于邻域的社会化推荐算法,在实际操作中很难获得所有好友的历史行为数据。
可以两方面改进:
- 两处截断。只拿和用户相似最高的N个好友;每个用户只返回最近1个月的行为。
- 重新设计数据库。给每个用户设计维护一个消息队列。
基于图的社会化推荐算法
信息流推荐
信息流的个性化推荐要解决的问题就是如何进⼀步帮助⽤户从信息墙上挑选有⽤的信息。
近似于Facebook的EdgeRank算法
EdgeRank算法的个性化因素仅仅是好友的熟悉度,它并没有考虑帖⼦内容和⽤户兴趣的相似度。
好友推荐
好友推荐系统的⽬的是根据⽤户现有的好友、⽤户的⾏为记录给⽤户推荐新的好友,从⽽增加整个社交⽹络的稠密程度和社交⽹站⽤户的活跃度。
基于内容推荐
推荐相似内容的用户作为好友,如:年龄,性别,职业,地理位置,喜欢物品等
基于兴趣推荐
在Twitter和微博为代表的以兴趣图谱为主的社交⽹络中,⽤户往往不关⼼对于⼀个⼈是否在现实社会中认识,⽽只关⼼是否和他们有共同的兴趣爱好。因此,给⽤户推荐和他有共同兴趣的其他⽤户。
使用Twitter数据集。
#基于共同兴趣推荐好友
def InterestBased(user):
recommend_user = {}
with open('../Twitter-基于社交网络的推荐数据集/twitter/%s.circles'%user) as f:
circle_user_list = [i.strip().split() for i in f.readlines()]
for circle in circle_user_list:
for j in circle[1:]:
if j not in recommend_user.keys():
recommend_user.setdefault(j,0)
#热门圈子进行惩罚
recommend_user[j] += round(1/len(circle),2)
recommend_user = {k: v for k, v in sorted(recommend_user.items(), key=lambda item: item[1], reverse=True)[:20] if
v != 0}
return recommend_user
print(InterestBased('428333'))
{'86902774': 0.45, '78231411': 0.45, '15214543': 0.26, '104446737': 0.16, '45536687': 0.14, '23572083': 0.14, '112391041': 0.14, '24797315': 0.14, '83590349': 0.14, '18170896': 0.12, '113430220': 0.12, '15224867': 0.12, '27719762': 0.04, '35629711': 0.04, '15909010': 0.04, '27885519': 0.04, '20642310': 0.04, '21875245': 0.04, '104851609': 0.04, '16139105': 0.04}
基于社交网络图推荐
利用好友比例计算相似度,引申出以下三种:
在无向图中第二种与第三种一样,因为out(u)==in(u),而无向图中则不是。
import os
#基于社交网络推荐好友
class SocialBased():
def __init__(self,file_dir):
self.file_dir = file_dir
# 导入文件目录
file_list = os.listdir(self.file_dir)
self.fname_list = list(set([i.split('.')[0] for i in file_list]))
#基于出度与出度计算相似度
def out_out(self,ruser):
#计算指定用户的出度,即该用户关注的用户
with open(self.file_dir+'%s.edges'%ruser) as f:
user_set = set([i.strip().split()[0] for i in f.readlines()])
#计算其他用户的出度,并计算相似度
recom_user = dict()
for i in self.fname_list :
if i== ruser:
pass
else:
recom_user.setdefault(i,{})
with open(self.file_dir+i+'.edges') as f:
temp = set([i.strip().split()[0] for i in f.readlines()])
recom_user[i] = round(len(user_set & temp)/(len(user_set)*len(temp))**0.5,3)
#返回相似度高的前20个用户
return {k:v for k,v in sorted(recom_user.items(),key=lambda item:item[1],reverse=True)[:20] if v != 0}
#基于入度与入度计算相似度
def in_in(self,ruser):
#计算每个用户的入度用户,即关注该用户的用户
user_in_dict = {}
for user in self.fname_list:
with open(self.file_dir+'%s.edges'%user) as f:
user_set1 = [i.strip().split()[0] for i in f.readlines()]
f.seek(0,0)
user_set2 = [i.strip().split()[1] for i in f.readlines()]
#对第一列数据处理,该用户关注的用户
for i in user_set1:
if i not in user_in_dict.keys():
user_in_dict.setdefault(i, [])
user_in_dict[i].append(user)
# 对第二列数据处理,该用户关注的用户,关注的用户
for i in range(len(user_set2)):
if user_set2[i] not in user_in_dict.keys():
user_in_dict.setdefault(user_set2[i], [])
user_in_dict[user_set2[i]].append(user_set1[i])
#去重,并计算相似度
user_list = user_in_dict.keys()
user_in_dict[ruser] = set(user_in_dict[ruser])
recommend_user = {}
for i in user_list:
user_in_dict[i] = set(user_in_dict[i])
if i == ruser:
pass
else:
recommend_user[i] = round(len(user_in_dict[i] & user_in_dict[ruser])/(len(user_in_dict[i]) * len(user_in_dict[ruser]))**0.5,3)
recommend_user = {k:v for k,v in sorted(recommend_user.items(),key=lambda item:item[1],reverse=True)[:20] if v !=0}
return recommend_user
#基于出度与入度计算相似度
def out_in(self,ruser):
#计算该用户的出度,即该用户关注的用户
with open(self.file_dir+'%s.edges'%ruser) as f:
user_set = set([i.strip().split()[0] for i in f.readlines()])
#同上计算每一个用户的入度
user_in_dict = {}
for user in self.fname_list:
with open(self.file_dir+'%s.edges' % user) as f:
user_set1 = [i.strip().split()[0] for i in f.readlines()]
f.seek(0, 0)
user_set2 = [i.strip().split()[1] for i in f.readlines()]
for i in user_set1:
if i not in user_in_dict.keys():
user_in_dict.setdefault(i, [])
user_in_dict[i].append(user)
for i in range(len(user_set2)):
if user_set2[i] not in user_in_dict.keys():
user_in_dict.setdefault(user_set2[i], [])
user_in_dict[user_set2[i]].append(user_set1[i])
#计算相似度
recommend_user = {}
for i in user_in_dict.keys():
user_in_dict[i] = set(user_in_dict[i])
if i != ruser:
recommend_user[i] = round(len(user_set & user_in_dict[i])/(len(user_set)*len(user_in_dict[i]))**0.5,3)
recommend_user = {k: v for k, v in sorted(recommend_user.items(), key=lambda item: item[1], reverse=True)[:20] if
v != 0}
return recommend_user
baso = SocialBased('../Twitter-基于社交网络的推荐数据集/twitter/')
print('out-out')
print(baso.out_out('93787797'))
print('in-in')
print(baso.in_in('93787797'))
print('out-in')
print(baso.out_in('93787797'))
out-out
{'59588845': 0.136, '200494218': 0.132, '40981798': 0.13, '358845982': 0.129, '160237722': 0.127, '19933035': 0.125, '430313102': 0.116, '228270980': 0.115, '151495845': 0.114, '230880104': 0.111, '69548480': 0.111, '18996905': 0.11, '107511013': 0.11, '202114894': 0.109, '152388029': 0.103, '18951737': 0.101, '43003845': 0.098, '314316607': 0.098, '186909156': 0.098, '64496469': 0.097}
in-in
{'104646268': 0.535, '81270719': 0.5, '166287349': 0.5, '152553053': 0.5, '192383259': 0.5, '406239056': 0.408, '191280225': 0.408, '192707262': 0.408, '79076592': 0.408, '152445382': 0.408, '453667258': 0.408, '218280403': 0.408, '219723179': 0.354, '152388833': 0.354, '126710787': 0.354, '145025085': 0.333, '90016131': 0.316, '477294097': 0.316, '227426011': 0.316, '394538655': 0.316}
out-in
{'51222571': 0.42, '50613262': 0.377, '21465973': 0.329, '52263864': 0.32, '26269424': 0.311, '14583400': 0.309, '229983913': 0.302, '33905807': 0.302, '49161606': 0.293, '212547041': 0.293, '72152715': 0.293, '139559356': 0.283, '100133641': 0.272, '138999836': 0.272, '120527521': 0.272, '189753564': 0.267, '212006583': 0.262, '155610817': 0.262, '212595641': 0.253, '79613352': 0.251}