使用 iGraph 创建图形并计算相似性度量

Creating graph with iGraph and computing similarity metric

我正在尝试使用如下所示的 csv 文件在 igraph 中创建图表:

ID    Element1 Element2 Element3 Element4
12346  A        12       56       2
13007  Y        16       66       2
...    ...      ...      ...      ...

ID 列由唯一的 4 位标识符填充,而元素列由重复的数字(或字母,在 Element1 中)填充。我的目标是计算所有 ID 的成对 Jaccard 相似度,它利用 ID 节点之间共享的元素。输出应该是一个 NxN 矩阵。

我一直在尝试使用 graph_from_data_frame 功能在 igraph 上创建图形,但这会从前两列创建节点,并将其余列作为边属性放置在它创建的节点之间的关系中。关于创建允许我计算 ID 节点之间的 Jaccard 的图形的最佳方法的任何想法?

供参考,目标是利用igraph的这个特性:

 similarity(graph, vids = V(graph), mode = c("all", "out", "in", "total"),
 loops = FALSE, method = c("jaccard", "dice", "invlogweighted"))

其中 graph 是我创建的图表,vids ID 节点。

如果您的主要目标是计算 ID 之间的 Jaccard 相似度,则无需先创建图表即可完成。 Jaccard 相似度定义为交集除以并集 J(A,B) = |A⋂B| / |A⋃B|,等价于|A⋂B| / ( |A| + |B| - |A⋂B| )。所以你可以这样计算:

## Example dataset
df = read.table(text = "ID    Element1 Element2 Element3 Element4
  12346  A        12       56       2
  13007  Y        16       66       2
  14008  B        14       56       3
  15078  A        15       56       4
  16000  Y        20       66       3"
,h=T,stringsAsFactors=F)

n = nrow(df)
m = matrix(0,n,n,dimnames=list(df[,1],df[,1]))
for(i in 1:n){
    for(j in i:n){
        m[i,j] = length(intersect(df[i,-1],df[j,-1]))/(2*(n-1)-length(intersect(df[i,-1],df[j,-1])))}}
## Making the matrix symmetrical
m[lower.tri(m)] = t(m)[lower.tri(m)]
> m
          12346     13007     14008     15078     16000
12346 1.0000000 0.1428571 0.1428571 0.3333333 0.0000000
13007 0.1428571 1.0000000 0.0000000 0.0000000 0.3333333
14008 0.1428571 0.0000000 1.0000000 0.1428571 0.1428571
15078 0.3333333 0.0000000 0.1428571 1.0000000 0.0000000
16000 0.0000000 0.3333333 0.1428571 0.0000000 1.0000000