点积是向量运算中最基础、最常用的运算之一。它将两个等长向量的对应分量相乘并求和,结果是一个标量。点积既可以表示一组数值的加权求和,也可以反映两个向量之间的方向关系。
在 Python 中,可以使用列表、循环、zip() 和 sum() 实现点积。对于两个等长的一维 NumPy 数组,还可以使用 np.dot() 或 @ 运算符计算点积。
一、什么是点积
1、点积的基本定义
点积(Dot Product)也称标量积(Scalar Product)。在实数向量空间中,它是标准内积(Inner Product)的一种具体形式。
设两个 n 维实向量为:
它们的点积定义为:
也可以写成求和形式:
点积的计算过程可以概括为:将两个向量对应位置的分量相乘,再将所有乘积相加,最终得到一个标量。
在标准坐标表示下,点积要求两个向量属于同一个 n 维实向量空间,因此具有相同数量的分量。
2、点积与逐元素乘法
设:
逐元素乘法得到一个向量:
点积则需要将这些乘积继续相加:
因此,逐元素乘法的结果仍是向量,点积的结果则是标量。
3、点积的手工计算示例
设两个三维向量为:
先计算对应位置分量的乘积:
再将三个乘积相加:
因此:
点积结果 −3 是一个标量,不再具有三个分量。
4、点积的基本性质
设 a、b、c 是同一实向量空间中的向量,k 是实数。
点积满足交换律:
对向量加法满足分配律:
与标量乘法满足:
向量与自身的点积等于其长度的平方:
只有零向量与自身的点积等于 0:
二、使用 Python 基本语法计算点积
1、使用循环计算
可以使用 Python 列表表示向量,并通过循环完成对应元素相乘与累加:
a = [2, -1, 3]b = [4, 5, -2]# 点积要求两个向量的长度相同if len(a) != len(b): raise ValueError("两个向量的长度必须相同")dot_product = 0# 将对应位置的元素相乘并累加for i in range(len(a)): dot_product += a[i] * b[i]print(dot_product)
输出:
变量 dot_product 从 0 开始,循环每执行一次,就将一组对应元素的乘积累加到已有结果中。
2、使用 zip() 和 sum()
zip() 可以将两个序列中相同位置的元素配对,生成式负责计算乘积,sum() 再对所有乘积求和:
a = [2, -1, 3]b = [4, 5, -2]if len(a) != len(b): raise ValueError("两个向量的长度必须相同")dot_product = sum( x * y for x, y in zip(a, b))print(dot_product)
输出:
zip() 会在较短的序列结束时停止。因此,计算点积前仍应检查两个向量的长度是否相同。
三、使用 NumPy 计算点积
1、使用 np.dot() 和 @
对于两个长度相同的一维 NumPy 数组,可以使用 np.dot() 函数或 @ 运算符计算点积:
import numpy as npa = np.array([2, -1, 3])b = np.array([4, 5, -2])result_1 = np.dot(a, b)result_2 = a @ bprint(result_1)print(result_2)
输出:
对于一维数组,np.dot(a, b) 和 a @ b 都会计算对应元素的乘积之和,得到相同的标量结果。
对于二维及更高维数组,np.dot() 与 @ 的规则会发生变化,不应再简单理解为两个向量的点积。相关规则将在矩阵乘法中进一步讨论。
2、点积结果的形状
上例中两个一维数组的形状都是 (3,)。点积结果是 NumPy 标量,其形状为 ():
result = a @ bprint(np.shape(result))
输出:
形状 () 表示结果是零维标量,不是形状为 (1,) 的一维数组。
四、点积的几何意义
1、点积与向量长度
n 维实向量 a 的长度为:
由于向量与自身的点积为:
因此:
点积不仅可以用来定义向量的长度,也可以用来反映两个向量之间的方向关系。
2、点积与向量夹角
对于两个非零向量 a 和 b,设它们之间的夹角为 θ,则:
其中:
‖a‖ 表示向量 a 的长度;
‖b‖ 表示向量 b 的长度;
θ 表示两个向量之间的夹角。
由此可以得到夹角余弦:
这个公式将点积的代数计算与向量的几何方向联系起来。
3、点积的符号与方向关系
对于两个非零向量,‖a‖ 和 ‖b‖ 均大于 0,因此点积的符号由 cos θ 决定:
a·b > 0:两个向量的夹角为锐角;
a·b = 0:两个向量的夹角为直角,二者相互正交;
a·b < 0:两个向量的夹角为钝角。
例如:
计算点积:
因此,两个非零向量 a 和 b 相互正交。
对应的 Python 代码为:
import numpy as npa = np.array([1, 0])b = np.array([0, 1])result = a @ bprint(result)
输出:
4、使用点积计算夹角
设:
先计算点积:
再计算两个向量的长度:
代入夹角公式:
因此:
使用 Python 计算:
import numpy as npa = np.array([1.0, 2.0])b = np.array([3.0, 1.0])# 计算点积dot_product = a @ b# 计算两个向量的长度norm_a = np.linalg.norm(a)norm_b = np.linalg.norm(b)# 根据点积公式计算夹角余弦cos_theta = dot_product / (norm_a * norm_b)# 避免浮点误差使结果略微超出 [-1, 1]cos_theta = np.clip(cos_theta, -1.0, 1.0)# 根据余弦值计算夹角,返回值的单位为弧度theta_radians = np.arccos(cos_theta)# 将弧度转换为角度theta_degrees = np.degrees(theta_radians)print("点积:", dot_product)print("夹角余弦:", cos_theta)print("夹角:", theta_degrees)
输出:
点积: 5.0夹角余弦: 0.7071067811865475夹角: 45.0
要注意的是,零向量的长度为 0,没有确定方向。因此,当任意一个向量为零向量时,不能使用夹角公式。
五、扩展:复数向量的内积
对于实数向量,点积是对应分量乘积之和。对于复数向量,标准内积需要对其中一个向量取复共轭。
不同教材可能采用不同的记号约定。这里采用 NumPy np.vdot() 的规则,对第一个向量取复共轭:
其中,āᵢ 表示 aᵢ 的复共轭。
例如:
根据上述约定:
NumPy 可以使用 np.vdot() 完成这种运算:
import numpy as npa = np.array([1 + 1j, 2])b = np.array([3, 1 - 1j])result = np.vdot(a, b)print(result)
输出:
np.vdot(a, b) 会先将输入展平,再对第一个输入取复共轭。
对于等长的实数一维数组,np.vdot()、np.dot() 和 @ 得到相同的数值结果;对于复数向量,三者的含义可能不同。
六、点积的典型应用
1、计算余弦相似度
点积结合向量长度,可以计算余弦相似度(Cosine Similarity),用于比较两个非零向量在方向上的接近程度:
NumPy 实现如下:
import numpy as npa = np.array([1.0, 2.0])b = np.array([2.0, 1.0])cosine_similarity = ( a @ b / (np.linalg.norm(a) * np.linalg.norm(b)))print(cosine_similarity)
输出可能为:
结果约为 0.8,说明两个向量的方向比较接近,但并不完全相同。
余弦相似度常用于比较文本、图像和其他数据的嵌入向量。其取值范围、特殊情况和距离关系将在后续文章中进一步讨论。
2、表示加权求和
点积还可以表示一组输入数值的加权求和。
设输入向量为:
权重向量为:
加权求和为:
这正是两个向量的点积:
例如,设:
手工计算:
NumPy 实现为:
import numpy as npv = np.array([4.0, 2.0, 5.0])w = np.array([0.5, 1.5, -1.0])weighted_sum = w @ vprint(weighted_sum)
输出:
点积可以表示输入与权重的加权求和;多个输出的点积可以进一步合并为矩阵乘法。
七、常见问题及使用建议
1、确认向量长度和数组形状
使用 NumPy 计算向量点积时,应确认两个输入都是长度相同的一维数组。
对于二维及更高维数组,np.dot() 和 @ 的运算规则会发生变化,不能再简单理解为两个向量的点积。
2、区分逐元素乘法与点积
对于一维数组,* 表示逐元素乘法,@ 和 np.dot() 表示点积,不要混用。
3、零向量不能用于计算夹角
零向量与任意向量的点积都为 0,因此零向量与任意向量都满足正交的代数定义。
但是,零向量没有确定方向,不能据此认为它与其他向量的夹角为 90°,因为这一夹角没有定义。
4、注意浮点数误差
计算夹角或余弦相似度时,浮点误差可能使理论上属于 [−1, 1] 的余弦值略微超出该范围,例如:
传入 np.arccos() 前,可以使用:
cos_theta = np.clip( cos_theta, -1.0, 1.0)
将数值限制在合法范围内,避免得到无效结果。
📘 小结
点积将两个等长向量的对应分量相乘并求和,结果是标量。它可以表示向量长度、方向关系、余弦相似度和加权求和。Python 可使用循环、np.dot() 或 @ 实现点积;计算夹角时,还需注意零向量和浮点误差。