本文详细介绍了如何使用 NumPy 实现两个向量之间的余弦相似度计算,帮助理解向量相似度在推荐系统、文本处理等领域的应用。

1. 余弦相似度定义

余弦相似度是衡量两个向量在高维空间中夹角大小的指标,其公式为:

cos(θ)=A⋅B∥A∥∥B∥ {cos(\theta)} = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} cos(θ)=A∥∥BAB
其中:

  • A⋅BA⋅BAB 表示向量的点积,即 A1B1+A2B2+...+AnBnA_1B_1+A_2B_2+...+A_nB_nA1B1+A2B2+...+AnBn
  • ∥A∥∥A∥A∥B∥∥B∥B 是向量的 L2 范数(即欧几里得长度)

如果 A=[1,2,3]A=[1,2,3]A=[1,2,3] B=[2,3,4]B=[2,3,4]B=[2,3,4] 则有:

  • A⋅B=1∗2+2∗3+3∗4=20A⋅B =1*2+2*3+3*4=20AB=12+23+34=20
  • ∥A∥=12+22+32∥A∥=\sqrt{1^2+2^2+3^2}A=12+22+32
  • ∥B∥=22+32+42∥B∥ = \sqrt{2^2+3^2+4^2}B=22+32+42

余弦相似度的取值范围为 [-1, 1]:

  • 1 表示两个向量方向完全相同。
  • 0 表示两个向量正交(没有相关性)。
  • −1 表示两个向量方向完全相反。

2. Python Numpy实现

代码实现:

import numpy as np
def cosine_similarity(vec1, vec2):
    # 计算点积
    dot_product = np.dot(vec1, vec2)
    norm_a = np.linalg.norm(vec1)
    norm_b = np.linalg.norm(vec2)
    
    # 防止分母为0
    if norm_a == 0 or norm_b == 0:
        return 0.0
    
    # 余弦相似度
    return dot_product/(norm_a * norm_b)

3. 扩展:矩阵形式计算余弦相似度

代码实现:

def batch_cosine_similarity(matrix_a, matrix_b):
    """
    计算两个矩阵中对应向量之间的余弦相似度
    :param matrix_a: 矩阵 A (m x d)
    :param matrix_b: 矩阵 B (n x d)
    :return: 相似度矩阵 (m x n)
    """
    norm_a = np.linalg.norm(matrix_a, axis=1, keepdims=True)
    norm_b = np.linalg.norm(matrix_b, axis=1, keepdims=True)
    similarity_matrix = np.dot(matrix_a, matrix_b.T) / (norm_a * norm_b.T)
    return similarity_matrix

实际应用:

  • 在文本分析中,如果两个文本的余弦相似度接近 1,说明这两篇文本内容相似;而如果相似度接近 0,则说明文本之间没有明显的联系。
  • 在推荐系统中,用户的行为向量与商品的描述向量的余弦相似度可以帮助计算推荐结果。
  • 在图像处理领域,计算图像特征向量之间的余弦相似度也可以用于检索相似图像。
  • 余弦相似度也可以用于信号分析,表示两个信号的波形相似性。例如,某些电子设备的状态诊断可能基于当前信号与历史信号的余弦相似度。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