Генерировать случайное число с заданной вероятностью matlab
Я хочу создать случайное число с заданной вероятностью, но я не уверен, как:
Мне нужно число от 1 до 3
num = ceil(rand*3);
но мне нужны разные значения, чтобы иметь разные вероятности генерации, например.
0.5 chance of 1
0.1 chance of 2
0.4 chance of 3
Я уверен, что это просто, но я не могу придумать, как это сделать.
Ответы
Ответ 1
Простое решение состоит в том, чтобы сгенерировать число с равномерным распределением (используя rand
) и немного манипулировать им:
r = rand;
prob = [0.5, 0.1, 0.4];
x = sum(r >= cumsum([0, prob]));
или в одном слое:
x = sum(rand >= cumsum([0, 0.5, 0.1, 0.4]));
Объяснение
Здесь r
- равномерно распределенное случайное число между 0 и 1. Чтобы создать целое число от 1 до 3, трюк состоит в том, чтобы разделить диапазон [0, 1] на 3 сегмента, где длина каждого сегмента пропорциональна его соответствующей вероятности. В вашем случае у вас будет:
- Сегмент [0, 0.5), соответствующий номеру 1.
- Сегмент [0,5, 0,6], соответствующий номеру 2.
- Сегмент [0,6, 1], соответствующий номеру 3.
Вероятность r
, попадающая в любой из сегментов, пропорциональна вероятностям, которые вы хотите для каждого числа. sum(r >= cumsum([0, prob]))
- просто причудливый способ сопоставления целочисленного числа с одним из сегментов.
Расширение
Если вы заинтересованы в создании вектора/матрицы случайных чисел, вы можете использовать цикл или arrayfun
:
r = rand(3); % # Any size you want
x = arrayfun(@(z)sum(z >= cumsum([0, prob])), r);
Конечно, есть также векторизованное решение, я просто слишком ленив, чтобы написать его.
Ответ 2
>> c = cumsum([0.5, 0.1, 0.4]);
>> r = rand(1e5, 1);
>> x = arrayfun(@(x) find(x <= c, 1, 'first'), r);
>> h = hist(x, 1:3)
h =
49953 10047 40000
x
распределяется по желанию.
Ответ 3
Несколько более общее решение было бы:
r=rand;
prob=[.5,.1,.4];
prob=cumsum(prob);
value=[1,2,3]; %values corresponding to the probabilities
ind=find(r<=prob,1,'first');
x=value(ind)
Ответ 4
Ответы до сих пор верны, но медленны для больших входов: O (m * n), где n - количество значений, а m - количество случайных выборок. Вот версия O (m * log (n)), которая использует монотонность результата cumsum
и двоичный поиск, используемый в histc
:
% assume n = numel(prob) is large and sum(prob) == 1
r = rand(m,1);
[~,x] = histc(r,cumsum([0,prob]));
Соответствующий поток форума Matlab Central
Ответ 5
с помощью функции randsample
из "Статистика" и "Machine Learning Toolbox" вы можете генерировать случайные числа с заданной вероятностной массовой функцией (pmf):
pmf = [0.5, 0.1, 0.4];
population = 1:3;
sample_size = 1;
random_number = randsample(population,sample_size,true,pmf);
Я думаю, что это самый простой способ.