Как преобразовать равномерное распределение (поскольку большинство генераторов случайных чисел производят, например, между 0.0 и 1.0) в нормальное распределение? Что, если я хочу среднего и стандартного отклонения от моего выбора?Преобразование равномерного распределения в нормальное распределение
ответ
Ziggurat algorithm довольно эффективен для этого, хотя Box-Muller transform проще реализовать с нуля (и не безумно медленно).
Обычные предупреждения о линейных конгруэнтных генераторах применяются к обоим этим методам, поэтому используйте достойный генератор подрыва. Приветствия. – dmckee 2008-09-16 19:02:04
Например, Mersenee Twister, или у вас есть другие предложения? – 2008-09-18 21:19:28
Я бы использовал Box-Muller. Две вещи по этому поводу:
- Вы в конечном итоге с двумя значениями на итерации
Как правило, вы кэшировать одно значение и возвращаете другое. При следующем вызове образца вы возвращаете кешированное значение. - Box-Muller дает Z-счет
Вы должны затем масштабировать Z-балл стандартным отклонением и добавить среднее значение, чтобы получить полное значение в нормальном распределении.
Как вы масштабируете Z-счет? – Terhorst 2008-09-16 19:18:29
scaled = mean + stdDev * zScore // дает вам нормальный (средний, stdDev^2) – yoyoyoyosef 2008-10-20 14:31:56
Стандартный модуль случайных Python библиотека имеет то, что вы хотите:
normalvariate (мю, сигма)
Нормальное распределение. mu - среднее значение, а сигма - стандартное отклонение.
Для самого алгоритма взгляните на функцию в random.py в библиотеке Python.
К сожалению, библиотека python использует Kinderman, A.J. и Monahan, J.F., «Компьютерное генерирование случайных величин с использованием отношения однородных отклонений», ACM Trans Math Software, 3, (1977), pp. 257-260. Это использует две равномерные случайные величины для генерации нормального значения, а не для одного, поэтому неясно, как использовать его в качестве отображения, которое требуется OP. – Ian 2011-04-04 17:27:41
function distRandom(){
do{
x=random(DISTRIBUTION_DOMAIN);
}while(random(DISTRIBUTION_RANGE)>=distributionFunction(x));
return x;
}
Не гарантируется возврат, правда? ;-) – 2008-10-15 02:43:13
он возвращается почти наверняка. – 2010-07-16 13:19:49
Случайные числа слишком важны, чтобы их оставили на волю случая. – 2011-01-03 05:59:15
Изменение распределения любой функции к другой предполагает использование обратной функции, которую вы хотите.
Другими словами, если вы стремитесь к определенной вероятностной функции p (x), вы получаете распределение, интегрируя по ней -> d (x) = integ (p (x)) и используя ее обратное: Inv (d (Икс)). Теперь используйте случайную вероятностную функцию (которая имеет равномерное распределение) и передают результат через функцию Inv (d (x)). Вы должны получить случайные значения, отличные от дистрибутива, в соответствии с выбранной вами функцией.
Это общий математический подход. Используя его, вы можете выбрать любую вероятность или функцию распределения, если у вас есть обратное или хорошее обратное приближение.
Надеюсь, это помогло и спасибо за небольшое замечание об использовании распределения, а не о самой вероятности.
Используйте центральную предельную теорему wikipedia entrymathworld entry в ваших интересах.
Сформировать п равномерно распределенных чисел, обобщать их, вычитать п * 0,5 и у вас есть выход приблизительно нормального распределения со средним равным 0 и дисперсией, равной (1/12) * (1/sqrt(N))
(см wikipedia on uniform distributions для этого последнего)
n = 10 дает вам что-то наполовину приличное быстро.Если вы хотите, чтобы что-то более чем наполовину пошло для решения tylers (как указано в wikipedia entry on normal distributions)
Вот реализация javascript с использованием полярной формы преобразования Box-Muller.
/*
* Returns member of set with a given mean and standard deviation
* mean: mean
* standard deviation: std_dev
*/
function createMemberInNormalDistribution(mean,std_dev){
return mean + (gaussRandom()*std_dev);
}
/*
* Returns random number in normal distribution centering on 0.
* ~95% of numbers returned should fall between -2 and 2
* ie within two standard deviations
*/
function gaussRandom() {
var u = 2*Math.random()-1;
var v = 2*Math.random()-1;
var r = u*u + v*v;
/*if outside interval [0,1] start over*/
if(r == 0 || r >= 1) return gaussRandom();
var c = Math.sqrt(-2*Math.log(r)/r);
return u*c;
/* todo: optimize this algorithm by caching (v*c)
* and returning next time gaussRandom() is called.
* left out for simplicity */
}
Есть много методов:
- ли не использовать Box Muller. Особенно, если вы рисуете много гауссовских чисел. Box Muller дает результат, который зажат между -6 и 6 (при условии двойной точности. Вещи ухудшаются с поплавками). И это действительно менее эффективно, чем другие доступные методы.
- Ziggurat - это хорошо, но вам нужен поиск в таблице (и некоторые настройки для конкретной платформы из-за проблем с размером кеша)
- Соотношение мундиров является моим фаворитом, всего несколько добавлений/умножений и журнал 1/50th из время (например, look there).
- Инвертирование CDF является эффективным (и упускается из виду, почему?), У вас есть быстрая реализация его доступна, если вы ищете Google. Это обязательно для Квази-случайных чисел.
где R 1, R 2 представляют собой случайные равномерные числа:
нормальное распределение, с SD 1: SQRT (-2 * журнал (R1)) * соз (2 * пи * R 2)
Это точно ... не нужно делать все эти медленные петли!
Я хочу попробовать это в EXCEL: =norminv(rand();0;1)
. Это будет производить случайные числа, которые должны нормально распределяться с нулевым средним значением и объединяться с дисперсией. «0» может поставляться с любым значением, так что числа будут иметь желаемое среднее значение, и, изменив «1», вы получите дисперсию, равную квадрату вашего ввода.
Например: =norminv(rand();50;3)
уступит нормально распределенных чисел со средним значением = 50 ДИСПЕРСИИ = 9.
Приближение:
function rnd_snd() {
return (Math.random()*2-1)+(Math.random()*2-1)+(Math.random()*2-1);
}
Q Каким образом можно преобразовать равномерное распределение (поскольку большинство генераторов случайных чисел производят, например, между 0.0 и 1.0), в нормальное распределение?
Для реализации программного обеспечения я знаю пару случайных имен генераторов, которые дают вам псевдо равномерную случайную последовательность в [0,1] (Вихрь Мерсенна, линейный Congruate генератор). Назовем это U (x)
Существует математическая область, которая называется теорией вероятностей. Первое: если вы хотите модель r.v. с интегральным распределением F, то вы можете попробовать только оценить F^-1 (U (x)). В п.теории доказано, что такой р.в. будет иметь интегральное распределение F.
Шаг 2 может быть применен для генерации r.v. ~ F без использования каких-либо методов подсчета, когда F^-1 можно получить аналитически без проблем. (например, exp.распределение)
Чтобы моделировать нормальное распределение, вы можете cacculate y1 * cos (y2), где y1 ~ равномерно в [0,2pi]. и y2 является выпуклым распределением.
В: Что, если я хочу иметь среднее и стандартное отклонение от моего выбора?
Вы можете вычислить сигма * N (0,1) + m.
Можно показать, что такое перемещение и масштабирование приводит к N (м, SIGMA)
Это кажется невероятным, что я мог бы что-то добавить к этому после восьми лет, но в случае Java я хотел бы отметить читателей к методу Random.nextGaussian(), который генерирует распределение Гаусса со средним 0.0 и стандартным отклонением 1.0 для вас.
Простое добавление и/или умножение изменят среднее и стандартное отклонение в соответствии с вашими потребностями.
Это реализация Matlab с использованием полярной формы Box-Muller трансформации:
Функция randn_box_muller.m
:
function [values] = randn_box_muller(n, mean, std_dev)
if nargin == 1
mean = 0;
std_dev = 1;
end
r = gaussRandomN(n);
values = r.*std_dev - mean;
end
function [values] = gaussRandomN(n)
[u, v, r] = gaussRandomNValid(n);
c = sqrt(-2*log(r)./r);
values = u.*c;
end
function [u, v, r] = gaussRandomNValid(n)
r = zeros(n, 1);
u = zeros(n, 1);
v = zeros(n, 1);
filter = r==0 | r>=1;
% if outside interval [0,1] start over
while n ~= 0
u(filter) = 2*rand(n, 1)-1;
v(filter) = 2*rand(n, 1)-1;
r(filter) = u(filter).*u(filter) + v(filter).*v(filter);
filter = r==0 | r>=1;
n = size(r(filter),1);
end
end
И вызова histfit(randn_box_muller(10000000),100);
это результат:
Очевидно, что это на самом деле неэффективен по сравнению с встроенным Matlab randn.
- 1. поворота равномерного распределения в нормальное распределение
- 2. Преобразование равномерного распределения в распределение Пуассона
- 3. распределения Пуассона или нормальное распределение
- 4. Преобразование чисел в нормальное распределение
- 5. WinBUGS - Определение поэтапного равномерного распределения
- 6. Две переменные нормальное распределение
- 7. Случайное многомерное нормальное распределение
- 8. алгоритм отклонения приема C++ нормальное распределение
- 9. Невозможно вычислить нормальное распределение
- 10. Tensorflow: Нормальное распределение радиовещательной
- 11. batch нормальное распределение тест
- 12. Алгоритм равномерного распределения элементов в матрице
- 13. Установите данные в нормальное распределение
- 14. Нормальное распределение в oracle
- 15. Выборка из огромного равномерного распределения в Python
- 16. R имитировать обратное нормальное распределение
- 17. Рассчитать нормальное распределение Android-студия
- 18. Преобразование неравномерного распределения в равномерное распределение
- 19. Генерация равномерного распределения с использованием Math.random()
- 20. Как вычислить кумулятивное нормальное распределение в Python
- 21. Стандартное нормальное распределение с массивами
- 22. Matlab 3D поверхность нормальное распределение
- 23. Matlab - Как перекос нормальное распределение
- 24. Установить распределение Пуассона в нормальное распределение
- 25. Получение равномерного распределения вероятности с ограниченными средствами
- 26. Измерение равномерного распределения дискретных значений
- 27. uniform_real_distribution не дает равномерного распределения
- 28. нормальное распределение; iron python
- 29. Python - рассчитать нормальное распределение
- 30. Python подходит для равномерного распределения
У вас есть языковая спецификация, или это просто общий алгоритм? – 2008-09-16 19:08:26
Общий алгоритмный вопрос. Мне все равно, на каком языке. Но я бы предпочел, чтобы ответ не зависел от конкретной функциональности, которую предоставляет только этот язык. – Terhorst 2008-09-16 19:12:23