NumPy中np.linalg.eig特征分解重构原矩阵结果错误排查
问题描述
后续算法中使用的weights是维度为2017×2017、秩为7的对称矩阵。对矩阵做特征分解后,尝试通过累加特征分量还原原始矩阵时出现异常:直接计算得到的neoweights1与weights结果一致,但循环累加计算得到的neoweights与原矩阵完全不同。
涉及的错误代码如下:
w,v = np.linalg.eig(weights) neoweights1 = w2 * (v2 @ v2.T) neoweights = np.zeros((matsize,matsize)) for i in range(7): neoweights += np.real(w2[i] * (v2[i] @ v2[i].T))
注:代码中w2、v2为筛选排序后的前7个非零特征值、对应特征向量矩阵。
错误原因
核心错误是对np.linalg.eig返回的特征向量矩阵结构理解有误:
np.linalg.eig返回的特征向量矩阵v中,每一列对应一个特征值的特征向量,而非每一行- 循环中写的
v2[i]取的是特征向量矩阵的第i行,不是第i个特征向量。此时v2[i]是一维数组,v2[i] @ v2[i].T计算的是向量内积,返回单个标量值,相当于每次循环给整个矩阵的所有元素加同一个数值,完全不符合特征分解“累加特征值乘对应特征向量外积得到的秩1矩阵”的计算逻辑,最终结果必然和原矩阵不符。
修正方案
将循环中取行的逻辑改为取对应列的特征向量,同时正确计算特征向量的外积得到秩1矩阵,修正后的代码如下:
w,v = np.linalg.eig(weights) neoweights1 = w2 * (v2 @ v2.T) neoweights = np.zeros((matsize,matsize)) for i in range(7): # 取第i个特征向量(第i列) eigen_vec = v2[:, i] # 累加 特征值 * 特征向量外积得到的秩1矩阵 neoweights += np.real(w2[i] * np.outer(eigen_vec, eigen_vec))
修正后循环累加得到的neoweights会和直接计算的neoweights1、原矩阵weights一致。
内容的提问来源于stack exchange,提问作者Sea Erchin
相关产品推荐
相关产品推荐

