Python使用SVD分解重构不同维度矩阵遇广播错误如何解决
SVD矩阵重构与求逆问题解决方案
前置问题修正:X_b矩阵构造错误
你贴出的X_b每个元素都是独立的单元素数组,属于嵌套三维数组结构,会导致SVD分解结果维度异常。首先需要将其转换为标准二维numpy数组:
import numpy as np X_b = np.array([ [2.52390408, 2.4962137, 2.46467486, 2.48760957], [2.52390408, 2.4962137, 2.46467486, 2.48760957] ])
后续SVD分解和重构逻辑和下文R矩阵的处理方法完全一致。
R矩阵重构报错根因
np.linalg.svd返回的奇异值s是长度等于min(矩阵行数, 矩阵列数)的一维数组,而非二维对角矩阵。你设置full_matrices=True时,u的形状为(3,3),而s只有2个非零元素,直接用*做逐元素乘法时维度无法匹配,触发广播报错。
解决方法
方法1:构造完整奇异值矩阵重构
将s填充为和原始矩阵R形状一致的对角矩阵,再做矩阵乘法:
R = np.array([ [190.93095651, 189.30517758], [187.01785506, 185.38861727], [183.29225361, 181.47205695] ]) u, s, vh = np.linalg.svd(R, full_matrices=True) # 构造3行2列的奇异值矩阵,对角线填充s元素,其余为0 s_full = np.zeros((u.shape[0], vh.shape[0])) np.fill_diagonal(s_full, s) # 重构矩阵 R_recon = u @ s_full @ vh # 验证和原始矩阵是否一致 print(np.allclose(R_recon, R)) # 输出为True即验证通过
方法2:截断SVD重构(性能更优)
非零奇异值只有2个,u的第三列对应的奇异值为0,乘后结果为0,可以直接截取对应有效部分计算:
k = len(s) R_recon = u[:, :k] @ np.diag(s) @ vh print(np.allclose(R_recon, R))
扩展:通过SVD求矩阵伪逆
如果需要用SVD实现矩阵求逆,可参考如下写法:
# 对非零奇异值取倒数,可加阈值过滤极小值避免除零 s_inv = np.diag(1/s) R_pinv = vh.T @ s_inv @ u[:, :len(s)].T # 和numpy内置伪逆结果验证 print(np.allclose(R_pinv, np.linalg.pinv(R)))
内容的提问来源于stack exchange,提问作者Elaf Salah
相关产品推荐
相关产品推荐

