现在位置: 首页 > AI 数学基础 > 正文

向量的加法与数乘 -- 几何视角

向量加法:把两段位移拼接起来

向量可以理解为从原点出发的一支箭——有长度、有方向。

两个向量相加,就是把两段位移「拼接」在一起。

三角形法则

把第二个向量 b 的起点接到第一个向量 a 的终点。

从 a 的起点到 b 的终点的连线,就是 a + b。

直觉:「先走 a,再走 b」

平行四边形法则

以 a 和 b 为两条邻边,画一个平行四边形。

从起点出发的对角线,就是 a + b。

直觉:两种法则结果完全相同

数乘:拉伸或缩短向量

用一个标量(普通数字)去乘向量,结果是 改变向量的长度,但保持它所在的直线方向不变

|c| > 1

拉伸

如 2v:长度 ×2

0 < |c| < 1

缩短

如 0.5v:长度 ÷2

c < 0

反转方向

如 -v:方向相反

c = 0

缩为一个点

如 0v = 零向量

数乘只改变向量的「长度」,不改变它所在直线的方向(负数反转方向但仍在同一条直线上)。

这个性质叫做 共线性——数乘前后的两个向量总是在同一条直线上。


生活例子

向量加法:导航中的多段行程

你从家出发,先向东走 300 米(向量 a = (300, 0)),再向北走 400 米(向量 b = (0, 400))。

最终你在家的东北方向,距离 500 米处——这就是 a + b = (300, 400)。

数乘:视频倍速播放

正常速度走 5 步用 5 秒。用 2 倍速——同样的方向、同样步数,只用了 2.5 秒。

位移向量没变方向,但「每步的大小」翻倍了——这就是 2v 的效果。

反向:走回头路

你向东走了 100 米(v = (100, 0)),然后想回到原点——你需要向西走 100 米(-v = (-100, 0))。

负号就是向量方向的「掉头」指令。


数学定义

向量加法

两个同维度的向量相加,就是对应位置的元素分别相加。

\[ \mathbf{a} + \mathbf{b} = \begin{bmatrix} a_1 \\ a_2 \\ \vdots \\ a_n \end{bmatrix} + \begin{bmatrix} b_1 \\ b_2 \\ \vdots \\ b_n \end{bmatrix} = \begin{bmatrix} a_1 + b_1 \\ a_2 + b_2 \\ \vdots \\ a_n + b_n \end{bmatrix} \]

前提条件:两个向量维度必须相同,否则加法无意义。

向量减法

向量减法 = 加上反方向的向量:\( \mathbf{a} - \mathbf{b} = \mathbf{a} + (-\mathbf{b}) \)

向量数乘

一个标量 c 乘以一个向量,就是把向量的每个元素都乘以 c:

\[ c \cdot \mathbf{v} = c \cdot \begin{bmatrix} v_1 \\ v_2 \\ \vdots \\ v_n \end{bmatrix} = \begin{bmatrix} c \cdot v_1 \\ c \cdot v_2 \\ \vdots \\ c \cdot v_n \end{bmatrix} \]

运算性质速查

性质公式直觉
交换律\( \mathbf{a} + \mathbf{b} = \mathbf{b} + \mathbf{a} \)先走哪段都一样
结合律\( (\mathbf{a}+\mathbf{b})+\mathbf{c} = \mathbf{a}+(\mathbf{b}+\mathbf{c}) \)怎么分组走都一样
分配律\( c(\mathbf{a}+\mathbf{b}) = c\mathbf{a} + c\mathbf{b} \)先加再拉伸 = 先拉伸再加

Python 动手实践

实例

import numpy as np

# 创建两个向量
a_runoob = np.array([3, 1])    # a = (3, 1)
b_runoob = np.array([1, 2])    # b = (1, 2)

# 向量加法:对应位置相加
add_result = a_runoob + b_runoob
print("a + b =", add_result)    # [4, 3]

# 向量减法
sub_result = a_runoob - b_runoob
print("a - b =", sub_result)    # [2, -1]

# 数乘:每个元素乘以标量
c = 2.5
scale_result = c * a_runoob
print(f"{c} * a =", scale_result)  # [7.5, 2.5]

# 负向量:方向完全相反
neg = -a_runoob
print("-a =", neg)              # [-3, -1]

