python批量计算cosine distance

我们在做推荐或者信息检索任务时经常需要比较项目嵌入和项目嵌入之间或者用户嵌入和项目嵌入之间的相似度,然后进行推荐。余弦相似度的计算公式如下:

余弦相似度cosine similarity和余弦距离cosine distance是相似度度量中常用的两个指标,我们可以用sklearn.metrics.pairwise下的cosine_similarity和paired_distances函数分别计算两个向量之间的余弦相似度和余弦距离,效果如下:

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

x = np.array([[0.26304135, 0.91725843, 0.61099966, 0.40816231, 0.93606288, 0.52462691]])
print(x)
y = np.array([[0.03756129, 0.50223667, 0.66529424, 0.57392135, 0.20479857, 0.27286363]])
print(y)
# 余弦相似度
simi = cosine_similarity(x, y)
print('cosine similarity:', simi)
# 余弦距离 = 1 - 余弦相似度
dist = paired_distances(x, y, metric='cosine')
print('cosine distance:', dist)

这里可以看到,余弦相似度 + 余弦距离 = 1。

 我们试一下用cosine_similarity和paired_distances函数分别计算多个向量与一个向量的余弦相似度和余弦距离,效果如下:

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

x = np.array([[0.26304135, 0.91725843, 0.61099966, 0.40816231, 0.93606288, 0.52462691], [0.26304135, 0.91725843, 0.61099966, 0.40816231, 0.93606288, 0.52462691]])
print(x)
y = np.array([[0.03756129, 0.50223667, 0.66529424, 0.57392135, 0.20479857, 0.27286363]])
print(y)
# 余弦相似度
simi = cosine_similarity(x, y)
print('cosine similarity:', simi)
# 余弦距离 = 1 - 余弦相似度
dist = paired_distances(x, y, metric='cosine')
print('cosine distance:', dist)

可以看到这里余弦相似度可以正常计算,但在计算余弦距离时报错。 

现在我们自己写程序批量计算多个向量与多个向量之间的余弦相似度和余弦距离,效果如下:

def distCosine(x, y):
    """
    :param x: m x k array
    :param y: n x k array
    :return: m x n array
    """
    xx = np.sum(x ** 2, axis=1) ** 0.5
    x = x / xx[:, np.newaxis]
    yy = np.sum(y ** 2, axis=1) ** 0.5
    y = y / yy[:, np.newaxis]
    dist = 1 - np.dot(x, y.transpose())  # 1 - 余弦距离
    return dist


x = np.random.rand(10, 6)
print(x)
y = np.random.rand(5, 6)
print(y)
dist = distCosine(x, y)
print(dist)

 我们测试一下写的程序计算的余弦距离是否和paired_distances函数计算的一致,以第一行为例:

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

# x
x1 = np.array([[0.80752941, 0.53856979, 0.23620606, 0.19540647, 0.7920776, 0.00918439]])
x10 = np.array([[0.84784528, 0.69746047, 0.91245773, 0.27064697, 0.3165476, 0.85158265]])
# y
y1 = np.array([[0.21375023, 0.13551058, 0.93240456, 0.50134001, 0.8600716, 0.19956772]])
y5 = np.array([[0.60785337, 0.73592292, 0.57753456, 0.07512202, 0.82074906, 0.57231335]])

# 余弦距离 = 1 - 余弦相似度
dist1_1 = paired_distances(x1, y1, metric='cosine')
print('cosine distance:', dist1_1)
dist10_5 = paired_distances(x10, y5, metric='cosine')
print('cosine distance:', dist10_5)

可以看出计算结果是正确的,请放心使用。 

