Transformasi dirichlet array dengan range [-1,1] di numpy

Sep 15 2020

Sebuah vektor acak sampel dari distribusi Dirichlet berisi nilai-nilai yang termasuk dalam domain [0,1] dan jumlahnya 1 . Secara numpy dapat diprogram seperti ini untuk ukuran vektor 5:

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

Sebagai gantinya, saya ingin vektor acak yang berisi nilai yang [-1,1] dan berjumlah 1 , yang saya diberitahu dapat dicapai dengan mengubah xvektor yang dihasilkan Dirichlet sebagaiy = 2x -1

Di bawah ini adalah upaya transformasi ini. Namun skrip tidak berfungsi dengan baik karena ytidak berjumlah 1 sesuai kebutuhan. Bagaimana itu bisa diperbaiki, atau mungkinkah itu y = 2x -1tidak melakukan apa yang mereka katakan?

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

keluaran yang mana:

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

Jawaban

1 Charlie Nov 03 2020 at 04:19

Coba y=1/(dimension/3)-2*x. Itu berhasil untuk saya.

3 mathfux Sep 15 2020 at 23:11

Masalahnya adalah bahwa interval [0, 1]dapat memiliki satu dan satu-satunya peta linier ke interval [-1, 1]yang sebenarnya adalah sebuah peta x -> 2x - 1. Tetapi itu tidak dapat menjamin bahwa jumlah Anda akan stabil. Alasannya bisa dilihat dalam pengamatan ini:

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

Seperti yang Anda lihat, jumlah terakhir tidak berkurang 1 seperti yang diharapkan. Ini sebenarnya berkurang 5 karena setiap dari 5 item berkurang 1.

1 SextusEmpiricus Sep 16 2020 at 07:09

Seperti yang dijelaskan oleh salah satu jawaban di stats.stackexchange: hanya ada satu cara agar Anda dapat memetakan variabel dari distribusi Dirichlet ke [-1,1] sambil mempertahankan jumlahnya sama dengan 1. Ini adalah saat dimensinya 3 dan kapan Anda menggunakan 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))

yang mencetak:

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