Matriz de Dirichlet transformada com intervalo [-1,1] em numpy
Um vetor aleatório amostrado da distribuição de Dirichlet contém valores que caem no domínio [0,1] e somam 1 . Em numpy, ele pode ser programado assim para um tamanho de vetor de 5:
x = numpy.random.dirichlet(np.ones(5))
Em vez disso, eu gostaria de um vetor aleatório que contém valores que são [-1,1] e somam 1 , que me disseram que pode ser alcançado transformando o xvetor gerado por Dirichlet comoy = 2x -1
Abaixo está uma tentativa dessa transformação. O script não funciona corretamente, no entanto, porque ynão soma 1 conforme necessário. Como pode ser consertado, ou será que y = 2x -1não faz o que eles disseram?
x = numpy.random.dirichlet(np.ones(5))
y = 2*x -1
print(x, np.sum(x))
print(y, np.sum(y))
que produz:
[0.0209344 0.44791586 0.21002354 0.04107336 0.28005284] 1.0
[-0.9581312 -0.10416828 -0.57995291 -0.91785327 -0.43989433] -3.0000000000000004
Respostas
Experimente y=1/(dimension/3)-2*x. Isso funcionou para mim.
O fato é que o intervalo [0, 1]pode ter um e o único mapa linear para intervalo, [-1, 1]que na verdade é um mapa x -> 2x - 1. Mas não pode garantir que sua soma será estável. Um motivo pode ser visto nestas observações:
np.sum(x)
0.9999999999999999
np.sum(2*x)
1.9999999999999998
np.sum(2*x-1)
-3.0
Como você pode ver, a última soma não diminui em 1 conforme o esperado. Na verdade, diminui em 5 porque cada um dos 5 itens diminuiu em 1.
Como uma das respostas em stats.stackexchange explica: só há uma maneira de mapear as variáveis de uma distribuição de Dirichlet para [-1,1] , mantendo a soma igual a 1. Isso ocorre quando a dimensão é 3 e quando você usa 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))
que imprime:
[[2.97492728e-01 7.02444212e-01 6.30601451e-05]] 1.0000000000000002
[[0.40501454 -0.40488842 0.99987388]] 0.9999999999999998