【第8章 数据分析基础】逐元素乘法、矩阵乘法(矩阵积)、向量点乘(点积)、向量叉乘(叉积)的全面辨析

这是一个常见的概念混淆。下面我们从 定义、用途、计算方式、NumPy 实现 四个角度彻底厘清:


一、先说结论(一句话总结)

名称 是否存在? 正确术语 对应 NumPy 操作
矩阵乘法 ✅ 存在 矩阵乘积(Matrix Multiplication) A @ Bnp.dot(A, B)
矩阵叉乘 不存在 叉乘仅针对向量(通常是3D) np.cross(a, b)(仅用于向量)

🔑 叉乘(cross product)是向量运算,不是矩阵运算
你不能对两个普通矩阵做“叉乘”。


二、什么是矩阵乘法?(Matrix Multiplication)

定义:

给定矩阵 ( A \in \mathbb{R}^{m \times n} ) 和 ( B \in \mathbb{R}^{n \times p} ),
它们的矩阵乘积 ( C = AB ) 是一个 ( m \times p ) 的矩阵,其中:

[
C_{ij} = \sum_{k=1}^{n} A_{ik} B_{kj}
]

示例:

import numpy as np

A = np.array([[1, 2],
              [3, 4]])      # (2,2)
B = np.array([[5, 6],
              [7, 8]])      # (2,2)

C = A @ B   # 或 np.dot(A, B)
print(C)
# 输出:
# [[19 22]   # 1*5 + 2*7 = 19,  1*6 + 2*8 = 22
#  [43 50]]  # 3*5 + 4*7 = 43,  3*6 + 4*8 = 50
import numpy as np

# 示例1:2×2矩阵 × 2×3矩阵(列数2=行数2,满足要求)
A = np.array([[1, 2], [3, 4]])  # 形状:(2,2)(2行2列)
B = np.array([[5, 6, 7], [8, 9, 10]])  # 形状:(2,3)(2行3列)
C = A @ B  # 等价于np.matmul(A, B)
print("矩阵乘法结果(A@B):")
print(C)
# 计算逻辑:
# 第1行第1列:1×5 + 2×8 = 5 + 16 = 21
# 第1行第2列:1×6 + 2×9 = 6 + 18 = 24
# 第1行第3列:1×7 + 2×10 = 7 + 20 = 27
# 第2行第1列:3×5 + 4×8 = 15 + 32 = 47
# 第2行第2列:3×6 + 4×9 = 18 + 36 = 54
# 第2行第3列:3×7 + 4×10 = 21 + 40 = 61
# 输出:
# [[21 24 27]
#  [47 54 61]]

# 示例2:向量与矩阵的矩阵乘法(向量可视为1行n列或n行1列的矩阵)
x = np.array([1, 2])  # 形状:(2,),可视为(1,2)的行向量
D = x @ A  # x是(1,2),A是(2,2),结果为(1,2)的行向量
print("\n向量×矩阵的矩阵乘法结果:", D)  # 计算:1×1+2×3=7,1×2+2×4=10 → 输出:[ 7 10]

关键提醒:矩阵乘法不满足交换律,即 A@B ≠ B@A(除非是特殊矩阵如方阵),这与逐元素乘法完全不同。
✅ 这是线性代数中最基础、最重要的运算之一,用于:

  • 线性变换复合
  • 神经网络全连接层
  • 坐标变换等

三、什么是叉乘?(Cross Product)

首先明确:向量叉乘(Cross Product)是「三维向量特有的运算」,结果是一个「垂直于两个输入向量的新向量」,而非元素级运算(与点积、哈达玛积完全不同)。

1. 数学定义(三维向量)

设两个三维向量:

  • a = (a1, a2, a3)
  • b = (b1, b2, b3)

叉乘结果 a × b 是一个向量,计算公式为:

a × b = (a2*b3 - a3*b2, a3*b1 - a1*b3, a1*b2 - a2*b1)

几何意义:新向量的长度 = 两个向量长度的乘积 × 夹角正弦值(即平行四边形面积),方向由右手定则确定。

2. NumPy 中的叉乘实现

NumPy 用 np.cross(a, b) 实现向量叉乘,必须保证输入是三维向量(1D 数组长度为 3,或 2D 数组每行是三维向量)。

代码示例:

import numpy as np

# 1. 两个三维向量(1D 数组)
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
cross = np.cross(a, b)
print(cross)  # 输出:[-3  6 -3](按公式计算验证:2*6-3*5=-3,3*4-1*6=6,1*5-2*4=-3)

# 2. 多个三维向量(2D 数组,每行是一个向量)
a = np.array([[1,2,3], [4,5,6]])
b = np.array([[7,8,9], [10,11,12]])
cross = np.cross(a, b)
print(cross)  # 输出:[[-3  6 -3], [-3  6 -3]]

关键注意:

  • 若输入不是三维向量(如 2D 向量),np.cross 会自动补 0 成三维((x,y) → (x,y,0)),但结果可能不符合预期,需谨慎使用;
  • 叉乘不满足交换律:np.cross(a, b) = -np.cross(b, a)(方向相反)。

四、为什么会有“矩阵叉乘”的误解?

可能源于以下混淆:

混淆点 正确理解
“叉乘看起来像乘法” 叉乘是特殊向量运算,和普通乘法、矩阵乘法都不同
“3×3 矩阵和向量有关” 旋转矩阵可以表示叉乘的线性变换,但矩阵本身不做叉乘
中文口语说“矩阵相乘”泛指 技术上,“矩阵乘法”特指 matrix multiplication

五、NumPy 中的对应操作速查

