Keyfi bir kesikli dağılıma göre sayılar nasıl oluşturulur?


28

Rasgele kesikli dağılıma dayalı sayıları nasıl oluştururum?

Örneğin, oluşturmak istediğim bir dizi numara var. Diyelim ki 1-3 ile etiketlenmişler.

% 1: 4,% 2: 50,% 3: 46

Temel olarak, yüzdeler, rasgele sayı üretecinin çıktısında görünecekleri olasılıktır. [0, 1] aralığında tekdüze bir dağılım oluşturacak bir pesudorandom sayı üreteci var. Bunu yapmanın bir yolu var mı?

Kaç elemente sahip olabileceğim konusunda bir sınır yok, ancak% 100'e kadar ekleyecek.


2
Sorunuz buysa, başlığında "... rasgele ayrık dağılımlar" belirtmeyi önerebilirim. Sürekli durum farklı.
David M Kaplan

3
Genel bir yöntem, bu örnekte olacak olan kümülatif olasılıklar listesinde ikili bir arama . Ortalama olarak bu, olay başına prob alır . Olasılık çok düşük değilse , de eşit aralıklarla yerleştirilmiş değerlerin bir vektörünü oluşturarak ve (bir hesaplama öncesi aşamada) her değere bir sonuç atayarak performansını elde edebilirsiniz . Örneğin, bu örnekte vektörü ( 2 ve ) oluşturabilirsiniz. Bir üniforma oluşturun, 100 ile çarpın ve bu vektöre dizin ekleyin: bitti. günlük ( n ) / 2 O ( 1 ) [ 0 , 1 ] ( 1 , 1 , 1 , 1 , 2 , ... , 2 , 3 , ... , 3 ) 50 46(0,0.04,0.54,1.0)log(n)/2O(1)[0,1](1,1,1,1,2,,2,3,,3)5046
whuber

Ayrıca bakınız burada
Glen_b -Reinstate Monica

Bu "burada" bağlantısı aslında bu soruya bağlanıyor, @Glen_b ... copy-n-paste hatası?
buruzaemon

@ buruzaemon teşekkürler evet bu bir hataydı; Düzeltdim.
Glen_b -Reinstate Monica,

Yanıtlar:


26

Kesikli bir dağılımdan örnekleme için en iyi algoritmalardan biri takma yöntemdir .

Alias ​​yöntemi (verimli bir şekilde), dikdörtgeni olasılıklarla orantılı alanlara bölmek için iki boyutlu bir veri yapısını önceden oluşturur.

şekil

Başvurulan alandan bu şematikte, birim yükseklikte bir dikdörtgen, renkle farklılaştırıldığı gibi, , , ve oranlarında dört çeşit bölgeye ayrılmıştır . Bu olasılıklarla kesikli bir dağılımdan tekrar tekrar numune almak için. Dikey şeritler sabit (birim) genişliğe sahiptir. Her biri bir veya iki parçaya bölünmüştür. Parçaların kimlikleri ve dikey bölümlerin yerleri sütun dizini üzerinden erişilebilen tablolarda saklanır.1 / 3 1 / 12 1 / 121/21/31/121/12

Tablo, sadece iki bağımsız tekdüze değer oluşturma ve hesaplama gerektiren iki basit adımda (her koordinat için bir tane) örneklenebilir . Bu, buradaki diğer cevaplarda tarif edildiği gibi ayrık CDF'yi tersine çevirmek için gereken hesaplamasını geliştirir.0 ( log ( n ) )O(1)O(log(n))


2
Bu algoritma sadece olasılıklar hesaplanması ucuzsa en iyisidir. Örneğin, eğer büyükse , bütün ağacı inşa etmemek daha iyi olabilir. n
olasılıkalite

3
+1 Şimdiye kadar bu verimli bir algoritma öneren ve tanımlayan tek cevaptır.
whuber

19

