趋近智
将向量的基本运算转化为代码是实际应用中常见的需求。为了高效地完成这些运算,通常会使用 NumPy,它是 Python 中进行数值计算的标准库。
首先,我们来设置环境,导入 NumPy 库。我们通常遵循的惯例是将其导入并使用别名 np。
import numpy as np
在 NumPy 中,向量表示为一维数组。你可以使用 np.array() 函数创建向量,传入一个 Python 列表即可。
# 创建两个向量 v 和 w
v = np.array([2, 1])
w = np.array([1, 3])
print(f"向量 v: {v}")
print(f"向量 w: {w}")
输出:
向量 v: [2 1]
向量 w: [1 3]
在 NumPy 中执行加法和减法很简单。该库重载了标准的 + 和 - 运算符,对相同形状的数组执行逐元素运算。
# 向量加法
v_plus_w = v + w
print(f"v + w = {v_plus_w}")
# 向量减法
v_minus_w = v - w
print(f"v - w = {v_minus_w}")
输出:
v + w = [3 4]
v - w = [ 1 -2]
这与我们讨论的代数规则相符。将 v 和 w 相加会得到一个新向量 [2+1,1+3]=[3,4]。从几何角度看,这个运算可以想象成将一个向量的尾部放在另一个向量的头部。所得向量连接起点和终点,形成一个三角形。
向量加法的几何解释。结果向量
v+w是由v和w形成的平行四边形的对角线。
要将向量乘以标量,我们使用 * 运算符。这个运算会按比例改变向量的长度。乘以正标量会改变其大小,而负标量除了改变大小外,还会反转其方向。
# 定义一个向量和一个标量
u = np.array([3, 2])
s = 2.5
# 执行标量乘法
scaled_u = s * u
print(f"向量 u: {u}")
print(f"标量 s: {s}")
print(f"s * u = {scaled_u}")
输出:
向量 u: [3 2]
标量 s: 2.5
s * u = [7.5 5. ]
可以看到,向量 u 的每个元素都乘以了标量 s。所得向量 [7.5, 5] 方向与 u 相同,但长度是 u 的 2.5 倍。
点积是线性代数中的一个核心运算,特别是在机器学习中。它给出一个单一的数值,与两个向量之间的夹角有关。NumPy 提供了几种方法来计算它。
np.dot() 函数是常用的方法:
v = np.array([2, 1])
w = np.array([1, 3])
# 使用 np.dot() 计算点积
dot_product = np.dot(v, w)
print(f"v 和 w 的点积是: {dot_product}")
输出:
v 和 w 的点积是: 5
计算方法是 (2×1)+(1×3)=2+3=5。
另外,自 Python 3.5 起,你可以使用 @ 运算符,它专门用于矩阵乘法,也适用于向量的点积。这个运算符通常使代码更易读。
# 使用 @ 运算符计算点积
dot_product_operator = v @ w
print(f"使用 @ 运算符的点积是: {dot_product_operator}")
输出:
使用 @ 运算符的点积是: 5
向量的范数是其长度或大小的量度。np.linalg.norm() 函数是完成此任务的工具。默认情况下,它计算 L2 范数(欧几里得范数)。
u = np.array([3, 4])
# 计算 L2 范数(默认)
l2_norm = np.linalg.norm(u)
print(f"u 的 L2 范数是: {l2_norm}")
输出:
u 的 L2 范数是: 5.0
计算方法是 32+42=9+16=25=5。
要计算其他范数,例如 L1 范数(曼哈顿距离),你可以指定 ord 参数。
# 计算 L1 范数
l1_norm = np.linalg.norm(u, ord=1)
print(f"u 的 L1 范数是: {l1_norm}")
输出:
u 的 L1 范数是: 7.0
这是元素绝对值的和:∣3∣+∣4∣=7。
如果两个向量的点积为零,则它们是正交的。这是一个简单有效的方法。我们来定义两个应该是正交的向量并进行检查。
# 定义两个正交向量
vec1 = np.array([1, 0])
vec2 = np.array([0, 1])
# 计算它们的点积
dot_prod = vec1 @ vec2
print(f"vec1 和 vec2 的点积是: {dot_prod}")
输出:
vec1 和 vec2 的点积是: 0
点积为 0 确认它们是正交的。现在,我们尝试使用两个非正交向量。
# 定义两个非正交向量
vec3 = np.array([1, 1])
vec4 = np.array([1, -0.5])
# 计算它们的点积
dot_prod_non_ortho = vec3 @ vec4
print(f"vec3 和 vec4 的点积是: {dot_prod_non_ortho}")
输出:
vec3 和 vec4 的点积是: 0.5
由于结果不为零,向量 vec3 和 vec4 不是正交的。
我们可以组合这些运算来解决有趣的问题。例如,我们可以找出两个向量之间的夹角 θ,使用从点积定义中导出的公式:
cos(θ)=∥v∥∥w∥v⋅w这意味着:
θ=arccos(∥v∥∥w∥v⋅w)让我们在 NumPy 中实现这一点。
v = np.array([2, 1])
w = np.array([1, 3])
# 计算点积
dot_vw = v @ w
# 计算范数
norm_v = np.linalg.norm(v)
norm_w = np.linalg.norm(w)
# 计算夹角的余弦值
cos_theta = dot_vw / (norm_v * norm_w)
# 计算弧度制下的夹角
angle_rad = np.arccos(cos_theta)
# 转换为度数以便于理解
angle_deg = np.degrees(angle_rad)
print(f"点积: {dot_vw:.2f}")
print(f"v 的范数: {norm_v:.2f}")
print(f"w 的范数: {norm_w:.2f}")
print(f"v 和 w 之间的夹角(弧度): {angle_rad:.2f}")
print(f"v 和 w 之间的夹角(度数): {angle_deg:.2f}")
输出:
点积: 5.00
v 的范数: 2.24
w 的范数: 3.16
v 和 w 之间的夹角(弧度): 0.64
v 和 w 之间的夹角(度数): 36.87
这个实战例子表明点积和范数如何一起作用,以提供有意义的几何信息。掌握这些 NumPy 运算是实现更高级机器学习算法的第一步。
这部分内容有帮助吗?
np.dot和@运算符)以及np.linalg.norm等线性代数例程。© 2026 ApX Machine Learning用心打造