首页 文章

R中的Louvain社区检测使用igraph - 边缘和顶点格式

提问于
浏览
1

我有一个得分的相关矩阵,我想在igraph中使用Louvain方法进行社区检测,在R.我使用 cor2dist 将相关矩阵转换为距离矩阵,如下所示:

distancematrix <- cor2dist(correlationmatrix)

这给出了距离0-2的400 x 400矩阵 . 然后我使用以下方法从http://kateto.net/networks-r-igraph(第3.1节)制作了边缘(距离)和顶点(每个400个人)的列表 .

library(igraph)
test <- as.matrix(distancematrix)
mode(test) <- "numeric"
test2 <- graph.adjacency(test, mode = "undirected", weighted = TRUE, diag = TRUE)
E(test2)$weight
get.edgelist(test2)

然后,我写了'from'和'to'边缘列表的csv文件,以及相应的权重:

edgeweights <-E(test2)$weight
write.csv(edgeweights, file = "edgeweights.csv")
fromtolist <- get.edgelist(test2)
write.csv(fromtolist, file = "fromtolist.csv")

从这两个文件中我创建了一个名为“nodes.csv”的.csv文件,该文件只包含400个人的所有顶点ID:

id
1
2
3
4
...
400

还有一个名为“edges.csv”的.csv文件,详细说明了每个节点之间的“from”和“to”,并提供了每个边缘的权重(即距离度量):

from    to   weight
1       2    0.99
1       3    1.20
1       4    1.48
...
399     400  0.70

然后我尝试使用此节点和边缘列表来创建igraph对象,并以下列方式运行louvain群集:

nodes <- read.csv("nodes.csv", header = TRUE, as.is = TRUE)
edges <- read.csv("edges.csv", header = TRUE, as.is = TRUE)
clustergraph <- graph_from_data_frame(edges, directed = FALSE, vertices = nodes)
clusterlouvain <- cluster_louvain(clustergraph)

不幸的是,这并没有正确地进行louvain社区检测 . 我预计这将返回2-4个不同的社区,可以与here类似地绘制,但 sizes(clusterlouvain) 返回:

Community sizes
 1 
 400

表明所有人都被分到同一个社区 . 聚类也立即运行(即几乎没有计算时间),这也让我觉得它无法正常工作 .

My question is: 任何人都可以建议为什么cluster_louvain方法不起作用并且只识别一个社区?我认为我必须错误地指定距离矩阵或边/节点,或者以其他方式不给cluster_louvain方法提供正确的输入 . 我对R比较新,所以非常感谢任何建议 . 我已经在相同的距离矩阵(即k-means)上成功地使用了其他社区检测方法,这些方法确定了2-3个社区,但是我想知道我在这里做错了什么 .

我知道在R中有多个关于使用igraph的其他查询,但我没有找到一个明确指定边缘和节点的输入格式(来自相关矩阵)以使louvain社区检测正常工作 .

谢谢你的建议!如果有帮助,我可以提供更多信息 .

1 回答

  • 1

    我相信 cluster_louvain 完全应该对你的数据做了什么 . 问题是你的图 . 你的代码包括 get.edgelist(test2) 行 . 这必须产生大量的产出 . 相反,试试吧

    vcount(test2)
    ecount(test2)
    

    既然你说你的相关矩阵是400x400,我希望你会得到vcount给出400而ecount给出79800 = 400 * 399 / 2.当你构建它时,每个节点都直接连接到所有其他节点 . 当然只有一个大社区 .

    我怀疑你要做的是组相关的变量 . 如果相关性接近零,则变量应该是未连接的 . 似乎不太清楚的是如何处理相关性接近-1的变量 . 你想要他们连接吗?我们可以这样做 .

    您没有提供任何数据,因此我将使用 mlbench 包中的Ionosphere数据进行说明 . 我将尝试非常密切地模仿您的代码,但会更改一些变量名称 . 另外,对于我的目的,将边写入文件然后再读回它是没有意义的,所以我将直接使用构造的边 .

    首先,假设您希望连接具有接近-1的相关性的变量 .

    library(igraph)
    library(mlbench)    # for Ionosphere data
    library(psych)      # for cor2dist
    data(Ionosphere)
    
    correlationmatrix = cor(Ionosphere[, which(sapply(Ionosphere, class) == 'numeric')])
    distancematrix <- cor2dist(correlationmatrix)
    
    DM1 <- as.matrix(distancematrix)
    ## Zero out connections where there is low (absolute) correlation
    ## Keeps connection for cor ~ -1
    ## You may wish to choose a different threshhold
    DM1[abs(correlationmatrix) < 0.33] = 0
    
    G1 <- graph.adjacency(DM1, mode = "undirected", weighted = TRUE, diag = TRUE)
    vcount(G1)
    [1] 32
    ecount(G1)
    [1] 140
    

    不是完全连接的图形!现在让我们找到社区 .

    clusterlouvain <- cluster_louvain(G1)
    plot(G1, vertex.color=rainbow(3, alpha=0.6)[clusterlouvain$membership])
    

    Community 1

    相反,如果您不希望连接具有负相关的变量,只需去除上面的绝对值 . 这应该少得多

    DM2 <- as.matrix(distancematrix)
    ## Zero out connections where there is low correlation
    DM2[correlationmatrix < 0.33] = 0
    
    G2 <- graph.adjacency(DM2, mode = "undirected", weighted = TRUE, diag = TRUE)
    clusterlouvain <- cluster_louvain(G2)
    plot(G2, vertex.color=rainbow(4, alpha=0.6)[clusterlouvain$membership])
    

    Community 2

相关问题