<think>好的,我现在需要帮助用户了解如何在大型语言模型(LLM)中实现向量距离计算。首先,我得回忆一下LLM的基本结构,特别是向量表示的部分。大型语言模型如GPT或者BERT,通常会将输入的词或子词转换为高维向量,这些向量在模型的不同层中被处理。用户的问题是关于如何计算这些向量之间的距离,所以可能需要涉及到嵌入层或隐藏层的输出。 首先,我应该解释向量距离计算的常见方法,比如余弦相似度和欧氏距离。这些方法在机器学习中很常见,但在LLM中的具体应用可能需要考虑模型的结构。例如,在自注意力机制中,查询、键和向量的点积计算可能涉及到余弦相似度的概念,不过通常还会除以维度的平方根来缩放。 接下来,我需要分步骤说明如何在LLM中实现这些计算。可能需要提到嵌入层的使用,比如获取词嵌入向量,然后应用不同的距离公式。同时,还要注意模型中的具体层,比如隐藏层的输出,或者自注意力机制中的中间结果。 然后,考虑用户可能的实际应用场景,比如语义相似度计算或聚类,这时候需要给出具体的例子,比如使用PyTorch或TensorFlow代码片段来展示如何提取向量并进行计算。例如,用BERT模型获取句子的嵌入,然后计算两个句子向量之间的余弦相似度。 还需要注意技术细节,比如向量的归一化处理,这在计算余弦相似度时很重要,因为余弦相似度本质上是向量方向上的比较,与大小无关。此外,可能还要提到高效计算的方法,比如批量处理,这在处理大量数据时很重要。 用户可能对为什么使用这些距离方法感兴趣,所以需要解释余弦相似度适合衡量方向相似性,而欧氏距离反映绝对距离。同时,要指出在LLM中,这些距离计算的应用场景,比如检索增强生成(RAG)中的语义搜索,或者聚类分析。 另外,要确保回答中引用了提供的参考资料。比如,引用[3]中提到的模型参数结构,可能和向量维度有关,可以联系起来说明隐藏层维度d_model的影响。引用[1]提到的NLP模型预处理,可能涉及到文本到向量的转换步骤,这也是计算距离的前提。 最后,生成相关的问题,帮助用户进一步探索,比如不同距离指标的优缺点,如何处理高维向量的距离计算,或者在具体任务中的应用案例。这些问题需要自然衔接,覆盖用户可能感兴趣的扩展方向。 需要检查是否所有数学表达式都正确使用了$...$和$$...$$格式,例如余弦相似度公式和欧氏距离公式是否正确排版。同时确保代码示例正确,比如使用PyTorch的BERT模型提取嵌入,并计算距离。 总结下来,回答的结构应该是:先介绍向量距离的概念,再分步骤说明实现方法,给出代码示例,讨论应用场景,最后提出相关问题。同时,确保引用正确,技术细节准确,语言清晰易懂。</think>在大型语言模型(LLM)中,向量距离计算通常用于衡量语义相似度或特征空间中的关系。以下是实现方法的核心步骤和技术细节: --- ### 一、向量距离计算基础 LLM中的向量距离计算主要基于以下两类方法: 1. **余弦相似度**:衡量向量方向的一致性 $$ \text{cos\_sim}(A, B) = \frac{A \cdot B}{\|A\| \|B\|} $$ 2. **欧氏距离**:衡量向量空间的绝对距离 $$ \text{euclidean}(A, B) = \sqrt{\sum_{i=1}^{n}(A_i - B_i)^2} $$ --- ### 二、LLM中的实现步骤 1. **获取向量表示** - **嵌入层输出**:提取词/子词级别的嵌入向量 - **隐藏层输出**:获取经过Transformer块处理后的上下文感知表示 - **特殊标记表示**:如`[CLS]`标记的聚合语义(BERT类模型) 2. **计算流程示例(以PyTorch为例)**: ```python import torch from transformers import AutoModel, AutoTokenizer # 加载模型和分词器 model = AutoModel.from_pretrained("bert-base-uncased") tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") # 输入处理 texts = ["cat sits on mat", "dog lies on rug"] inputs = tokenizer(texts, padding=True, return_tensors="pt") # 获取向量(使用[CLS]标记) with torch.no_grad(): outputs = model(**inputs) embeddings = outputs.last_hidden_state[:, 0, :] # 形状: (batch_size, hidden_size) # 计算余弦相似度 cos_sim = torch.nn.CosineSimilarity(dim=1) similarity = cos_sim(embeddings[0], embeddings[1]) print(f"Cosine similarity: {similarity.item():.4f}") # 计算欧氏距离 euclidean_dist = torch.cdist(embeddings, embeddings, p=2) print(f"Euclidean distance: {euclidean_dist[0][1].item():.4f}") ``` --- ### 三、关键技术细节 1. **向量归一化**:计算余弦相似度前建议对向量进行L2归一化 $$ A_{\text{norm}} = \frac{A}{\|A\|_2} $$ 2. **注意力机制中的距离**:自注意力计算时使用的缩放点积可视为余弦相似度的变体 $$ \text{Attention}(Q,K,V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V $$ 3. **高效计算**:使用矩阵运算实现批量处理,避免循环 --- ### 四、典型应用场景 1. 语义搜索(RAG架构中的检索阶段) 2. 文本聚类/分类 3. 相似问题匹配(问答系统) 4. 模型解释性分析(通过向量空间分布理解模型行为) ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值