Можно ли воспроизвести randn() MATLAB с помощью NumPy?

Интересно, можно ли точно воспроизвести всю последовательность randn() MATLAB с помощью NumPy. Я закодировал свою собственную процедуру с помощью Python/Numpy, и она дает мне немного отличные результаты от кода MATLAB, который сделал кто-то другой, и мне трудно понять, откуда она берется, из-за разных случайных рисунков.

Я нашел значение numpy.random.seed, которое дает одно и то же число для первого розыгрыша, но со второго розыгрыша и далее оно совершенно другое. Я делаю многомерные нормальные отрисовки около 20 000 раз, поэтому я не хочу просто сохранять отрисовки в Matlab и читать их на Python.


person joon    schedule 15.09.2010    source источник
comment
Что не так с numpy.random.randn(...)? Он должен делать именно то, что вам нужно, если только вы не беспокоитесь о создании точно той же самой последовательности чисел с заданным начальным числом... (Неважно, очевидно, это то, что вы пытаетесь сделать, теперь, когда Я перечитал вопрос.Из смутного любопытства, а зачем вам, чтобы точная последовательность была одинаковой?)   -  person Joe Kington    schedule 16.09.2010
comment
Что вы имеете в виду, код MATLAB, который сделал кто-то другой? randn — стандартная функция MATLAB. Я искренне надеюсь, что вы не используете какую-то пользовательскую функцию из кучи мусора, которой является FEX.   -  person Nick T    schedule 16.09.2010
comment
В этом нет ничего плохого, мне нужно сгенерировать точно такую ​​же последовательность чисел с заданным начальным числом. Как я уже сказал, моя процедура с NumPy дает мне результат, отличный от кода MATLAB, и я не могу его отладить из-за разницы в случайных числах. Я не могу определить, где это пошло не так.   -  person joon    schedule 16.09.2010
comment
@Nict Т, конечно, нет. Я запускаю некоторую байесовскую модель, и мой код дает мне оценки, отличные от кода MATLAB. Я почти уверен, что код MATLAB правильный, поэтому я пытаюсь отладить свой код, но из-за разных случайных отрисовок я не могу определить, где отличаются вычисления.   -  person joon    schedule 16.09.2010
comment
Все еще не отвечая на ваш вопрос, но сохранение/загрузка не так уж плохо. В SciPy есть транслятор файлов MATLAB .mat, так что вы можете сбросить свое рабочее пространство MATLAB в файл и довольно легко перенести его с помощью SciPy.io.mio scipy.org/doc/api_docs/SciPy.io.mio.html   -  person Nick T    schedule 16.09.2010
comment
Да, я думаю, я должен это сделать. Для полного результата мне нужно около 10 000 000 розыгрышей, но я думаю, для теста я могу просто сохранить небольшое количество розыгрышей и смогу увидеть, где расчет отличается. Спасибо!   -  person joon    schedule 16.09.2010
comment
Рад сообщить, что мне удалось воспроизвести результаты. Закончилось сохранением/загрузкой 100 мл розыгрышей. Спасибо.   -  person joon    schedule 16.09.2010


Ответы (3)


Пользователь спросил, можно ли воспроизвести вывод randn() Matlab, а не rand. Мне не удалось настроить алгоритм или начальное число для воспроизведения точного числа для randn(), но приведенное ниже решение работает для меня.

В Matlab: сгенерируйте нормально распределенные случайные числа следующим образом:

rng(1);
norminv(rand(1,5),0,1)
ans = 
   -0.2095    0.5838   -3.6849   -0.5177   -1.0504

В Python: сгенерируйте нормально распределенные случайные числа следующим образом:

import numpy as np
from scipy.stats import norm
np.random.seed(1)
norm.ppf(np.random.rand(1,5))
array([[-0.2095,  0.5838, -3.6849, -0.5177,-1.0504]])

Очень удобно иметь функции, которые могут воспроизводить одинаковые случайные числа при переходе с Matlab на Python или наоборот.

person Jens Munk    schedule 24.04.2016

Если вы установите генератор случайных чисел на одно и то же начальное число, теоретически он будет создавать те же числа, то есть в Matlab. Я не совсем уверен, как это лучше всего сделать, но, похоже, это работает, в Matlab выполните:

rand('twister', 5489)

и соответствующий в numy:

np.random.seed(5489)

Для (повторной) инициализации ваших генераторов случайных чисел. Это дает мне те же числа для rand() и np.random.random(), но не для randn, я не уверен, что для этого есть простой метод.

В более новых версиях Matlab вы, вероятно, можете настроить RandStream с теми же свойствами, что и numpy, для более старых вы можете воспроизвести randn numpy в Matlab (или наоборот). Numpy использует полярную форму для создания однородных чисел из np.random.random() (второй алгоритм, приведенный здесь: http://www.taygeta.com/random/gaussian.html). Вы можете просто написать этот алгоритм в Matlab, чтобы создать те же числа randn, что и numpy, из функции rand в Matlab.

Если вам не нужно огромное количество случайных чисел, просто сохраните их в .mat и прочитайте с scipy.io...

person seberg    schedule 22.09.2010
comment
Большое спасибо за ваш ответ. Я обязательно попробую. - person joon; 29.09.2010

Просто хотел уточнить использование метода твистера / заполнения: MATLAB и numpy генерируют одну и ту же последовательность, используя это заполнение, но по-разному заполняют их в матрицах.

MATLAB заполняет матрицу вниз по столбцам, а python перемещается вниз по строкам. Итак, чтобы получить одинаковые матрицы в обоих, вам нужно транспонировать:

МАТЛАБ:

rand('twister', 1337);
A = rand(3,5)
A = 
 Columns 1 through 2
   0.262024675015582   0.459316887214567
   0.158683972154466   0.321000540520167
   0.278126519494360   0.518392820597537
  Columns 3 through 4
   0.261942925565145   0.115274226683149
   0.976085284877434   0.386275068634359
   0.732814552690482   0.628501179539712
  Column 5
   0.125057926335599
   0.983548605143641
   0.443224868645128

питон:

import numpy as np
np.random.seed(1337)
A = np.random.random((5,3))
A.T
array([[ 0.26202468,  0.45931689,  0.26194293,  0.11527423,  0.12505793],
       [ 0.15868397,  0.32100054,  0.97608528,  0.38627507,  0.98354861],
       [ 0.27812652,  0.51839282,  0.73281455,  0.62850118,  0.44322487]])

Примечание. Я также разместил этот ответ на этот аналогичный вопрос: Сравнение кода Matlab и Numpy, использующего генерацию случайных чисел

person Diego    schedule 15.05.2014