从0开始学习R语言--Day29--社交网络分析

在探寻数据之间的关系时,由于数据类型的限制,很多时候我们可以从数据的现实角度出发去选择方法,而不是一昧地从头尝试不同方法去分类。假如我们用的是传染病在市面上的传播路径数据,亦或是病毒对于基因的感染模块,就可以采用社交网络分析的方法,它的原理是类似于我们平时使用软件时会弹出“你可能认识的人”,通过比对非共同好友的共同好友数来判断两人是否认识。

以下是一个例子:

# 安装必要的包
if (!require("igraph")) install.packages("igraph")
if (!require("tidygraph")) install.packages("tidygraph")
if (!require("ggraph")) install.packages("ggraph")

library(igraph)
library(tidygraph)

library(ggraph)
library(dplyr)

# 生成模拟社交网络数据 - 50个节点的小世界网络
set.seed(123)
social_net <- sample_smallworld(1, 50, 3, 0.1)

# 添加节点属性
V(social_net)$name <- paste("用户", 1:50)
V(social_net)$gender <- sample(c("男", "女"), 50, replace = TRUE)
V(social_net)$age <- sample(18:60, 50, replace = TRUE)

# 添加边属性(关系强度)
E(social_net)$strength <- runif(ecount(social_net), 0.1, 1)

# 转换为tidygraph对象
tidy_net <- as_tbl_graph(social_net)

# 计算网络指标并添加到网络对象
tidy_net <- tidy_net %>% 
  activate(nodes) %>% 
  mutate(
    degree = degree(social_net),
    closeness = closeness(social_net),
    betweenness = betweenness(social_net)
  )

# 社区检测
communities <- cluster_louvain(social_net)

# 添加社区信息到两个网络对象
V(social_net)$community <- communities$membership
tidy_net <- tidy_net %>% 
  activate(nodes) %>% 
  mutate(community = as.factor(communities$membership))

# 查看社区划分
print(paste("检测到", length(communities), "个社区"))
print(sizes(communities))

# 可视化社区结构 (使用tidygraph对象)
ggraph(tidy_net, layout = "fr") + 
  geom_edge_link(aes(alpha = strength), show.legend = FALSE) +
  geom_node_point(aes(color = community, size = betweenness)) +
  geom_node_text(aes(label = name), size = 3, repel = TRUE) +
  scale_color_brewer(palette = "Set1") +
  theme_graph() +
  labs(title = "社交网络社区结构",
       subtitle = "节点大小代表中介中心性,颜色代表不同社区",
       color = "社区")

# 基于共同好友的好友推荐
recommend_friends <- function(net, user_id, n = 3) {
  # 获取用户当前好友
  current_friends <- neighbors(net, user_id)
  
  # 找出有共同好友但还不是好友的用户
  candidates <- setdiff(
    V(net)[unlist(neighborhood(net, 1, current_friends))],
    c(user_id, current_friends)
  )
  
  # 计算共同好友数
  common_friends <- sapply(candidates, function(x) {
    length(intersect(neighbors(net, user_id), neighbors(net, x)))
  })
  
  # 返回推荐列表
  recs <- data.frame(
    user_id = candidates,
    user_name = V(net)$name[candidates],
    common_friends = common_friends
  ) %>% 
    arrange(desc(common_friends)) %>% 
    head(n)
  
  return(recs)
}

# 为用户1推荐3个可能的好友
recommend_friends(social_net, 1, 3)

输出:

Community sizes
 1  2  3  4  5  6 
11  5 12  5  9  8 
  user_id user_name common_friends
1       5    用户 5              3
2      49   用户 49              3
3       6    用户 6              2

从输出中可以看到,社区之间存在明显的人数差异,说明网络存在社群结构;而用户5和49拥有一样的共友数量,则说明他们的社交重叠度更高,更有可能是认识的,从图中也能看到靠的更近。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值