矩阵是组织数据的结构,可以对其执行各种基本运算。与向量类似,这些运算既有数学定义,也有数据处理和算法实现中的实际用途。我们将介绍加法、减法、标量乘法和转置。高效执行这些运算很重要,我们将看到NumPy如何让这变得简单。矩阵加法和减法如果您熟悉向量加法,矩阵的加法或减法是很直观的。规则很简单:只有当矩阵具有完全相同的维度(行数和列数相同)时,才能进行加法或减法运算。运算是按元素进行的。如果您有两个 $m \times n$ 维的矩阵 $A$ 和 $B$,它们的和 $C = A + B$ 也是一个 $m \times n$ 矩阵,且每个元素 $c_{ij}$ 是 $A$ 和 $B$ 中对应元素的和:$$ c_{ij} = a_{ij} + b_{ij} $$同样,对于减法 $D = A - B$,每个元素 $d_{ij}$ 为:$$ d_{ij} = a_{ij} - b_{ij} $$示例:假设我们有两个 $2 \times 3$ 的矩阵:$$ A = \begin{bmatrix} 1 & 2 & 3 \ 4 & 5 & 6 \end{bmatrix}, \quad B = \begin{bmatrix} 7 & 8 & 9 \ 0 & 1 & 2 \end{bmatrix} $$它们的和 $A + B$ 是:$$ A + B = \begin{bmatrix} 1+7 & 2+8 & 3+9 \ 4+0 & 5+1 & 6+2 \end{bmatrix} = \begin{bmatrix} 8 & 10 & 12 \ 4 & 6 & 8 \end{bmatrix} $$它们的差 $A - B$ 是:$$ A - B = \begin{bmatrix} 1-7 & 2-8 & 3-9 \ 4-0 & 5-1 & 6-2 \end{bmatrix} = \begin{bmatrix} -6 & -6 & -6 \ 4 & 4 & 4 \end{bmatrix} $$使用NumPy实现:NumPy使用标准的 + 和 - 运算符使这些运算变得简单。import numpy as np # 定义矩阵 A 和 B A = np.array([[1, 2, 3], [4, 5, 6]]) B = np.array([[7, 8, 9], [0, 1, 2]]) # 矩阵加法 C = A + B print("矩阵 A:\n", A) print("\n矩阵 B:\n", B) print("\n矩阵之和 (A + B):\n", C) # 矩阵减法 D = A - B print("\n矩阵之差 (A - B):\n", D) # 尝试对不同形状的矩阵进行加法将引发错误 # E = np.array([[1, 2], [3, 4]]) # try: # F = A + E # except ValueError as e: # print(f"\n添加 A 和 E 时出错: {e}")机器学习中的意义: 虽然不如矩阵乘法常见,但加法和减法在组合或比较表示为矩阵的数据集时会用到,计算预测值和实际值之间的差异(误差矩阵),或在某些优化算法中更新权重矩阵时也会用到。标量乘法将矩阵乘以标量(一个数字)也是按元素进行的运算。您只需将矩阵中的每个元素乘以该标量。如果 $A$ 是一个 $m \times n$ 矩阵,$c$ 是一个标量,那么乘积 $cA$ 是一个 $m \times n$ 矩阵,其中每个元素是 $c \cdot a_{ij}$。示例:使用之前的矩阵 $A$ 和标量 $c=3$:$$ A = \begin{bmatrix} 1 & 2 & 3 \ 4 & 5 & 6 \end{bmatrix} $$$$ 3A = \begin{bmatrix} 3 \times 1 & 3 \times 2 & 3 \times 3 \ 3 \times 4 & 3 \times 5 & 3 \times 6 \end{bmatrix} = \begin{bmatrix} 3 & 6 & 9 \ 12 & 15 & 18 \end{bmatrix} $$使用NumPy实现:在标量和NumPy数组之间使用标准的 * 运算符。import numpy as np A = np.array([[1, 2, 3], [4, 5, 6]]) scalar = 3 # 标量乘法 scaled_A = scalar * A print("矩阵 A:\n", A) print(f"\n标量: {scalar}") print("\n标量乘法后的矩阵 (scalar * A):\n", scaled_A) # 也可以用数组乘以标量 scaled_A_alt = A * scalar print("\n标量乘法后的矩阵 (A * scalar):\n", scaled_A_alt)机器学习中的意义: 标量乘法常用于缩放数据集中的特征,调整梯度下降中的学习率(这时将梯度矩阵乘以学习率),或应用正则化项。矩阵转置矩阵的转置是通过交换其行和列获得的。原始矩阵 $A$ 中位于第 $i$ 行、第 $j$ 列的元素移动到转置矩阵 $A^T$ 的第 $j$ 行、第 $i$ 列。如果 $A$ 是一个 $m \times n$ 矩阵,它的转置 $A^T$ 将是一个 $n \times m$ 矩阵。示例:$$ A = \begin{bmatrix} 1 & 2 & 3 \ 4 & 5 & 6 \end{bmatrix} \quad (2 \times 3 \text{ 矩阵}) $$它的转置 $A^T$ 是:$$ A^T = \begin{bmatrix} 1 & 4 \ 2 & 5 \ 3 & 6 \end{bmatrix} \quad (3 \times 2 \text{ 矩阵}) $$请注意,第一行 $[1, 2, 3]$ 变成了第一列,第二行 $[4, 5, 6]$ 变成了第二列。需要记住的一个性质是,转置的转置会返回原始矩阵:$(A^T)^T = A$。使用NumPy实现:NumPy 数组有一个方便的 .T 属性用于转置。另外,您也可以使用 np.transpose() 函数。import numpy as np A = np.array([[1, 2, 3], [4, 5, 6]]) # 使用 .T 属性转置 A_transpose_T = A.T print("原始矩阵 A (2x3):\n", A) print("\n使用 .T 转置 (3x2):\n", A_transpose_T) # 使用 np.transpose() 转置 A_transpose_func = np.transpose(A) print("\n使用 np.transpose() 转置 (3x2):\n", A_transpose_func) # 转置行向量(将1D数组视为行) row_vec = np.array([7, 8, 9]) # 形状 (3,) print("\n原始行向量 (形状 {}):\n".format(row_vec.shape), row_vec) # 注意:对1D数组使用 .T 不会改变其形状! print("\n对1D数组使用 .T (形状 {}):\n".format(row_vec.T.shape), row_vec.T) # 要转置一个1D数组,首先需要将其变为2D(例如,1xN 或 Nx1) row_vec_2d = row_vec[np.newaxis, :] # 形状 (1, 3) col_vec = row_vec_2d.T # 形状 (3, 1) print("\n重塑为2D的行向量 (形状 {}):\n".format(row_vec_2d.shape), row_vec_2d) print("\n转置为列向量 (形状 {}):\n".format(col_vec.shape), col_vec)注意: 对一维NumPy数组(例如 np.array([1, 2, 3]))使用 .T 进行转置不会改变其形状。要将其视为数学上的行向量并转置为列向量,您通常需要使用 reshape() 或通过 np.newaxis 或 np.expand_dims() 添加新轴等方法,明确地赋予它两个维度(例如,行向量的形状为 (1, n),列向量的形状为 (n, 1))。机器学习中的意义: 转置是一种基本运算,在机器学习中出现的线性代数公式中广泛使用。例如,求解线性回归的正规方程涉及 $(X^T X)^{-1} X^T y$。它也用于计算协方差矩阵($X^T X$,假设 $X$ 已中心化)或调整数据形状以满足矩阵乘法或其他库函数的要求。这些基本运算是未来我们会遇到的更复杂矩阵操作的构建基础,特别是矩阵乘法,它对线性变换非常重要。掌握这些NumPy基础知识为实现机器学习算法打下了坚实根基。