将材料共现频率表转换为矩阵用于聚类分析的技术问询
材料共现矩阵构建与聚类分析实现方案
问题背景
我手头有一份记录材料成对共现频率的数据集,其中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
相关产品推荐
相关产品推荐