数学运算 NumPy 写法 输入要求
逐元素乘法 A * B 形状可广播
矩阵乘法 A @ Bnp.dot(A, B) A 列数 = B 行数
向量点积 np.dot(a, b)a @ b 向量长度相同
向量叉乘 np.cross(a, b) 向量长度为 2 或 3

六、总结

  • x * xx ** 2 等价,都是元素级平方,可互换;
  • 矩阵乘法:存在,是标准线性代数运算,用 @np.dot
  • 矩阵叉乘不存在。叉乘只作用于向量(尤其是 3D 向量)。
  • 🔄 如果你有一批 3D 向量(形状 (N,3)),可以用 np.cross 批量计算,但这仍是向量叉乘的批量版,不是“矩阵叉乘”。

非常好的问题!“点积”、“点乘”、“矩阵乘法”这几个术语在不同语境下容易混淆。下面我们从数学定义、NumPy 实现、相互关系三个层面彻底厘清:


✅ 一句话总结

术语 是否等价? 说明
点积 = 点乘 ✅ 是 两者是同一概念的不同叫法(dot product)
点积 = 矩阵乘法? ⚠️ 部分情况是 当两个向量做矩阵乘法时,结果等于点积;但矩阵乘法范围更广

一、点积(Dot Product) = 点乘

✔ 定义:

给定两个相同长度的向量 (\mathbf{a}, \mathbf{b} \in \mathbb{R}^n),
它们的点积(也叫内积标量积)是一个标量(单个数):

[
\mathbf{a} \cdot \mathbf{b} = a_1 b_1 + a_2 b_2 + \cdots + a_n b_n = \sum_{i=1}^{n} a_i b_i
]

✔ NumPy 实现:

import numpy as np

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

# 以下三种写法等价:
result1 = np.dot(a, b)
result2 = a @ b          # Python 3.5+ 推荐
result3 = np.sum(a * b)  # 手动实现

print(result1)  # 32 → 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32

“点积”和“点乘”完全等价,只是中文习惯不同:“点积”强调结果是“积”,“点乘”强调运算形式像“乘”。


二、点积 和 矩阵乘法 的关系

🔑 核心结论:

两个向量的点积,可以看作是矩阵乘法的一个特例

📌 具体来说:

假设:

  • (\mathbf{a}) 是列向量(shape (n, 1)
  • (\mathbf{b}) 是列向量(shape (n, 1)

那么:

  • (\mathbf{a}^\top \mathbf{b})(行向量 × 列向量)是一个 1×1 矩阵,其值等于点积;
  • 在 NumPy 中,如果你用 a @ ba, b 都是 1D 数组,NumPy 会自动按向量点积处理

✅ 示例:

a = np.array([1, 2, 3])      # shape (3,) → 1D 向量
b = np.array([4, 5, 6])      # shape (3,)

print(a @ b)                 # 32 → 点积(标量)

# 如果显式转为 2D:
a_col = a.reshape(-1, 1)     # (3,1)
b_row = b.reshape(1, -1)     # (1,3)

print(b_row @ a_col)         #  → 1x1 矩阵,值为点积

❌ 但注意:

  • 如果你用两个 2D 矩阵相乘(如 (2,3) @ (3,4)),这是普通矩阵乘法,结果是 (2,4) 矩阵,不是点积
  • 点积只针对两个向量,结果是标量;矩阵乘法可作用于任意兼容维度的矩阵,结果通常是矩阵。

三、对比总结表

运算 输入要求 输出类型 NumPy 写法 是否等价
点积 / 点乘 两个等长向量(1D 或 (n,) 标量 np.dot(a,b)a @ b ✅ 点积 = 点乘
矩阵乘法 A: (m,n), B: (n,p) (m,p) 矩阵 A @ Bnp.dot(A,B) ⚠️ 点积是其特例(当 m=p=1)
逐元素乘法 形状可广播 同形状数组 A * B ❌ 完全不同

四、常见误区澄清

❌ 误区1:“点乘就是 *

→ 错!a * b逐元素相乘,结果还是向量:

a = [1,2,3]; b = [4,5,6]
a * b → [4,10,18]  # 不是 32!

❌ 误区2:“所有 @ 都是点积”

→ 错!@通用矩阵乘法运算符

  • 对 1D 数组:执行点积(返回标量)
  • 对 2D+ 数组:执行标准矩阵乘法(返回矩阵)

✅ 正确认知:

  • 点积 = 向量之间的特殊矩阵乘法
  • 矩阵乘法 ⊃ 点积(点积是子集)

五、实际应用场景

场景 用什么? 为什么?
计算两个特征向量的相似度 a @ b 点积衡量方向一致性
神经网络全连接层 X @ W 矩阵乘法批量计算线性组合
求向量长度平方 v @ v 点积自身 = ∥v∥²

✅ 终极总结

  • 点积 = 点乘:✅ 完全等价,都是 a · b = Σ aᵢbᵢ,结果是标量。
  • 点积 是 矩阵乘法的特例:✅ 当两个向量以“行×列”形式相乘时,矩阵乘法退化为点积。
  • 但矩阵乘法 ≠ 点积:❌ 矩阵乘法适用范围更广,结果通常是矩阵。

🧠 记住口诀:
“点乘点积一回事,矩阵乘法包罗它;
向量相乘得标量,矩阵相乘得矩阵。”

这样你就再也不会混淆啦!

📌 记住:
“叉乘属于向量,矩阵只有乘法(和转置、求逆等)。”

这样就不会再混淆啦!

posted @ 2025-11-22 23:11  wangya216  阅读(257)  评论(0)    收藏  举报