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

时间:2018-04-14 18:31:39

标签: r cluster-analysis igraph

我有一个得分的相关矩阵,我希望在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

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

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

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

感谢您的任何建议!如果有帮助,我可以提供进一步的信息。

1 个答案:

答案 0 :(得分:2)

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

vcount(test2)
ecount(test2)

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

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

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

首先,假设您想要变量,其相关性接近-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