趋近智
特征值 (λ) 和特征向量 (v) 由关系 Av=λv 定义。特征分解将矩阵 A 表示为 A=PDP−1,其中 P 的列是特征向量,D 是由特征值构成的对角矩阵。可以借助 Python 的 NumPy 库高效地进行这些计算。这是应用主成分分析(PCA)等方法的基本能力。
首先,请确保您已安装 NumPy 并将其导入:
import numpy as np
让我们使用一个简单的 2x2 对称矩阵。对称矩阵具有很好的性质,例如总是拥有实数特征值并且可以对角化。
# 定义一个对称矩阵
A = np.array([[4, 2],
[2, 1]])
print("我们的矩阵 A:")
print(A)
NumPy 的线性代数模块 linalg 专门提供了 eig 函数,用于计算特征值和特征向量。
# 计算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(A)
print("\n特征值:")
print(eigenvalues)
print("\n特征向量(每列是一个特征向量):")
print(eigenvectors)
输出说明:
eigenvalues:这是一个一维 NumPy 数组,包含矩阵 A 的特征值 (λ)。在此例中,我们得到 [5. 0.]。eigenvectors:这是一个二维 NumPy 数组,其中每列代表一个特征向量,它与 eigenvalues 数组中相同索引位置的特征值相对应。
eigenvectors[:, 0] 对应于 eigenvalues[0]。eigenvectors[:, 1] 对应于 eigenvalues[1]。NumPy 通常返回归一化的特征向量(长度为 1 的向量)。
让我们验证第一个特征值-特征向量对的基本关系 Av=λv。
# 提取第一个特征值和对应的特征向量
lambda_1 = eigenvalues[0]
v_1 = eigenvectors[:, 0] # 第一列
# 计算 A * v_1
Av1 = A @ v_1 # 使用 @ 运算符进行矩阵乘法
# 计算 lambda_1 * v_1
lambda1_v1 = lambda_1 * v_1
print("\n验证第一个特征值/特征向量:")
print(f"lambda_1: {lambda_1:.4f}")
print(f"v_1: {v_1}")
print(f"A @ v_1: {Av1}")
print(f"lambda_1 * v_1: {lambda1_v1}")
# 检查 Av1 和 lambda1_v1 是否接近(由于浮点运算)
print(f"Av1 和 lambda1*v1 在数值上是否接近? {np.allclose(Av1, lambda1_v1)}")
你应该会看到 A @ v_1 和 lambda_1 * v_1 的结果确实非常接近,这证实了它们之间的关系。你可以对第二个特征值和特征向量进行类似的检查。注意,当 λ=0 时,Av 会得到零向量,这与预期相符。
现在,让我们使用矩阵 A 的特征值和特征向量来重构它。回想公式 A=PDP−1,其中:
# 从特征向量构建矩阵 P
P = eigenvectors
# 从特征值构建对角矩阵 D
D = np.diag(eigenvalues)
# 计算 P 的逆
# 对于正交矩阵(如对称矩阵的特征向量),P_inv = P.T
# 但我们在这里使用 np.linalg.inv 以适应一般情况。
try:
P_inv = np.linalg.inv(P)
# 重构原始矩阵 A
A_reconstructed = P @ D @ P_inv
print("\n使用 P D P_inv 重构 A:")
print("矩阵 P(特征向量):")
print(P)
print("\n矩阵 D(对角特征值):")
print(D)
print("\n矩阵 P_inv(P 的逆):")
print(P_inv)
print("\n重构的矩阵 (P @ D @ P_inv):")
print(A_reconstructed)
# 验证重构
print(f"\n重构的矩阵与原始矩阵 A 是否接近? {np.allclose(A, A_reconstructed)}")
except np.linalg.LinAlgError:
print("\n矩阵 P 是奇异的,无法求逆。A 可能无法使用此方法对角化。")
输出应显示重构的矩阵在数值上与原始矩阵 A 非常接近。这验证了特征分解。
特征向量表示在应用矩阵 A 所代表的变换时,方向保持不变(仅发生缩放)的向量。让我们将此过程对矩阵 A 进行可视化。我们将变换一个标准基向量 e1=[1,0],并将其变换结果与第一个特征向量 v1 的变换结果进行比较。
# 定义标准基向量 e1 和第一个特征向量 v1
e1 = np.array([1, 0])
# v1 已在前面的步骤中定义
# 应用变换 A
Ae1 = A @ e1
Av1 = A @ v1 # 这应该是 lambda_1 * v1
# 准备绘图数据
origin = np.array([[0, 0], [0, 0], [0, 0], [0, 0]]) # 箭头的起点
vectors = np.array([e1, Ae1, v_1, Av1]) # 向量
该图显示了原始向量(实线)以及它们经矩阵 A 变换后的结果(虚线)。蓝色向量 e1 发生了旋转和缩放。红色向量 v1(一个特征向量)仅沿其原始方向按等于其特征值 (λ1≈5) 的因子进行缩放。它的变换版本 Av1 位于同一条线上。
np.linalg.eig 仍可能计算特征值和向量,但此时 P 将是奇异的(不可逆)。然而,对称矩阵总是可以对角化的。A 不是对称的,它可能具有复数特征值和特征向量。np.linalg.eig 可以正确处理这种情况,必要时会返回复数数据类型的数组。本次实践练习显示了 NumPy 如何简化特征值、特征向量的计算以及特征分解的验证。理解这些计算对于领会主成分分析(PCA)等算法如何借助这些特殊向量和标量来认识数据本身的结构,具有重要作用。
简洁的语法。内置调试功能。从第一天起就可投入生产。
为 ApX 背后的 AI 系统而构建
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造