You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将材料共现频率表转换为矩阵用于聚类分析的技术问询

材料共现矩阵构建与聚类分析实现方案

问题背景

我手头有一份记录材料成对共现频率的数据集,其中V1和V2代表成对出现的材料编号,N是它们的共同出现次数。需要将这份数据转换为696×696的矩阵(行/列对应1-696的材料编号,存在的组合填N,不存在的填0),之后用hclust的centroid方法完成聚类分析。

原始数据集

> dput(ans)
structure(list(V1 = c(2L, 7L, 7L, 7L, 7L, 7L, 9L, 9L, 9L, 10L, 10L, 11L, 12L, 12L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 20L, 20L, 21L, 25L, 29L, 29L, 29L, 33L, 35L, 38L, 42L, 46L, 46L, 46L, 46L, 46L, 46L, 46L, 46L, 46L, 46L, 46L, 46L, 47L, 47L, 48L, 52L, 52L, 52L, 52L, 52L, 56L, 56L, 56L, 56L, 56L, 56L, 56L, 57L, 57L, 57L, 57L, 57L, 57L, 58L, 58L, 58L, 58L, 58L, 59L, 59L, 59L, 59L, 60L, 60L, 60L, 61L, 61L, 62L, 65L, 65L, 65L, 65L, 67L, 67L, 67L, 68L, 70L, 70L, 71L, 73L, 73L, 74L), 
               V2 = c(3L, 8L, 20L, 21L, 22L, 78L, 10L, 11L, 12L, 11L, 12L, 12L, 38L, 39L, 14L, 15L, 16L, 17L, 18L, 29L, 64L, 15L, 16L, 17L, 18L, 16L, 17L, 18L, 17L, 18L, 29L, 30L, 18L, 29L, 30L, 21L, 22L, 22L, 26L, 30L, 47L, 64L, 34L, 36L, 39L, 43L, 47L, 48L, 49L, 52L, 65L, 67L, 70L, 71L, 72L, 73L, 74L, 75L, 48L, 49L, 49L, 65L, 67L, 73L, 74L, 75L, 57L, 58L, 59L, 60L, 61L, 62L, 63L, 58L, 59L, 60L, 61L, 62L, 63L, 59L, 60L, 61L, 62L, 63L, 60L, 61L, 62L, 63L, 61L, 62L, 63L, 62L, 63L, 63L, 67L, 73L, 74L, 75L, 73L, 74L, 75L, 69L, 71L, 72L, 72L, 74L, 75L, 75L ), 
               N = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L)), 
          row.names = c(NA, -108L), class = c("data.table", "data.frame"))

实现步骤

1. 加载依赖包

先加载处理数据和聚类所需的工具包:

library(data.table)
library(stats)

2. 构建696×696的共现矩阵

先初始化一个全0的矩阵,再将数据集中的共现频率填充到对应位置:

# 初始化全0矩阵,行/列名设为1-696
co_occur_matrix <- matrix(0, nrow = 696, ncol = 696, 
                          dimnames = list(as.character(1:696), as.character(1:696)))

# 遍历数据集,填充对应位置的N值
for (i in 1:nrow(ans)) {
  v1 <- as.character(ans$V1[i])
  v2 <- as.character(ans$V2[i])
  co_occur_matrix[v1, v2] <- ans$N[i]
  # 如果共现关系是无向的(A-B和B-A属于同一种共现),可以打开下面的注释让矩阵对称
  # co_occur_matrix[v2, v1] <- ans$N[i]
}

3. 基于共现矩阵进行聚类分析

hclust需要输入距离矩阵,所以先将共现矩阵转换为相似度矩阵,再转为距离矩阵(这里用1 - 标准化共现值构建距离,你也可以根据需求调整转换逻辑):

# 标准化共现矩阵(可选,避免高频率对聚类的过度影响)
norm_matrix <- co_occur_matrix / max(co_occur_matrix[co_occur_matrix != 0])

# 转换为距离矩阵:相似度越高,距离越小
dist_matrix <- as.dist(1 - norm_matrix)

# 使用centroid方法进行聚类
hc <- hclust(dist_matrix, method = "centroid")

# 绘制聚类树状图(对应你提到的预期输出示例)
plot(hc, main = "材料共现频率聚类树状图", xlab = "材料编号", ylab = "距离", cex = 0.6)

补充说明

  • 如果你的共现关系是无向的(即V1-V2和V2-V1代表同一种共现情况),记得打开矩阵对称填充的注释代码,这样矩阵会更符合实际业务逻辑。
  • 标准化步骤是可选的:如果你希望原始共现频率直接影响聚类结果,可以跳过标准化,直接用as.dist(max(co_occur_matrix) - co_occur_matrix)构建距离矩阵。

内容的提问来源于stack exchange,提问作者M.A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:18:38