【问题标题】:Louvain community detection in R using igraph - format of edges and vertices使用 igraph 在 R 中进行 Louvain 社区检测 - 边和顶点的格式
【发布时间】:2018-09-24 20:47:06
【问题描述】:

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

distancematrix <- cor2dist(correlationmatrix)

这给出了一个 400 x 400 的距离矩阵,从 0 到 2。然后,我使用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   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 比较陌生,因此非常感谢您提供任何建议。我已经成功地在识别 2-3 个社区的同一距离矩阵(即 k-means)上使用了其他社区检测方法,但想了解我在这里做错了什么。

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

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

【问题讨论】:

    标签: r cluster-analysis igraph


    【解决方案1】:

    我相信cluster_louvain 完全按照它应该对您的数据执行的操作。 问题是您的图表。您的代码包含get.edgelist(test2) 行。那必须产生大量的输出。不如试试这个

    vcount(test2)
    ecount(test2)
    

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

    我怀疑您正在尝试做的是对相关的变量进行分组。 如果相关性接近于零,则变量应该是不相关的。似乎不太清楚的是如何处理相关性接近 -1 的变量。你想让它们连接还是不连接?无论哪种方式,我们都可以做到。

    您没有提供任何数据,因此我将使用来自的电离层数据进行说明 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])
    

    如果相反,您不希望连接具有负相关性的变量, 只需摆脱上面的绝对值。这应该少得多的联系

    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])
    

    【讨论】:

    • 非常感谢您的帮助!这解决了问题。我不确定cluster_louvain 是否自动阈值边缘列表以仅使用更高加权边缘(即更高相关性)派生社区。但是考虑到这一点,我当然意识到cluster_louvain 会使用所有边缘进行社区检测,因为它不会自动知道边缘表示相关性(或任何其他指标),其中只有更高的值才有意义;这是我们作为研究人员在相关/输入矩阵中指定的。再次感谢您的有益解释和解决方案。
    • 我在运行此分析时询问了后续调查here - 它不直接相关,但它可能对任何研究如何正确导入相关矩阵的人有所帮助R 代表“cluster_louvain”。再次非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    • 2014-08-17
    • 2014-12-10
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    相关资源
    最近更新 更多