В этом SAStips'е рассказывает про нюансы выбора начального значения для генератора случайных чисел.

На прошлой неделе мне задали простой вопрос: "Как выбрать начальное значение для функций генерации случайных чисел в SAS?" Ответ может вас удивить: используйте любое начальное значение, которое вам нравится. Для хорошо спроектированного генератора случайных чисел каждое значение, вероятно, порождает поток случайных чисел, и различные потоки можно рассматривать как статистически эквивалентные.

Случайное означает случайное

Поясню: я говорю об использовании начального значения для инициализации современного высококачественного генератора псевдослучайных чисел (RNG). Например, в SAS можно использовать STREAMINIT для инициализации алгоритма вихря Мерсенна, который используется функцией RAND. Если вы все еще пользуетесь старыми функциями RANUNI или RANNOR, ознакомьтесь со статьей "Шесть причин отказаться от функции RANUNI для генерации случайных чисел."

Начальное значение задает конкретный поток из набора возможных случайных числовых потоков. При указании начального значения SAS генерирует одинаковый набор псевдослучайных чисел при каждом запуске программы. Однако нет никаких оснований предпочитать один поток другому. Поток для начального значения 12345 так же случаен, как поток для девятизначного простого числа 937162211.

Некоторые видят число 937162211 и считают, что оно выглядит "более случайным", чем 12345. Затем они предполагают, что поток случайных чисел, полученный в результате вызова CALL STREAMINIT (937162211), является "более случайным", чем поток, полученный в результате вызова CALL STREAMINIT (12345). Нет, случайное значит случайное. В современных генераторах псевдослучайных чисел потоки для разных начальных значений должны иметь сходные статистические свойства. Кроме того, многие генераторы используют начальное число в двоичной системе, и число (12345)10 = (11000000111001)2 выглядит довольно случайным! На самом деле, если не брать числа, являющиеся степенью двойки, то двоичные представления большинства десятичных чисел "выглядят случайными".

Инициализация: трудно для исследователей, легко для пользователей

Исследователи, специализирующиеся на генераторах случайных чисел, могут назвать мою модель слишком упрощенной. Было написано множество статей о том, как взять 32-битное целое число и использовать эту информацию для инициализации генератора случайных чисел, внутреннее состояние которого содержит более 32 бит. Были случаи, когда генератор случайных чисел был опубликован, но позже авторы изменили процедуру инициализации, поскольку определенные начальные значения не приводили к достаточно случайным потокам. Было много дискуссий о том, как создать алгоритм инициализации начальных чисел, который легко вызвать и который почти всегда приводит к высококачественному потоку случайных чисел.

Это непростая задача, но, к счастью, исследователи разработали такие способы инициализации потока из начального значения, при которых существует высокая вероятность того, что поток будет иметь отличные статистические свойства. Соответствующий вопрос для многих программистов SAS выглядит так: "Можно ли использовать 12345 или мой номер телефона в качестве начального значения или всегда нужно вводить длинную девятизначную последовательность?" Мой ответ заключается в том, что нет никаких оснований предпочитать длинные начальные значения простым, таким как ваш номер телефона, день рождения или первые несколько цифр числа пи.

Выбор случайного начального значения

Если вы решительно настаиваете на использовании "случайного начального значения", SAS может помочь. Если вызвать STREAMINIT со значением 0, то для создания начального значения при вызове функции RAND SAS будет использовать дату, время и, возможно, другую информацию. SAS помещает начальное значение в переменную SYSRANDOM. Это значение можно вывести с помощью %PUT:

data _null_;
call streaminit(0);   /* generate seed from system clock */
x = rand("uniform");
run;
%put &=SYSRANDOM;
SYSRANDOM=1971603567

Каждый раз при запуске программы вы получите новое начальное значение, которое можно использовать в качестве начального значения для следующей программы.

Второй способ заключается в использовании функции RAND для создания случайного целого числа от 1 до 231-1 (это диапазон действительных начальных значений для генератора случайных чисел по алгоритму вихря Мерсенна в SAS 9.4m4). Следующая программа создает случайное начальное значение:

data _null_;
call streaminit(0);
seed = ceil( (2**31 - 1)*rand("uniform") ); 
put seed=;
run;
seed=1734176512

Оба этих метода создают начальное значение. Однако случайно сгенерированное начальное значение не приносит никакой пользы. Для современного высококачественного генератора псевдослучайных чисел поток должен обладать хорошими статистическими свойствами независимо от начального значения. Использование случайного начального значения не делает поток "более случайным"

Оригинал статьи на английском