从 python 而不是 l2 获取 l1 归一化特征向量?

Getting l1 normalized eigenvectors from python instead of l2?

考虑这个矩阵:

[.6, .7]
[.4, .3]

这是马尔可夫链矩阵;每列总和为 1。这可以表示人口分布、转换率等。

为了使总体处于平衡状态,取特征值和特征向量...

来自 wolfram alpha,特征值及其对应的特征向量是:

l1 = 1, v1 = [4/7, 1]
l2 = -1/10, v2 = [-1,1]

对于处于平衡状态的总体,取对应于特征值 1 的特征向量,并对其进行缩放,使总数 = 1。

Vector = [7/4, 1]
Total = 11/4

所以向量乘以 4/11...

4/11 * [7/4, 1] = [7/11, 4/11]

因此,在平衡状态下,第一个州占人口的 7/11,另一个州占人口的 4/11。

如果您采用所需的特征向量,[7/4, 1] 并对其进行 l2 归一化(因此所有平方值总和为 1),您将大致得到 [.868, .496].

没关系。但是当你从 python...

得到特征向量时
mat = np.array([[.6, .7], [.4, .3]])
vals, vecs = np.linalg.eig(mat)
vecs = vecs.T #(because you want left eigenvectors)

它吐出的特征向量之一是 [.868, .496],对于 l2 范数。现在,您可以很容易地再次缩放它,使每个值的总和为 1(而不是每个值的平方和)为 1...只需执行 vector * 1/sum(vector)。但是有没有办法跳过这一步呢?为什么要将计算费用添加到我的脚本中,每次执行此操作时都必须对向量求和?你能得到 numpy、scipy 等来吐出 l1 归一化向量而不是 l2 归一化向量吗?另外,术语 l1 和 l2... 的用法是否正确?

注意:我已经看到以前的问题询问如何以这种方式获得马尔可夫稳态。我的问题不同,我问的是如何让 numpy 以我想要的方式吐出一个归一化的向量,我通过包括马尔可夫部分来解释我的推理。

我认为您假设 np.linalg.eig 像您手动计算特征向量和特征值一样。它没有。 在幕后,它使用了一个高度优化的(著名的)FORTRAN 库,称为 LAPACK。该库使用的数值技术有点超出范围,但长话短说,它不会像您手动那样计算 2x2 的特征值。我相信它大部分时间使用 the QR algorithm,有时使用 QZ,甚至其他。这并不是那么简单:我认为它有时甚至会根据矩阵 structure/size 选择不同的算法(我不是 LAPACK 专家,所以不要在这里引用我的话)。我所知道的是,LAPACK 已经经过了大约 40 年的审查,它的速度非常快,而且速度越快,复杂性就越高。

另一方面,Wolfram Alpha 在后端使用 Mathematica,这是一个符号求解器(即不是浮点运算)。这就是为什么您得到 "same" 结果就像您手动完成一样。

长话短说,要求您从 np.linalg.eig 获得 L1 范数是不可能的: 如果您查看 QR 算法,每次迭代都会有L2 归一化向量(收敛到特征向量)。你很难从大多数数值库中获取它,原因很简单,因为它们中的很多都依赖于 LAPACK 或使用类似的算法(例如 MATLAB 也输出单位向量)。

归根结底,向量是否归一化并不重要。它确实必须朝着正确的方向发展。如果您需要按比例缩放它,那么就这样做。它将被 numpy 向量化(即快速),因为它是一个简单的乘法。

HTH.