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

如何计算指定维度numpy数组的余弦相似度并构建相似矩阵

解决样本间字段组合相似度计算的方案

嘿,我来帮你搞定这个相似度计算的需求!咱们先把需求再明确一遍:你有两个向量数组,arr1是100个样本(每个含4个200维字段向量),arr2是150个样本(每个含6个200维字段向量)。最终要得到15000×24的结果——其中15000是100×150的样本对总数,24是4×6的字段组合总数,每个位置对应一组样本对的字段相似度。

核心思路

我们可以利用numpy的广播机制来高效计算所有样本对、所有字段组合的相似度,不用写嵌套循环(既慢又麻烦)。这里以最常用的余弦相似度为例,你也可以替换成其他相似度(比如欧氏距离归一化后的值)。

方法一:纯Numpy实现(无依赖第三方库)

import numpy as np

# 模拟你的输入数组(实际使用时替换成你自己的数组)
arr1 = np.random.rand(100, 4, 200)  # (样本数1, 字段数1, 向量维度)
arr2 = np.random.rand(150, 6, 200)  # (样本数2, 字段数2, 向量维度)

# 步骤1:调整形状,适配广播计算
arr1_expanded = arr1[:, :, np.newaxis, :]  # 新增维度对应arr2的样本,shape变为(100,4,1,200)
arr2_expanded = arr2[np.newaxis, :, :, :]  # 新增维度对应arr1的样本,shape变为(1,150,6,200)

# 步骤2:计算余弦相似度
# 分子:向量点积
dot_product = np.sum(arr1_expanded * arr2_expanded, axis=-1)  # shape: (100,150,4,6)
# 分母:两个向量的L2范数乘积
norm1 = np.linalg.norm(arr1_expanded, axis=-1)  # shape: (100,4,1,1)
norm2 = np.linalg.norm(arr2_expanded, axis=-1)  # shape: (1,150,6,1)
# 避免除以0,加一个极小值epsilon
epsilon = 1e-8
cos_sim = dot_product / (norm1 * norm2 + epsilon)  # shape: (100,150,4,6)

# 步骤3:调整为目标形状(15000,24)
result = cos_sim.reshape(-1, 4*6)
print(result.shape)  # 输出 (15000, 24)

方法二:用Scikit-learn的cosine_similarity(更简洁)

如果你的环境里有sklearn,也可以用它的cosine_similarity函数,代码会更简洁:

from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

arr1 = np.random.rand(100, 4, 200)
arr2 = np.random.rand(150, 6, 200)

# 步骤1:提取所有字段向量
arr1_fields = arr1.reshape(-1, 200)  # shape: (400, 200) → 100样本×4字段
arr2_fields = arr2.reshape(-1, 200)  # shape: (900, 200) → 150样本×6字段

# 步骤2:计算所有字段对的相似度
field_sim = cosine_similarity(arr1_fields, arr2_fields)  # shape: (400,900)

# 步骤3:重组为目标形状
# 先拆分为(100,4,150,6),再调整维度顺序为(100,150,4,6),最后展平为(15000,24)
result = field_sim.reshape(100,4,150,6).transpose(0,2,1,3).reshape(-1,24)
print(result.shape)  # 输出 (15000,24)

关键细节说明

  • 两种方法的计算结果完全一致,选哪种取决于你的环境和习惯:纯numpy方法更轻量,sklearn方法更简洁。
  • 如果需要替换成其他相似度(比如欧氏距离),只需要修改相似度计算的部分即可。比如欧氏距离可以用np.linalg.norm(arr1_expanded - arr2_expanded, axis=-1),再根据需求做归一化处理。
  • 加入epsilon是为了避免某个向量全为0时,范数为0导致的除以0错误,这是数值计算中的常规操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:23:45