Bunu R içinde kolayca yapabilirsiniz, sadece ihtiyacınız olan boyutu belirtin:

sample(x=c(1,2,3), size=1000, replace=TRUE, prob=c(.04,.50,.46))

3
Şahsen, bir algoritmayı (ya da gerekli bilgiyi öğrenmek için bir yere) tercih ederim, çünkü bunu inşa ettiğim bir uygulamaya dahil etmeye çalışıyorum :) Cevabınız için çok teşekkür ederim :)
FurtiveFelon

Hmmm tamam ... Ne yapmak istediğinizi biraz daha bilmek bilmek size rehberlik etmemize yardımcı olur. Bize biraz daha bahseder misiniz? (Amaç, içerik vb.)
Dominic Comtois

Oy vermek içindir. Örneğin, bir sürü fotoğrafım var ve bir defada bir kullanıcıya yalnızca 6 gösterebilirim, bir kerede bir kullanıcıya "en iyisini" eklemek isterim ve kullanıcı her fotoğrafta oy kullanabilir veya aşağı yapabilir . Şu anda işe yarayabilecek en basit çözüm, ana hatlarıyla belirttiğim şemadır (her sayı bir fotoğrafı temsil eder, her aşağı oylama o fotoğraftaki olasılığı azaltır ve her şeyde artar)
FurtiveFelon

1
@furtivefelon, kodu her zaman R'den ayırabilir, algoritmayı koddan çözebilir ve yeniden uygulayabilirsiniz.
mpiktas

Yığın Taşması hakkında iyi (daha iyi) tavsiyeler alabileceğinizi düşünüyorum, çünkü bu özel amaç için bazı iyi bilinen çözümler olabilir. Son yorumunuzdaki bilgileri doğrudan sorunuza eklemenizi de öneririm.
Dominic Comtois

19

Örneğinizde, sözde rasgele Uniform [0,1] değerinizi çizdiğinizi söyleyin ve U olarak adlandırın.

1 ise U <0,04

2 eğer U> = 0.04 ve U <0.54

3 eğer U> = 0,54

Belirtilen% a, b, ... ise, basitçe çıktı

U ise değer 1

U> = a ve U <(a + b) ise 2 değeri

vb.

Temel olarak,% 'yi [0,1]' in alt gruplarına eşliyoruz ve tek tip rastgele bir değerin herhangi bir aralığa düşme ihtimalinin o aralığın uzunluğu olduğunu biliyoruz. Aralıkları sıraya koymak, benzersiz olmasa da bunu yapmanın en basit yolu. Bu, yalnızca kesikli dağılımları sorduğunuzu varsaymaktadır; Sürekli olarak, "reddetme örneklemesi" gibi bir şey yapabilir ( Wikipedia girişi ).


8
Kategorileri, azalan olasılık sırasına göre sıralarsanız, algoritma daha hızlıdır. Bu şekilde, oluşturulan rasgele sayı başına daha az sayıda test (ortalama olarak) yaparsınız.
jbowman

1
Yalnızca sıralama üzerine hızlı bir not eklemek için - bu yalnızca bir örnekleme planının başlangıcında bir kez yaparsanız etkili olacaktır - bu nedenle olasılıkların daha büyük bir genel programın bir parçası olarak örneklendiği durumlar için iyi olmaz ( örneğin, ve ardından ). Bu durumda sıralama yaparak, her bir yinelemeye zamanı ekleyecek olan her örnekleme yinelemesine sıralama işlemini ekliyorsunuzdur . Bununla birlikte, bu durumda başlangıçtaki olasılıkların boyutunda yaklaşık bir tahminle sıralama yapmak faydalı olabilir. P r ( Y = j ) = p j O ( n günlüğü ( n ) )pjDistPr(Y=j)=pjO(nlog(n))
olasılık,

4

