pin_drop当前位置:知识文库 ❯ 图文

NumPy线性代数完整教程 - 矩阵运算与SVD分解

一、概述

NumPy的linalg模块提供了完整的线性代数运算功能,包括矩阵乘法、矩阵分解(LU、QR、SVD、Cholesky)、行列式计算、逆矩阵、特征值与特征向量、解线性方程组等。这些功能是科学计算、机器学习和工程计算的基础工具。

无论是解决多元一次方程组,还是进行主成分分析(PCA)降维,线性代数运算都是不可或缺的。NumPy将这些底层复杂的数学运算封装为简洁的API,让开发者无需手动实现复杂的算法。


二、语法与常用函数

NumPy线性代数运算的核心入口是numpy.linalg模块。以下是常用语法概览:

代码示例

import numpy as np
from numpy import linalg

np.dot(a, b)          # 点积
linalg.inv(a)         # 逆矩阵
linalg.det(a)         # 行列式
linalg.eig(a)         # 特征值和特征向量
linalg.solve(a, b)    # 解线性方程组
linalg.norm(a)        # 范数
linalg.svd(a)         # 奇异值分解

三、参数说明

以下是linalg模块中各核心函数的参数说明:

函数 参数 说明
linalg.inv(a) a: 方阵 计算逆矩阵
linalg.det(a) a: 方阵 计算行列式
linalg.eig(a) a: 方阵 计算特征值和特征向量
linalg.eigh(a) a: 对称方阵 对称矩阵特征分解(更高效)
linalg.solve(a, b) a: 系数矩阵, b: 常数向量 解线性方程组Ax=b
linalg.norm(a, ord) a: 向量/矩阵, ord: 范数阶数 计算范数
linalg.svd(a) a: 矩阵 奇异值分解
linalg.qr(a) a: 矩阵 QR分解
linalg.cholesky(a) a: 正定矩阵 Cholesky分解
linalg.matrix_rank(a) a: 矩阵 计算矩阵秩

四、矩阵基本运算

矩阵运算是线性代数的基础。NumPy提供了矩阵乘法、求逆、行列式和矩阵秩等常用运算,下面通过代码示例来演示:

代码示例

import numpy as np
from numpy import linalg

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

# 矩阵乘法
print(f"A @ B:\n{A @ B}")

# 逆矩阵
A_inv = linalg.inv(A)
print(f"\nA的逆矩阵:\n{A_inv}")
print(f"验证 A @ A_inv:\n{np.round(A @ A_inv)}")

# 行列式
print(f"\nA的行列式: {linalg.det(A):.1f}")

# 矩阵秩
print(f"A的秩: {linalg.matrix_rank(A)}")

输出结果:

代码示例

A @ B:
[[19 22]
 [43 50]]

A的逆矩阵:
[[-2.   1. ]
 [ 1.5 -0.5]]
验证 A @ A_inv:
[[1. 0.]
 [0. 1.]]

A的行列式: -2.0
A的秩: 2

小贴士

在NumPy中,矩阵乘法推荐使用@运算符(Python 3.5+),它比np.dot()语义更清晰。行列式为0表示矩阵不可逆,此时调用linalg.inv()会抛出LinAlgError。


五、特征值与特征向量

特征值和特征向量描述了矩阵变换中的不变方向。对于一个方阵A,如果存在非零向量v和标量λ,使得A @ v = λ * v,则λ是特征值,v是对应的特征向量。

代码示例

import numpy as np
from numpy import linalg

A = np.array([[4, 2], [1, 3]])

# 特征值和特征向量
eigenvalues, eigenvectors = linalg.eig(A)

print(f"特征值: {eigenvalues}")
print(f"特征向量:\n{eigenvectors}")

# 验证: A @ v = lambda * v
for i in range(len(eigenvalues)):
    v = eigenvectors[:, i]
    lam = eigenvalues[i]
    print(f"\nlambda={lam:.2f}: A@v = {A @ v}, lambda*v = {lam * v}")

输出结果:

代码示例

特征值: [5. 2.]
特征向量:
[[ 0.89442719 -0.70710678]
 [ 0.4472136   0.70710678]]

lambda=5.00: A@v = [4.47213595 2.23606798], lambda*v = [4.47213595 2.23606798]

lambda=2.00: A@v = [-1.41421356  1.41421356], lambda*v = [-1.41421356  1.41421356]

代码验证了特征值和特征向量的定义:矩阵A乘以特征向量v等于特征值λ乘以v,说明计算结果正确。


六、解线性方程组与SVD分解

