numpy 中范围为 [-1,1] 的变换 Dirichlet 数组

Transformed Dirichlet array with range [-1,1] in numpy

从 Dirichlet 分布采样的随机向量包含落在 域 [0,1] 中的值,它们总和为 1。在 numpy 中,它可以这样编程,向量大小为 5:

x = numpy.random.dirichlet(np.ones(5))

相反,我想要一个随机向量,其中包含 [-1,1] 和总和为 1 的值,I was told 可以通过转换来实现Dirichlet 生成的 x 向量为 y = 2x -1

下面是这种改造的尝试。然而,该脚本无法正常工作,因为 y 未根据需要求和为 1。怎么解决,还是y = 2x -1没有按他们说的做?

x = numpy.random.dirichlet(np.ones(5))
y = 2*x -1
print(x, np.sum(x))
print(y, np.sum(y))

输出:

[0.0209344  0.44791586 0.21002354 0.04107336 0.28005284] 1.0
[-0.9581312  -0.10416828 -0.57995291 -0.91785327 -0.43989433] -3.0000000000000004

问题是区间 [0, 1] 可以有一个也是唯一一个到区间 [-1, 1] 的线性映射,它实际上是一个映射 x -> 2x - 1。但是不能保证你的金额稳定。从这些观察中可以看出一个原因:

np.sum(x)
0.9999999999999999
np.sum(2*x)
1.9999999999999998
np.sum(2*x-1)
-3.0

如您所见,最后的总和并没有像预期的那样减少 1。它实际上减少了5,因为5个项目中的每一个都减少了1。

正如 stats.stackexchange 上的一个答案所解释的那样:只有一种方法可以将 Dirichlet 分布的变量映射到 [-1,1] 保持总和等于 1。这是当维度为 3 且使用 y=1-2x

import numpy
numpy.random.seed(seed = 1)
x = numpy.random.dirichlet(alpha = numpy.ones(3), size = 1)
y = 1-2*x
print(x, numpy.sum(x))
print(y, numpy.sum(y))

打印:

[[2.97492728e-01 7.02444212e-01 6.30601451e-05]] 1.0000000000000002
[[0.40501454 -0.40488842  0.99987388]] 0.9999999999999998

尝试y=1/(dimension/3)-2*x。这对我有用。