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

在R中计算仅统计共享列的二进制数据相似度矩阵

高效计算二进制数据行间相似度(排除0值贡献)

核心需求

计算data.frame中每行(代表单个项目)的相似度,仅基于**同时为1的列(组)**统计,0值(非组内成员)不参与相似度计算——即只考虑两行都属于的组,忽略双方都不属于的组。

高效实现方案

方案1:纯矩阵运算(无依赖)

利用二进制矩阵的交叉乘积快速计算两两交集,再结合行和计算并集,最终得到符合需求的Jaccard相似度(交集/并集):

# 将data.frame转为矩阵
mat <- as.matrix(your_dataframe)

# 计算两两行的交集(同时为1的列数)
intersection <- mat %*% t(mat)

# 计算每行的1的数量(项目所属组的总数)
row_counts <- rowSums(mat)

# 计算两两行的并集(至少一方为1的列数)
union <- outer(row_counts, row_counts, "+") - intersection

# 生成相似度矩阵,对角线设为1(自身相似度)
similarity_mat <- intersection / union
diag(similarity_mat) <- 1

矩阵运算基于R基础包实现,底层是优化过的线性代数逻辑,处理大数据集时比循环实现快数个数量级。

方案2:用proxy包快速实现

proxy包专门优化了距离/相似度计算,内置Jaccard方法,代码更简洁:

library(proxy)

# 转矩阵(data.frame也可直接传入)
mat <- as.matrix(your_dataframe)

# 将Jaccard距离转为相似度(1-距离)
similarity_mat <- 1 - dist(mat, method = "Jaccard")
similarity_mat <- as.matrix(similarity_mat)

底层实现经过性能优化,适合快速开发场景。

示例验证

假设输入数据:

df <- data.frame(
  GroupA = c(1,1,0,0),
  GroupB = c(1,0,1,0),
  GroupC = c(0,1,1,1),
  GroupD = c(0,0,0,1)
)

运行上述代码后得到的相似度矩阵:

[,1]      [,2]      [,3]      [,4]
[1,] 1.0000000 0.3333333 0.2500000 0.0000000
[2,] 0.3333333 1.0000000 0.5000000 0.2500000
[3,] 0.2500000 0.5000000 1.0000000 0.3333333
[4,] 0.0000000 0.2500000 0.3333333 1.0000000

完全符合基于共享组的相似度需求。

额外说明

  • 如果数据不是严格二进制(存在大于1的值),先转二进制:mat <- (mat > 0) * 1
  • 若仅需要共享组的数量作为相似度,直接使用intersection矩阵即可,无需计算并集。

内容的提问来源于stack exchange,提问作者mikeblazanin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:17:21