Générer un nombre aléatoire avec une probabilité donnée matlab

je veux générer un nombre aléatoire avec une probabilité donnée mais je ne sais pas comment:

j'ai besoin d'un nombre entre 1 et 3

num = ceil(rand*3);

mais j'ai besoin de valeurs différentes pour différentes probabilités de générer par exemple.

0.5 chance of 1
0.1 chance of 2
0.4 chance of 3

je suis sûr que c'est simple mais je ne peux pas penser à la façon de le faire.

23
demandé sur Eamonn McEvoy 2012-12-17 16:20:39

5 réponses

la solution simple est de générer un nombre avec une distribution uniforme (en utilisant rand), et le manipuler un peu:

r = rand;
prob = [0.5, 0.1, 0.4];
x = sum(r >= cumsum([0, prob]));

ou dans un one-liner:

x = sum(rand >= cumsum([0, 0.5, 0.1, 0.4]));

Explication

Ici r est un chiffre aléatoire uniformément distribué entre 0 et 1. Pour générer un nombre entier entre 1 et 3, le truc est de diviser l'intervalle [0, 1] en 3 segments, où la longueur de chaque segment est proportionnelle à son correspondant probabilité. Dans votre cas, vous devez:

  • Segment [0, 0.5), correspondant au numéro 1.
  • Segment [0.5, 0.6), correspondant au numéro 2.
  • Segment [0.6, 1], correspondant au numéro 3.

La probabilité de r à l'intérieur de l'un des segments est proportionnelle aux probabilités que vous voulez pour chaque nombre. sum(r >= cumsum([0, prob])) est juste une façon élégante de mappage d'un nombre entier à l'un des segment.

Extension

si vous êtes intéressé à créer un vecteur / matrice de nombres aléatoires, vous pouvez utiliser une boucle ou arrayfun:

r = rand(3); % # Any size you want
x = arrayfun(@(z)sum(z >= cumsum([0, prob])), r);

bien sûr, il y a aussi une solution vectorisée, je suis juste trop paresseux pour l'écrire.

44
répondu Eitan T 2015-01-12 16:58:05

Les réponses sont correctes, mais lent pour les grandes entrées: O(m*n) où n est le nombre de valeurs et m est le nombre d'échantillons aléatoires. Voici une version O (M * log (n)) qui tire profit de la monotonie de la cumsum résultat et la recherche binaire utilisée dans histc:

% assume n = numel(prob) is large and sum(prob) == 1
r = rand(m,1);
[~,x] = histc(r,cumsum([0,prob]));

Forum Central Matlab pertinent

6
répondu Alec Jacobson 2013-12-04 12:37:11
>> 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 distribué comme souhaité.

5
répondu Serg 2012-12-17 18:54:21

une solution un peu plus générale serait:

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
répondu user1860611 2012-12-17 16:24:13

en utilisant randsample function boîte à outils de statistiques et D'apprentissage automatique, vous pouvez générer des nombres aléatoires avec la fonction de masse de probabilité (pmf) spécifiée:

pmf = [0.5, 0.1, 0.4];
population = 1:3;
sample_size = 1;

random_number = randsample(population,sample_size,true,pmf);

je pense que c'est la méthode la plus simple.

3
répondu MohammadReza 2016-10-30 14:50:48