2

我想在 python中执行矩阵平衡。我想使用linalg.matrix_balance以使输入矩阵成为双重随机矩阵

from scipy import linalg
import numpy as np
x = np.array([[1,2,7], [9,1,1], [1,2,10*np.pi]])

y, permscale = linalg.matrix_balance(x)    
np.abs(x).sum(axis=0) / np.abs(x).sum(axis=1)        
np.abs(y).sum(axis=0) / np.abs(y).sum(axis=1)


permscale  

array([[ 1.,  0.,  0.],
      [ 0.,  2.,  0.],
      [ 0.,  0.,  1.]])

看起来它实际上并没有平衡矩阵的行和列。知道我该怎么做吗?

如果我做:y, permscale = linalg.matrix_balance(x, scale=False)

结果也没有标准化:

array([[ 1. , 2. , 7. ], [ 9. , 1. , 1. ], [ 1. , 2. , 31.41592654]])
4

1 回答 1

1

您对输出的分析是正确的,但在考虑做什么时是错误的matrix_balance。从文档中,

平衡矩阵满足以下等式,

B = inv(T) * A * T(矩阵乘积)

我们可以用您的矩阵轻松验证,

>>>print(np.dot(np.dot(np.linalg.inv(permscale), x), permscale))

[[  1.           4.           7.        ]
 [  4.5          1.           0.5       ]
 [  1.           4.          31.41592654]]

确实如此y。这意味着matrix_balance像它声称的那样工作。你声称,

看起来它实际上并没有平衡矩阵的行和列。知道我该怎么做吗?

但这不是真的:这个修改后的矩阵的 L1 范数平衡的,在 2 的一个数量级内,因此精确的数量级反映到缩放矩阵permscale

您的目标是使您的矩阵具有双重随机性,而不是(仅)平衡吗?如果是这样,你可以看看例如 这个项目。按照那里提供的指南,我为您的数据找到了以下双随机矩阵,

>>>print(sk.fit(x))

[[ 0.1385636   0.55482644  0.30660996]
 [ 0.79518122  0.17688932  0.02792947]
 [ 0.06695665  0.26810303  0.66494032]]

>>>print(sk.fit(x).sum(axis=0), sk.fit(x).sum(axis=1))

[ 1.00070147  0.99981878  0.99947975] [ 1.  1.  1.]

对于大多数用例来说,这应该“足够接近”。

于 2018-07-12T17:22:38.483 回答