# NumPy 广播:标量与向量各元素直接运算
print("a + 10 =", a_runoob + 10)   # 每个元素都加 10
print("a * 3  =", a_runoob * 3)    # 每个元素都乘 3
a + b = [4 3]
a - b = [2 -1]
2.5 * a = [7.5 2.5]
-a = [-3 -1]
a + 10 = [13 11]
a * 3  = [9 3]

实例

import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

RUnoob_a = np.array([3, 1])
RUnoob_b = np.array([1, 2])
RUnoob_sum = RUnoob_a + RUnoob_b

fig, axes = plt.subplots(1, 2, figsize=(12, 5))

# 左图:三角形法则
for ax, title in zip(axes, ['三角形法则', '平行四边形法则']):
    ax.set_xlim(-1, 6); ax.set_ylim(-1, 5)
    ax.axhline(y=0, color='gray', lw=0.5); ax.axvline(x=0, color='gray', lw=0.5)
    ax.set_aspect('equal'); ax.grid(True, alpha=0.3); ax.set_title(title)

# 画三角形法则
ax = axes[0]
ax.arrow(0, 0, RUnoob_a[0], RUnoob_a[1], head_width=0.2, head_length=0.2,
         fc='#e74c3c', ec='#e74c3c', lw=2, label='a')
ax.arrow(RUnoob_a[0], RUnoob_a[1], RUnoob_b[0], RUnoob_b[1],
         head_width=0.2, head_length=0.2, fc='#3498db', ec='#3498db', lw=2, label='b')
ax.arrow(0, 0, RUnoob_sum[0], RUnoob_sum[1], head_width=0.2, head_length=0.2,
         fc='#2ecc71', ec='#2ecc71', lw=2, ls='dashed', label='a+b')
ax.legend()

# 画平行四边形法则
ax = axes[1]
ax.arrow(0, 0, RUnoob_a[0], RUnoob_a[1], head_width=0.2, head_length=0.2,
         fc='#e74c3c', ec='#e74c3c', lw=2, label='a')
ax.arrow(0, 0, RUnoob_b[0], RUnoob_b[1], head_width=0.2, head_length=0.2,
         fc='#3498db', ec='#3498db', lw=2, label='b')
ax.arrow(RUnoob_a[0], RUnoob_a[1], RUnoob_b[0], RUnoob_b[1],
         head_width=0.2, head_length=0.2, fc='#3498db', ec='#3498db', lw=1.5, ls='dotted', alpha=0.6)
ax.arrow(RUnoob_b[0], RUnoob_b[1], RUnoob_a[0], RUnoob_a[1],
         head_width=0.2, head_length=0.2, fc='#e74c3c', ec='#e74c3c', lw=1.5, ls='dotted', alpha=0.6)
ax.arrow(0, 0, RUnoob_sum[0], RUnoob_sum[1], head_width=0.2, head_length=0.2,
         fc='#2ecc71', ec='#2ecc71', lw=2, ls='dashed', label='a+b')
ax.legend()
plt.tight_layout(); plt.show()

交互式向量加法演示

拖动下方红色向量 a 和蓝色向量 b 的端点,观察绿色和向量 a+b 实时变化。体会三角形法则和平行四边形法则:


AI 中的应用场景

词向量的语义运算

Word2Vec 和 GloVe 等词嵌入模型最著名的发现:向量的加减法有语义含义。

\[ \text{vec}(\text{国王}) - \text{vec}(\text{男人}) + \text{vec}(\text{女人}) \approx \text{vec}(\text{女王}) \]

减法是去掉「男性」特征分量,加法是加上「女性」特征分量。结果向量在嵌入空间中距离「女王」最近。

这种语义运算不仅限于性别——「巴黎 - 法国 + 意大利 ≈ 罗马」也是同样的原理。向量的加法和减法在此起到了「特征编辑」的作用。

神经网络中的偏置

每个神经元的计算 \( y = Wx + b \) 中,+b 就是向量加法——偏置将 wx 的结果整体平移。

如果没有偏置 b,模型在 x=0 时输出必定为 0,这严重限制了模型的表达能力。偏置相当于给每个神经元一个「默认激活值」。

梯度更新

训练时的参数更新 \( \theta_{new} = \theta_{old} - \eta \nabla J \) 就是数乘(学习率 × 梯度)与向量减法的组合。

数乘控制每步更新的大小(学习率越大步长越大),减法将参数向损失减小的方向移动。

数据预处理:均值中心化

在训练神经网络之前,通常会对数据做「减均值」操作:\( x_{norm} = x - \mu \)。这就是向量减法——将数据中心平移到原点,有助于梯度下降更快收敛。