Mümkün ayrık sonuçlar olduğunu varsayalım . aralığını , bölümlenmiş aralığını vermek için , kümülatif olasılık kütle fonksiyonuna ( bağlı olarak alt girişimlere bölersiniz.[ 0 , 1 ] F ( 0 , 1 )m[0,1]F(0,1)

I1I2Im

burada ve . Örnekte veIj=(F(j1),F(j))F(0)0m=3

I1=(0,.04),     I2=(.04,.54),     I3=(.54,1)

çünkü ve ve .F(1)=.04F(2)=.54F(3)=1

Sonra aşağıdaki algoritmayı kullanarak dağıtımı ile oluşturabilirsiniz :XF

(1) üretirUUniform(0,1)

(2) Eğer , .UIjX=j

  • Bu adım olmadığını bakarak yapılabilir az her daha birikimli (gelen değişim noktası nerede olasılıklar ve görme için ) kullandığınız ne olursa olsun programlama dili bir boolean operatörü kullanarak meselesi olmalı ve hangi oluşur ilk vektörde nerede meydana geldiğini bulma .UTRUEFALSEFALSE

, ayrık ve bölünmüş olduklarından tam olarak aralıklarından birinde olacağını unutmayın .UIj[0,1]


Bu aralıkların tümü yarı kapalı olmamalı mı? Aksi takdirde, aralıklar arasındaki sınırlar dahil edilmez. {[0,0.04), [0.04,0.54), [0.54,1]}
na1101

1
P(U=u)=0Herhangi bir noktası için (yani yarı açık aralığın Lebesgue ölçümü açık aralığınkiyle aynıdır), bunun önemli olduğunu sanmıyorum. u
Makro

1
Ancak sonlu hassas bir dijital makinede, belki bir gün evrenin bitiminden önce önemli olacak ...
jbowman

1
Yeterince adil, @whuber, düzenlememe bakın.
Makro

1
Tamam, bu bir algoritma. BTW, neden böyle bir şeyi iade etmiyorsun min(which(u < cp))? Her aramada kümülatif toplamı yeniden hesaplamaktan kaçınmak iyi olur. Bu önceden hesaplanmış olan tüm algoritma, 'a indirgenmiştir min(which(runif(1) < cp)). Veya daha iyisi, OP sayıları oluşturmayı istediğinden ( çoğul ), olarak onu vektörleştirin n<-10; apply(matrix(runif(n),1), 2, function(u) min(which(u < cp))).
whuber

2

Basit bir algoritma, tekdüze rastgele numaranızla başlamaktır ve bir döngüde ilk önce ilk olasılıktan çıkarırsınız, sonuç negatifse sonra ilk değeri döndürürsünüz, yine de pozitif ise bir sonraki yinelemeye gider ve sonraki olasılığı çıkarırsınız. , negatif olup olmadığını kontrol edin, vb.

Değerlerin / olasılıkların sayısının sonsuz olabileceği için bu hoş bir şey ancak yalnızca bu sayılara yaklaştığınızda (Poisson veya negatif binom dağılımından üretmek gibi bir şey için) olasılıkları hesaplamanız gerekiyor.

Sonlu bir olasılık kümeniz varsa, ancak bunlardan çok sayıda sayı üretecekseniz, olasılıkları sıralamak daha verimli olabilir, böylece ilk önce en büyüğü, sonra en büyüğü ikinci olanı çıkarırsınız.


2

Öncelikle, dikkatinizi tam anlamıyla dağıtmayı izleyen tam sayı veya kayan nokta rasgele sayı üretimi için kullanıma hazır sınıfları olan bir python kütüphanesine dikkatinizi çekeyim .

Genel olarak konuşursak, bu soruna birkaç yaklaşım vardır. Bazıları zaman içinde doğrusaldır, ancak büyük bellek depolama gerektirir, bazıları O (n log (n)) zamanında çalışır. Bazıları tam sayılar için optimize edilmiş, bazıları ise dairesel histogramlar için tanımlanmıştır (örneğin: bir gün boyunca rastgele zaman noktaları oluşturma). Yukarıda belirtilen kütüphanede , tam sayı sayıları için bu kağıdı ve kayan nokta sayıları için bu tarifi kullandım. (Hala) dairesel histogram desteğinden yoksun ve genellikle dağınık, fakat iyi çalışıyor.


2

Ben de aynı problemi yaşadım. Her bir öğenin olasılığı olan ve öğelerinin olasılıkları birleştiği bir küme göz önüne alındığında, bir örneği verimli bir şekilde, yani herhangi bir şeyi sıralamadan ve tekrar tekrar kümeyi tekrarlamadan çizmeyi istedim .

Aşağıdaki işlev aralığı içinde en düşük düzgün dağılımlı rasgele sayı çizer . den rasgele bir sayı olsun .N[a,1)r[0,1)

next(N,a)=1(1a)rN

Bir çizmek için bu fonksiyonu kullanarak artan bir dizi ait homojen [0,1 rastgele sayı dağıtılmaktadır). İşte olan bir örnek :(ai)NN=10

a0=next(10,0)
a1=next(9,a0)
a2=next(8,a1)

a9=next(1,a8)

Düzgün dağılmış sayılardan oluşan artan diziyi çizerken, (ancak sonlu) dağılımınızı temsil eden olasılık kümesini yineleyin . Letyineleyici ol ve . Çizdikten sonra , artım kadar sıfır ya da daha fazla kez . Daha sonra numunenize ekleyin ve çizerek devam edin .(ai)P0k<|P|pkPaikp0pk>aipkai+1


Operasyon dizisinin ve örneklem büyüklüğü örnek :{(1,0.04),(2,0.5),(3,0.46)}N=10

i a_i k Toplam Çizim
0 0.031 0 0.04 1
1 0.200 1 0.54 2
2 0.236 1 0.54 2
3 0,402 1 0,54 2
4 0,488 1 0,54 2
5 0,589 2 1,0 3
6 0,625 2 1,0 3
7 0,638 2 1,0 3
8 0,738 2 1,0 3
9 0.942 2 1.0 3

Örnek:(1,2,2,2,2,3,3,3,3,3)


Eğer merak ise fonksiyonu: Bu biri o olasılık tersi olan homojen aralığı içinde rasgele sayılar yalan dağıtılmış ile .nextN[a,x)x1


İkinci paragrafta aniden değiştirdiğiniz sorunun, rastgele bir ayrı dağılımdan, tek tip bir dağıtımdan örneklemeye kadar olanlardan birinden değişmesi gibi görünüyor . Çözümü burada sorulan soru ile ilgili görünmüyor.
whuber

Son kısmı açıklığa kavuşturdum.
casi

Cevabınız hala soru ile ilgisiz görünüyor. Algoritmanızın küçük ama önemsiz bir şekilde çalıştığı bir örnek verebilir misiniz? Bize , soruda verilen olasılıklara göre kümesinden tek bir beraberlik getireceğini gösterin . {1,2,3}
whuber

Bir örnek ekledim. Cevabımın David M Kaplan'ın cevabı ile ortak bir yanı var ( istatistik.stackexchange.com/a/26860/93386 ), ancak N N th kökleri. Her iki prosedürü de profillendirdim ve benimki çok daha hızlıydı.
casi

Açıklama için teşekkür ederiz (+1). Bunun pek çok okuyucunun basit rastgele bir örnek olmaması ilginç olabilir, çünkü sonuçlar önceden belirlenmiş, sabit bir düzende görünür: basit bir rastgele örnek oluşturmak için sonuçlara rastgele bir permütasyon uygulanması gerekir. Ayrıca, bu algoritmanın paralelleştirilebilir bir sürümüyle de ilginizi çekebilir burada basit bir Uniform (0,1) değişkeni u1,,uN+1
aj=i=1jlog(ui)i=1N+1log(ui)
u1,,uN+1
örneğidir
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.