[英]Graph learning in R, igraph, tidygraph
我有一个图表,每个节点都有一个值(红色值)。
我想做以下两件事(我猜1是2的特例):
应该为每个节点分配指向它的直接对等点的值的平均值。 例如节点 #5 (1+2)/2=1.5
或节点 #3 (0+2+0)/3=2/3
。
代替直接邻居,包括所有连接的节点,但扩散时间为 1/n,其中 n 是到节点的距离。 信息越远,我们所拥有的信号就越弱。
我查看了 igraph 的功能,但找不到任何这样做的东西(虽然我可能已经监督了)。 我怎么能做这个计算?
下面是具有随机值的示例网络的代码。
library(tidyverse)
library(tidygraph)
library(ggraph)
set.seed(6)
q <- tidygraph::play_erdos_renyi(6, p = 0.2) %>%
mutate(id = row_number(),
value = sample(0:3, size = 6, replace = T))
q %>%
ggraph(layout = "with_fr") +
geom_edge_link(arrow = arrow(length = unit(0.2, "inches"),
type = "closed")) +
geom_node_label(aes(label = id)) +
geom_node_text(aes(label = value), color = "red", size = 7,
nudge_x = 0.2, nudge_y = 0.2)
编辑,找到了1的解决方案
q %>%
mutate(value_smooth = map_local_dbl(order = 1, mindist = 1, mode = "in",
.f = function(neighborhood, ...) {
mean(as_tibble(neighborhood, active = 'nodes')$value)
}))
编辑2,解决方案2,我猜不是最优雅的
q %>%
mutate(value_smooth = map_local_dbl(order = 1, mindist = 0, mode = "in",
.f = function(neighborhood, node, ...) {
ne <- neighborhood
ne <- ne %>%
mutate(d = node_distance_to(which(as_tibble(ne,
active = "nodes")$id == node)))
as_tibble(ne, active = 'nodes') %>%
filter(d != 0) %>%
mutate(helper = value/d) %>%
summarise(m = mean(value)) %>%
pull(m)
}))
编辑 3,一个更快的替代map_local_dbl
map_local
循环遍历图的所有节点。 对于大图,这需要很长时间。 对于仅计算均值,这不是必需的。 一个更快的替代方法是使用邻接矩阵和一些矩阵乘法。
q_adj <- q %>%
igraph::as_adjacency_matrix()
# out
(q_adj %*% as_tibble(q)$value) / Matrix::rowSums(q_adj)
# in
(t(q_adj) %*% as_tibble(q)$value) / Matrix::colSums(q_adj)
邻接矩阵的平方是二阶邻接矩阵,以此类推。 因此,也可以创建问题 2 的解决方案。
编辑4,直接加权平均
假设原始图具有与每条边相关的权重。
q <- q %>%
activate(edges) %>%
mutate(w = c(1,0.5,1,0.5,1,0.5,1)) %>%
activate(nodes)
我们想计算直接同行价值的加权平均值。
q_adj_wgt <- q %>%
igraph::as_adjacency_matrix(attr = "w")
# out
(q_adj_wgt %*% as_tibble(q)$value) / Matrix::rowSums(q_adj_wgt)
# in
(t(q_adj_wgt) %*% as_tibble(q)$value) / Matrix::colSums(q_adj_wgt)
可能你可以试试下面的代码
q %>%
set_vertex_attr(
name = "value",
value = sapply(
ego(., mode = "in", mindist = 1),
function(x) mean(x$value)
)
)
这使
# A tbl_graph: 6 nodes and 7 edges
#
# A directed simple graph with 1 component
#
# Node Data: 6 x 2 (active)
id value
<int> <dbl>
1 1 0.5
2 2 NaN
3 3 0.667
4 4 NaN
5 5 1.5
6 6 NaN
#
# Edge Data: 7 x 2
from to
<int> <int>
1 3 1
2 6 1
3 1 3
# ... with 4 more rows
应该为每个节点分配指向它的直接对等点的值的平均值。
猜你是真的意思
在更改任何节点值之前,应为每个节点分配指向它的直接对等点的值的平均值
这似乎微不足道 - 也许我错过了什么?
Loop over nodes
Sum values of adjacent nodes
Calculate mean and store in vector by node index
Loop over nodes
Set node value to mean stored in previous loop
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.