趋近智
虽然向量加法、减法和标量乘法改变了向量的位置或尺度,但点积(也称作标量积或内积)提供了一种“乘法”方式,将两个向量相乘,得到一个单一的标量。这个标量描述了两个向量方向之间的关联,使其成为测量相似度以及理解特征空间中几何关联的重要方法。
对于Rn中的两个向量a=[a1,a2,...,an]和b=[b1,b2,...,bn],它们的点积,表示为a⋅b或aTb,通过对应元素相乘并求和得到:
a⋅b=∑i=1naibi=a1b1+a2b2+⋯+anbn
结果总是一个标量,而非向量。
例子: 设 a=[1,2,3] 且 b=[−2,0,4]。 它们的点积为: a⋅b=(1×−2)+(2×0)+(3×4)=−2+0+12=10
在Python中使用NumPy,可以通过numpy.dot函数、NumPy数组的dot方法或@运算符(Python 3.5+)有效计算点积。
import numpy as np
a = np.array([1, 2, 3])
b = np.array([-2, 0, 4])
# 方法 1: np.dot()
dot_product_1 = np.dot(a, b)
# 方法 2: .dot() 方法
dot_product_2 = a.dot(b)
# 方法 3: @ 运算符
dot_product_3 = a @ b
print(f"使用 np.dot 的点积: {dot_product_1}")
print(f"使用 .dot 方法的点积: {dot_product_2}")
print(f"使用 @ 运算符的点积: {dot_product_3}")
# 预期输出:所有方法均为 10
点积有一个强大的几何解释,它与两个向量(当它们首尾相接时)之间的夹角θ相关:
a⋅b=∣∣a∣∣2∣∣b∣∣2cos(θ)
这里,∣∣a∣∣2和∣∣b∣∣2是向量a和b的欧几里得 (L2) 范数(模长)。此公式将代数计算(∑aibi)与几何(长度和向量间的夹角)联系起来。
我们可以重新排列此公式来求夹角:
cos(θ)=∣∣a∣∣2∣∣b∣∣2a⋅b θ=arccos(∣∣a∣∣2∣∣b∣∣2a⋅b)
点积的符号描述了夹角θ:
几何解释直接引出了机器学习中向量间相似度的一个常用度量:余弦相似度。它测量了两个非零向量间夹角的余弦值。
余弦相似度(a,b)=cos(θ)=∣∣a∣∣2∣∣b∣∣2a⋅b
余弦相似度的取值范围是 -1 到 1:
这种度量广泛应用于自然语言处理(NLP)等领域,以比较文档嵌入或词向量,以及在推荐系统中查找相似用户或物品,因为它侧重于向量的朝向(方向)而非其模长。例如,两篇讨论相同主题的文档,它们的向量表示可能指向相似方向,即便其中一篇文档比另一篇长得多(向量模长更大)。
import numpy as np
# 例子:文档向量(例如,词频)
doc1 = np.array([2, 1, 0, 3]) # 词 A, B, C, D 的计数
doc2 = np.array([4, 2, 1, 6]) # 相似主题,更长的文档
doc3 = np.array([0, 0, 5, 1]) # 不同主题
def cosine_similarity(vec1, vec2):
dot_prod = vec1 @ vec2
norm1 = np.linalg.norm(vec1) # 默认是 L2 范数
norm2 = np.linalg.norm(vec2)
if norm1 == 0 or norm2 == 0:
return 0 # 如果向量为零,避免除以零
return dot_prod / (norm1 * norm2)
sim_1_2 = cosine_similarity(doc1, doc2)
sim_1_3 = cosine_similarity(doc1, doc3)
print(f"doc1 和 doc2 之间的相似度: {sim_1_2:.4f}") # 应该接近 1
print(f"doc1 和 doc3 之间的相似度: {sim_1_3:.4f}") # 应该低得多
# 预期输出(约):
# doc1 和 doc2 之间的相似度: 0.9990
# doc1 和 doc3 之间的相似度: 0.1705
点积的另一个主要用途是计算一个向量在另一个向量上的投影。想象将光源垂直照射到向量b上;向量a在包含b的线上投下的影子就是a在b上的向量投影。这个投影描述了向量a在向量b方向上的“量”。
向量a在向量b上的投影。紫色虚线向量
proj_b(a)是向量a沿向量b方向的分量。
有两个相关量:
标量投影: 这是向量投影的长度。它是“影子”的带符号模长。从三角学 (∣∣a∣∣2cos(θ)) 和点积公式 (a⋅b=∣∣a∣∣2∣∣b∣∣2cos(θ)) 中,我们得到: 向量 a 在 b 上的标量投影=∣∣a∣∣2cos(θ)=∣∣b∣∣2a⋅b 符号指示投影方向与b方向相同(+)或相反(-)。
向量投影: 这是表示投影的实际向量。为了得到这个向量,我们将标量投影(长度)乘以b方向的单位向量。b方向上的单位向量是∣∣b∣∣2b。 projb(a)=(标量投影)×(向量 b 的单位向量) projb(a)=(∣∣b∣∣2a⋅b)∣∣b∣∣2b=∣∣b∣∣22a⋅bb 由于∣∣b∣∣22=b⋅b,一个常用的替代形式是: projb(a)=(b⋅ba⋅b)b
投影在需要将向量分解为分量的算法中非常有用,例如用于生成正交基的Gram-Schmidt正交化过程,并且它们被隐式应用于像主成分分析(PCA)这样的降维方法中,其中数据被投影到方差较大的方向上。
计算例子: 设 a=[2,3] 且 b=[4,0]。 a⋅b=(2)(4)+(3)(0)=8 b⋅b=(4)(4)+(0)(0)=16 ∣∣b∣∣2=16=4
向量a在b上的标量投影 =∣∣b∣∣2a⋅b=48=2。 向量a在b上的向量投影 =(b⋅ba⋅b)b=(168)[4,0]=21[4,0]=[2,0]。
这直观上讲得通:向量 a=[2,3] 在 x 轴方向上(即 b=[4,0] 的方向)有一个长度为 2 的分量。
import numpy as np
a = np.array([2, 3])
b = np.array([4, 0])
# 标量投影
scalar_proj = (a @ b) / np.linalg.norm(b)
# 向量投影
vector_proj = ( (a @ b) / (b @ b) ) * b
# 使用标量投影计算向量投影的替代方法:
# unit_b = b / np.linalg.norm(b)
# vector_proj_alt = scalar_proj * unit_b
print(f"向量 a: {a}")
print(f"向量 b: {b}")
print(f"向量 a 在 b 上的标量投影: {scalar_proj:.4f}")
print(f"向量 a 在 b 上的向量投影: {vector_proj}")
# 预期输出:
# 向量 a 在 b 上的标量投影: 2.0000
# 向量 a 在 b 上的向量投影: [2. 0.]
点积和投影是非常实用的方法。它们使我们能够从简单的向量运算转向分析向量间的几何关联、测量相似度以及将向量分解为有特定意义的分量,所有这些都是在机器学习中处理数据时的常见操作。
简洁的语法。内置调试功能。从第一天起就可投入生产。
为 ApX 背后的 AI 系统而构建
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造