【问题标题】:Structuring data for community detection in R's igraph在 R 的 igraph 中构建用于社区检测的数据
【发布时间】:2015-08-04 19:22:03
【问题描述】:

我是 igraph 和社交网络分析的新手,但不是 R。

我正在努力正确构建用于社区检测的数据集,但已成功使用 iGraph 生成共现矩阵 as directed [here]。接下来我想做的是在同一个数据集上使用社区检测算法来创建一个显示集群的图形as is done in the answer here

如何做到这一点的示例代码如下:

df1 <- graph.famous("Zachary")
df2 <- walktrap.community(df1) #any algorithm
plot.communities(df2, df)

我一直在网上四处寻找 Zachary 数据集的结构,以便正确建模我的数据,但我很难通过技术文档找到自己的方法。

我的数据目前是长格式的,这样:

id         interest    comments
1             Comedy          2
1  Music: Electronic         11
1       Video Gaming         10
1         Music: Pop          1
1      Entertainment          1
1       Video Gaming          4
2       Video Gaming         45
2      Entertainment         26
2         Music: Pop          1
2            Comedy         14
3      Video Gaming         10
3     Entertainment          4
3            Comedy          8
4      Video Gaming          9
4 Music: Electronic          1
4        Music: Pop          2
5        Music: Pop          2
5     Entertainment          1
5      Video Gaming          1
6      Video Gaming         12

我试图在我正在研究的人群中找到重叠兴趣的集群,所以ID 是一个人,interests 是这个人的兴趣,comments 是他们有多少次的索引表现出兴趣。这有帮助吗?

我尝试在此数据集上运行社区算法(例如df2 &lt;- walktrap.community(df)),但这似乎无法正常工作。关于这个 n00b 做错了什么的想法?

【问题讨论】:

  • 图由节点和边组成。您的数据集中的哪些内容与节点相关,您如何知道哪些节点已连接?对于 Zarchary 数据,它可以用邻接矩阵 (get.adjacency(df1)) 或边列表 (get.edgelist(df1)) 表示
  • @MrFlick 节点是“兴趣”列中的值——即喜剧、游戏等。我试图在我正在研究的人群中找到重叠兴趣的集群,所以 ID 是一个人,兴趣是这个人的兴趣,而“cmets”是他们表现出兴趣的次数的指数。这有帮助吗?
  • 这是有道理的,但仍然不能很好地转化为图形语言。因此,您希望每个兴趣都成为一个节点,然后如果用户共享两个兴趣,您希望节点之间有一条边?我不确定你会对 cme​​ts 列做什么,因为它似乎不太适合作为节点或边权重。我仍然很难看到这些数据将如何以图表形式表示。
  • @MrFlick 我可能没有准确地沟通......我的最终目标是找到具有不同兴趣组合的独特人群。因此,可能会有一群喜欢“游戏和娱乐”的人,这可能与喜欢“游戏和喜剧”的人相关(但又不同)。 “cmets”旨在提供相对的兴趣权重(并用于共现分析),但我真的只是想通过建议的聚类方法来混淆我的方式......
  • @roody 如果您觉得我的回答对您有帮助或回答了您的问题,请点赞/接受。否则,请随时发表评论以获得澄清。

标签: r igraph


【解决方案1】:

图表不允许您对个体进行聚类,而只能找出哪些变量是相关的。尽管如此,如果你想从你的数据中构建一个图表,这就是你必须做的。 (请注意,我已将您的示例数据保存为 .csv 文件并将其上传到保管箱,以制作一个易于重现的示例)。

library(repmis)
library(igraph)

test=source_data("https://www.dropbox.com/s/bochkedd4o3gzvq/so.csv?dl=0")

首先,您想要创建一个矩阵,其中每个个体一行,每个特征一列:

matrix=matrix    
rownames(matrix)=unique(test[,1])
colnames(matrix)=unique(test[,2])

并且单元格的值对应于兴趣的强度:

for (i in 1:nrow(matrix)){
    temp=test[test[,1]==i,][,2:3]
    for (j in 1:ncol(matrix)){
    matrix[i,j]=sum(temp[temp[,1]==colnames(matrix)[j],2]) # sum is used because of duplicates
    }
}

你得到的是:

> matrix
  comedy electronic gaming pop ent
1      2         11     14   1   1
2     14          0     45   1  26
3      8          0     10   0   4
4      0          1      9   2   0
5      0          0      1   2   1
6      0          0     12   0   0

然后,您可以从中创建一个邻接矩阵:

x=t(matrix)%*%matrix

你得到的是:

> x
           comedy electronic gaming pop  ent
comedy        264         22    738  16  398
electronic     22        122    163  13   11
gaming        738        163   2547  79 1225
pop            16         13     79  10   29
ent           398         11   1225  29  694

从中构建图表很容易:

g=graph.adjacency(x,weighted=T,mode="undirected",diag=FALSE)
g=simplify(g)

您可以将任何社区检测算法应用于对象g,例如:

spinglass.community(g,weight=E(g)$weight)

如果您想对个体而不是变量进行聚类,我会研究 PCA 和层次聚类(例如,参见 FactoMineR 包中出色的 HCPC 函数)。在这种情况下,您将使用上面的对象matrix(无需计算邻接矩阵)。

【讨论】:

  • 你能解释一下矩阵 x 中的数字代表什么吗?请解释一下叉积的结果。
  • @user20650 请查看graph.adjacency函数的文档:igraph.org/r/doc/graph.adjacency.html
  • 感谢您的回复。为了扩展我的问题,例如,264xcomedy / comedy 元素中的264 有什么关系 - 我看不出这与原始数据有何关系(我知道我可能很慢)ps。我确实知道您正在尝试形成加权邻接矩阵。
  • @user20650 这些值本身没有任何物理意义,它们只是有意义的权重,因为它们允许比较,而且矩阵是对称的,我们不关心对角线。这些值表示变量之间共现的强度。例如,electronicgamingelectroniccomedy (22) 更频繁地共同出现 (163)。创建加权图时,这些数字将决定边缘的“厚度”。
  • @user20650 请注意,我更正了一个错字:x=t(matrix)%*%matrix 而不是 x=t(x)%*%x
猜你喜欢
  • 1970-01-01
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
  • 2014-12-10
  • 2014-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多