AI 术语通俗词典:余弦相似度
余弦相似度是线性代数、数据分析、机器学习、自然语言处理和人工智能中非常常见的一个术语。它用来描述两个向量在方向上有多接近。换句话说,余弦相似度关注的不是两个向量“离得有多远”,而是它们“指向是否相近”。
如果说向量回答的是“一个对象在多个维度上的数值表示”,那么余弦相似度回答的就是“两个对象在整体方向上有多相似”。因此,余弦相似度常用于文本相似度、词向量比较、推荐系统、向量检索和语义匹配,在人工智能中具有非常重要的实际意义。
一、基本概念:什么是余弦相似度
余弦相似度(Cosine Similarity)是一种衡量两个向量方向相似程度的指标。它的核心思想来自向量夹角:如果两个向量方向很接近,那么它们的余弦值就大;如果方向差异很大,那么余弦值就小。
设有两个向量:
那么它们的余弦相似度公式可写为:
其中:
• a · b 表示向量 a 与向量 b 的点积(Dot Product)
• ‖a‖ 表示向量 a 的范数(Norm),也就是它的长度
• ‖b‖ 表示向量 b 的范数
• θ 表示两个向量之间的夹角
若把点积和范数展开,则也可以写成:
这个公式的含义可以分成三步理解:
(1)先计算两个向量在对应维度上的乘积并求和,也就是点积;
(2)再分别计算两个向量的长度;
(3)最后用点积除以两个长度的乘积,得到一个介于 -1 到 1 之间的数。
从通俗角度看,余弦相似度可以理解为:先忽略两个向量本身有多长,只看它们是不是朝着差不多的方向。
例如,在二维平面中:
若两个向量方向完全相同,夹角为 0°,那么余弦相似度为 1;
若两个向量互相垂直,夹角为 90°,那么余弦相似度为 0;
若两个向量方向相反,夹角为 180°,那么余弦相似度为 -1。
也就是说:
值越接近 1,说明方向越接近;
值越接近 0,说明方向差异越大;
值越接近 -1,说明方向越相反。
在很多人工智能任务中,向量分量通常非负,因此余弦相似度常常落在 0 到 1 之间。此时就更容易直观理解为“越接近 1 越相似”。
例如,若两个向量为:
虽然 b 比 a 更长,但它们方向完全一致,所以余弦相似度为 1。
这说明余弦相似度关心的是“方向相似”,而不是“大小相同”。
二、余弦相似度的重要性与常见应用场景
1、余弦相似度的重要性
余弦相似度之所以重要,是因为在很多实际任务中,我们更关心两个对象“模式是否相似”,而不是“绝对数值是否相近”。
首先,余弦相似度可以减弱向量长度差异带来的影响。
有些对象虽然总量不同,但结构模式很相似。例如,两篇文章字数不同,但主题相近;两个用户点击总量不同,但兴趣方向类似。若直接比较数值大小,可能会被总量干扰;而余弦相似度更强调方向,因此能更好地抓住“模式相似”。
其次,余弦相似度非常适合高维向量比较。
在自然语言处理、推荐系统和向量检索中,对象常常被表示为高维向量。余弦相似度提供了一种简洁而有效的相似度度量方式。
再次,余弦相似度建立在点积和范数之上,几何意义明确。
它并不是一个纯经验指标,而是有清晰的向量夹角解释,因此既容易理解,也便于与点积、范数、向量空间等概念联系起来。
可以概括地说:欧氏距离强调“相隔多远”;余弦相似度强调“方向有多像”。
2、常见应用场景
(1)在自然语言处理中,余弦相似度常用于比较词向量或句向量
在自然语言处理(Natural Language Processing,NLP)中,词语、句子或整段文本常常会被表示成向量。
此时,可以通过余弦相似度来判断它们在语义空间中是否接近。例如:
“老师”和“教师”的向量余弦相似度通常较高;
“老师”和“汽车”的余弦相似度通常较低。
(2)在文本检索中,余弦相似度常用于判断查询与文档是否匹配
当用户输入查询词后,系统可以把查询和候选文档都表示成向量,再用余弦相似度判断谁与查询更接近。
相似度越高,通常说明文档越可能与用户需求相关。
(3)在推荐系统中,余弦相似度常用于比较用户或物品的兴趣模式
若两个用户的兴趣向量方向相近,即使一个用户更活跃、点击更多,另一个用户更少,系统仍可能认为他们兴趣相似。
这时,余弦相似度就比单纯看总量更合适。
(4)在向量数据库与语义搜索中,余弦相似度非常常见
现代检索系统常把文本、图片、音频等内容先转换为向量,再在向量空间中查找最相近的内容。
余弦相似度是这类向量检索中最常见的度量方式之一。
(5)在聚类与分类中,余弦相似度也可用于衡量样本接近程度
某些聚类或分类方法并不直接用欧氏距离,而是更关注方向上的相似性。
在这类情况下,余弦相似度也很有价值。
可以概括地说:向量说明“对象如何被数字化表示”;余弦相似度说明“这些表示在方向上有多接近”。
三、余弦相似度与欧氏距离的区别
余弦相似度很容易与欧氏距离(Euclidean Distance)一起出现,因此有必要顺便区分一下。
1、余弦相似度关注方向,欧氏距离关注距离
欧氏距离回答的是“两个点相隔多远”;
余弦相似度回答的是“两个向量方向是否相近”。例如:
(1, 1) 和 (2, 2) 的欧氏距离不为 0;
但它们的余弦相似度为 1,因为方向完全相同。
2、余弦相似度对长度变化不太敏感
若两个向量只是整体倍数关系,那么它们方向不变,余弦相似度通常保持不变。这使余弦相似度特别适合比较“模式是否一致”。
3、欧氏距离更受数值尺度影响
如果一个向量整体数值很大,那么欧氏距离很容易被这种大小差异拉开。
而余弦相似度由于做了长度归一化,更能突出结构方向。因此:
若你关心“大小差异”,欧氏距离更自然;
若你关心“方向模式”,余弦相似度更自然。
四、使用余弦相似度时需要注意的问题
余弦相似度虽然非常常用,但在理解和使用时也要注意几个问题。
1、余弦相似度强调方向,不强调绝对大小
这既是它的优点,也是它的限制。
若两个对象在方向上相似,但总量差异非常大,余弦相似度仍可能很高。因此,在某些任务中,单独使用余弦相似度可能会忽略掉“规模差异”。
2、零向量无法计算余弦相似度
如果某个向量长度为 0,那么分母中的范数为 0,公式就无法计算。
因此,在实际应用中,需要先检查是否存在零向量。
3、余弦相似度高不一定就表示语义完全相同
在文本和语义任务中,余弦相似度只是向量空间中的一种接近程度。
它能反映“表示相近”,但并不自动等于“意义完全一致”。
4、不同向量表示方式会影响余弦相似度结果
同一个词语、句子或用户对象,若采用不同的向量表示方法,计算出的余弦相似度也可能不同。
因此,余弦相似度本身只是度量工具,结果质量很大程度上取决于向量表示本身。
5、余弦相似度与点积不能简单等同
点积和余弦相似度关系密切,但点积会受到向量长度影响,而余弦相似度已经对长度做了归一化。
因此,点积更像“方向 + 大小”的混合结果,余弦相似度更像“纯方向相似性”的结果。
五、Python 示例
下面给出两个简单示例,用来说明余弦相似度的基本计算过程,以及它如何帮助我们比较两个向量在方向上的接近程度。
示例 1:计算两个向量的余弦相似度
import math # 两个向量a = [1, 1]b = [2, 2] # 计算点积dot_product = 0for i in range(len(a)): dot_product += a[i] * b[i] # 计算向量长度norm_a = math.sqrt(sum(x ** 2 for x in a))norm_b = math.sqrt(sum(x ** 2 for x in b)) # 计算余弦相似度cosine_similarity = dot_product / (norm_a * norm_b) print("向量 a:", a)print("向量 b:", b)print("余弦相似度:", cosine_similarity)这个例子展示了余弦相似度最基本的计算方式。
虽然 a 和 b 的长度不同,但它们方向完全一致,因此余弦相似度为 1。
示例 2:比较两组向量谁更相似
import math # 定义三个向量x = [1, 2, 3]y = [2, 4, 6]z = [3, 0, 1] # 定义余弦相似度函数def cosine_similarity(a, b): dot_product = 0 for i in range(len(a)): dot_product += a[i] * b[i] norm_a = math.sqrt(sum(v ** 2 for v in a)) norm_b = math.sqrt(sum(v ** 2 for v in b)) return dot_product / (norm_a * norm_b) sim_xy = cosine_similarity(x, y)sim_xz = cosine_similarity(x, z) print("x 与 y 的余弦相似度:", sim_xy)print("x 与 z 的余弦相似度:", sim_xz)这个例子展示了余弦相似度在比较多个向量时的典型用途。
若 x 与 y 的余弦相似度高于 x 与 z,就说明 x 与 y 在方向上更接近,也通常意味着它们的整体模式更相似。
📘 小结
余弦相似度是一种用来衡量两个向量方向相似程度的指标。它不强调两个对象绝对相隔多远,而强调它们在整体模式上是否朝着相近方向变化。在自然语言处理、文本检索、推荐系统和向量搜索中,余弦相似度都非常常见。对初学者而言,可以把它理解为:向量表示“对象如何被数字化”,而余弦相似度表示“这些数字化表示在方向上有多相像”。
“点赞有美意,赞赏是鼓励”
