如何缩小我的2d numpy数组中的值而不会丢失信息

时间:2018-03-08 05:38:22

标签: python numpy math matrix data-science

我有一个大小为n的正方形2d数组,用数值填充。

对于每个条目,我对该条目的行和列求和,但减去原始条目。

while 1:
    new = np.copy(next)
    for i in xrange(n):
        for j in xrange(n):
            val = new[i][j] 
            rowsum = np.sum(new[i])
            colsum = np.sum(new[:,j])
            next[i][j] = rowsum+colsum-val-val

完成我想要的东西,但经过一些迭代后,条目通常会变得太大(因为它们几乎加倍)。我想定期缩减我的价值观,但我想这样做,这样我就不会丢失信息。重要信息是任何两个条目之间的百分比差异。

我希望以一种使条目为负的方式避免缩放。

输入范围不受任何限制。如果我能以某种方式扩展它以使负面条目变为正数,那将是特别好的。

我认为对矩阵进行归一化可能会有效,但它最终会将值推到一起,并且经过一些循环后,所有值都非常相等。

2 个答案:

答案 0 :(得分:2)

你可以在求和后应用一个像sigmoid函数一样有界的函数。 https://en.wikipedia.org/wiki/Sigmoid_function

enter image description here

因此,如果你取一个值的行和列的总和,然后将该值插入sigmoid函数,这将防止数字超出范围(0,1)。这样,无论您执行此操作多少次,都不会使数字爆炸。

可能有其他功能可能更适合您的想法,但想法是一样的。使用具有有界范围的函数,如果您的输出是此函数的输出,那么您使用的数字将始终具有相同的边界。

这(或类似的东西)是在神经网络的节点中使用的。由于节点的输出是网络中较早的所有连接节点的总和,因此在数字爆炸时可以获得相同的效果。有时在NN中他们称之为压扁功能,或者压扁。

答案 1 :(得分:1)

&#34;我认为对矩阵进行标准化可能会有效,但最终会将值推到一起,并且在一些循环之后所有值都非常相等。&#34; < / p>

这实际上是预期的,不是规范化的效果。

要理解为什么首先观察到你的操作实际上是循环卷积,内核除了第一行和第一列以外都是零,而左上角也是零,并且非零值都等于。

我们可以在numpy中查看这个

>>> from scipy.fftpack import fftn, ifftn
>>> 
>>> def iterate(new):
...     next = new.copy()
...     for i in xrange(n):
...         for j in xrange(n):
...             val = new[i][j] 
...             rowsum = np.sum(new[i])
...             colsum = np.sum(new[:,j])
...             next[i][j] = rowsum+colsum-val-val
...     return next
... 
>>> n = 8
>>> kernel = np.arange(n)==0
>>> kernel = np.bitwise_xor.outer(kernel, kernel)
>>> 
>>> data = np.random.random((n, n))
>>> 
>>> np.allclose(ifftn(fftn(data) * fftn(kernel)).real, iterate(data))
True

多次迭代与在傅里叶域中获取内核的功能相同:

>>> np.allclose(ifftn(fftn(data) * fftn(kernel)**3).real, iterate(iterate(iterate(data))))
True

让我们看看傅立叶空间中的内核:

>>> fftn(kernel).real
array([[14.,  6.,  6.,  6.,  6.,  6.,  6.,  6.],
       [ 6., -2., -2., -2., -2., -2., -2., -2.],
       [ 6., -2., -2., -2., -2., -2., -2., -2.],
       [ 6., -2., -2., -2., -2., -2., -2., -2.],
       [ 6., -2., -2., -2., -2., -2., -2., -2.],
       [ 6., -2., -2., -2., -2., -2., -2., -2.],
       [ 6., -2., -2., -2., -2., -2., -2., -2.],
       [ 6., -2., -2., -2., -2., -2., -2., -2.]])

正如我们所看到的,左上角有一个显性条目,即恒定模式,即转换后的全局偏移。 显然,如果我们掌握这个FT内核的强大功能,那么恒定模式将变得越来越占主导地位。这也适用于具有此功率的FT数据产品,因此后重变换元素之间的相对差异将变得越来越小。

您可以尝试通过全局平均减法来解决这个问题。很容易验证FT内核的功能是否会收敛到原始内核的标量倍数:

>>> np.round((fftn(kernel-kernel.mean()).real)**100 / 10.**75, 20)
array([[  0.  , 653.32, 653.32, 653.32, 653.32, 653.32, 653.32, 653.32],
       [653.32,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ],
       [653.32,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ],
       [653.32,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ],
       [653.32,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ],
       [653.32,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ],
       [653.32,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ],
       [653.32,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ,   0.  ]])

由于一切都是真实的,这背面的FT与我们已经看到的前向FT相同。因此,使用平均减法进行迭代会将标量因子收敛到使用原始内核的FT的循环卷积。