解线性方程组:对于方程组Ax=b,linalg.solve()可以直接求解。奇异值分解(SVD)是最通用的矩阵分解方法,可将任意矩阵分解为U、Σ、Vt三个矩阵的乘积。

代码示例

import numpy as np
from numpy import linalg

# 解线性方程组: 2x + y = 5, x + 3y = 10
A = np.array([[2, 1], [1, 3]])
b = np.array([5, 10])

x = linalg.solve(A, b)
print(f"方程组解: x={x[0]:.2f}, y={x[1]:.2f}")
print(f"验证: A@x = {A @ x}")

# SVD分解
M = np.array([[1, 2], [3, 4], [5, 6]])
U, S, Vt = linalg.svd(M)
print(f"\nSVD分解:")
print(f"U shape: {U.shape}, S: {S}, Vt shape: {Vt.shape}")

# 重构矩阵
S_matrix = np.zeros((3, 2))
S_matrix[:2, :2] = np.diag(S)
reconstructed = U @ S_matrix @ Vt
print(f"重构矩阵:\n{np.round(reconstructed)}")

# 范数计算
v = np.array([3, 4])
print(f"\nL2范数: {linalg.norm(v)}")
print(f"L1范数: {linalg.norm(v, ord=1)}")
print(f"无穷范数: {linalg.norm(v, ord=np.inf)}")

输出结果:

代码示例

方程组解: x=1.00, y=3.00
验证: A@x = [ 5. 10.]

SVD分解:
U shape: (3, 3), S: [9.52551809 0.51430058], Vt shape: (2, 2)
重构矩阵:
[[1. 2.]
 [3. 4.]
 [5. 6.]]

L2范数: 5.0
L1范数: 7.0
无穷范数: 4.0

提示:向量v=[3,4]的L2范数为√(3²+4²)=5,L1范数为|3|+|4|=7,无穷范数为max(|3|,|4|)=4。


七、实际应用场景

  • 场景1:机器学习中,使用SVD进行主成分分析(PCA)降维,减少特征维度的同时保留主要信息

  • 场景2:工程计算中,使用solve求解电路方程、结构力学方程等线性方程组

  • 场景3:推荐系统中,使用矩阵分解进行协同过滤,预测用户对物品的评分


八、注意事项

注意:linalg.inv()要求矩阵必须可逆(行列式不为0),否则抛出LinAlgError。不可逆矩阵也称为奇异矩阵。

注意:数值计算中逆矩阵可能不稳定,推荐优先使用solve()而非inv()求解方程组。solve内部使用LU分解,数值稳定性更好。

注意:对称矩阵使用eigh()比eig()更高效且数值更稳定,因为eigh利用了对称性进行优化。


九、线性代数函数对比

函数 输入 输出 适用场景
inv 方阵 逆矩阵 求逆
solve A, b 解向量 解方程组
eig 方阵 特征值+特征向量 特征分析
svd 任意矩阵 U, S, Vt 降维、压缩
qr 矩阵 Q, R 最小二乘
cholesky 正定矩阵 下三角矩阵L 高效求解

十、练习题

练习1

创建一个3x3的可逆矩阵,计算其逆矩阵,并验证A @ A_inv = I

练习2

使用linalg.solve()解三元一次方程组:x+y+z=6, 2x-y+z=3, x+y-2z=-2

练习3

对一个4x3的随机矩阵进行SVD分解,用前2个奇异值重构矩阵,计算重构误差

常见问题

为什么推荐使用solve()而不是inv()求解方程组?

solve()内部使用LU分解,数值稳定性更好,计算速度也更快。inv()需要先计算完整的逆矩阵,再与b相乘,增加了数值误差的累积。

SVD分解在数据压缩中如何应用?

SVD可以将矩阵分解为U、Σ、Vt,通过保留前k个最大奇异值(截断SVD),可以用更少的存储空间近似原矩阵。奇异值越大,包含的信息量越多。

矩阵的行列式代表什么几何意义?

行列式的绝对值表示矩阵所代表的线性变换对空间体积的缩放比例。行列式为0表示变换将空间压缩到了低维(不可逆),行列式为1表示保持体积不变。

eigh和eig有什么区别?

eigh专门用于对称/厄米特矩阵,利用对称性进行优化,计算速度更快、数值稳定性更好。当确定矩阵是对称矩阵时,应优先使用eigh。

标签: NumPy 线性代数 矩阵运算 SVD分解 特征值 逆矩阵

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: NumPy统计函数大全 - 均值方差分位数轴计算完整教程 下一篇: NumPy随机数生成器教程 - 概率分布与随机采样

poll相关推荐