R语言手动计算加权网络Newman's Q、Qmax及同配系数并对比igraph、assortnet结果
加权网络指标计算错误修正与正确实现
1. 加权Newman模块化系数Q的计算错误与修正
你之前的计算存在三个核心错误:
- 错误1:加权网络中节点的度应替换为节点强度(即节点所有关联边的权重和),你使用的
degree(g)返回的是无权度(关联边的数量),不符合加权计算要求。 - 错误2:加权Q的分母是2倍的全网总边权重
W,不是2倍的边数量m,你误用了无权场景下的参数。 - 错误3:手动将邻接矩阵下三角置0,导致邻接矩阵求和结果仅为真实总权重的1/2,和公式要求的全对称邻接矩阵计算逻辑不符。
正确的加权Q计算公式为:
$Q = \frac{1}{2W} \sum_{i,j} (A_{ij} - \frac{s_i s_j}{2W}) \delta(c_i, c_j)$
其中$W$为全网边权重总和,$s_i$为节点$i$的强度,$\delta$为克罗内克函数,$c_i$为节点$i$所属社区。
修正后的计算代码:
# 计算节点强度(加权度) strengths <- strength(g, weights = E(g)$weight) # 计算全网总权重 W <- sum(E(g)$weight) # 全对称邻接矩阵,不要置0下三角 adjmat_full <- get.adjacency(g, sparse = FALSE, attr = "weight") %>% as.matrix() # 重新计算模块化矩阵 modmat_correct <- matrix(0, nrow = nrow(adjmat_full), ncol = ncol(adjmat_full)) for(i in 1:nrow(adjmat_full)){ for(j in 1:ncol(adjmat_full)){ modmat_correct[i,j] <- (adjmat_full[i,j] - strengths[i] * strengths[j] / (2 * W)) * kdmat[i,j] } } # 计算手动Q (myQ_correct <- 1/(2 * W) * sum(modmat_correct)) # 和igraph输出的加权Q对比,结果一致 (igQ <- igraph::modularity(g, membership = community, weights = E(g)$weight))
2. Qmax的正确计算方法
你之前的Qmax计算同样误用了无权参数,正确的加权场景下Qmax计算逻辑为:当社区划分固定时,Q的最大值出现在所有边都落在社区内部的情况,计算公式为:
$Q_{max} = 1 - \frac{1}{(2W)^2} \sum_{c} S_c^2$
其中$S_c$为社区$c$所有节点的强度总和。
修正后的计算代码:
# 计算每个社区的总强度 S_c <- tapply(strengths, community, sum) (qmax_correct <- 1 - sum(S_c^2)/(2*W)^2)
计算完成后,myQ_correct/qmax_correct的结果会和assortnet输出的加权同配系数一致。
3. 同配系数差异说明
assortnet::assortment.discrete默认支持加权网络计算,你得到的0.7823是正确的加权同配系数。igraph::assortativity_nominal函数本身不支持加权网络计算,仅能返回无权场景下的离散型同配系数,所以和加权结果差异极大,属于正常情况。如果需要用igraph生态计算加权同配系数,可自行实现公式或者直接调用assortnet包的对应函数。
内容的提问来源于stack exchange,提问作者highlandsmain
相关产品推荐
相关产品推荐

