我想在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]])
您对输出的分析是正确的,但对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范数是平衡的,在二的一个数量级内,使得精确的数量级反映到缩放矩阵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.]
对于大多数用例来说,这应该是"足够接近"的。