Bir aralıktaki dağılımı takiben rastgele sayılar üretme


17

aralığı içinde Normal dağılımı takiben rastgele sayılar üretmem gerekiyor . (R'de çalışıyorum.)(a,b)

Fonksiyonun rnorm(n,mean,sd)normal dağılımdan sonra rasgele sayılar üreteceğini biliyorum , ama bunun içindeki aralık sınırlarını nasıl ayarlayabilirim? Bunun için özel R fonksiyonları var mı?


Bunu neden yapmak istiyorsun? Sınırlıysa, o zaman normal olamaz. Ne elde etmeye çalışıyorsunuz?
gung - Monica'yı eski

x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
Hugh

3
@Bu harika bir şey ... kaç tane rastgele değer aldığınız umurumda değil.
Glen_b

Yanıtlar:


31

Kesik bir dağılımdan simüle etmek istediğiniz gibi ve özel örneğinizde kesik bir normal gibi görünüyor .

Bunu yapmak için çeşitli yöntemler vardır, bazıları basit, bazıları nispeten verimli.

Normal örneğinizle ilgili bazı yaklaşımları göstereceğim.

  1. İşte bir kerede bir tane oluşturmak için çok basit bir yöntem (bir tür sahte kodda):

    repeat N'denxi oluşturur(ortalama, sd)until altxi üst

    enter image description here

    Dağılımın çoğu sınırlar içindeyse, bu oldukça mantıklıdır, ancak neredeyse her zaman sınırların dışında üretim yaparsanız oldukça yavaş olabilir.

    R'de, sınırlar içindeki alanı hesaplayarak bir kerede bir döngüden kaçınabilir ve sınırların dışına attıktan sonra hala gerektiği kadar çok değere sahip olduğunuzdan neredeyse emin olabileceğiniz yeterli değerleri üretebilirsiniz.

  2. Aralık boyunca uygun bir uygunlaştırma işlevi ile kabul-reddetme kullanabilirsiniz (bazı durumlarda üniforma yeterince iyi olacaktır). Sınırlar sd'ye göre oldukça dar olsaydı, ancak kuyruğa çok uzak olmasaydınız, muntazam bir ihtisaslaşma normalde işe yarayabilirdi.

    enter image description here

  3. Eğer makul verimli cdf ve (örneğin ters cdf varsa pnormve qnormAr normal dağılımı için) Eğer simüle bölümünün birinci paragrafında tarif ters-ED yöntemini kullanabilirsiniz kesilmiş Normal Wikipedia sayfası . [Aslında bu, kesilmiş bir üniforma almakla aynıdır (gerekli miktarlarda kesilmiş, aslında hiç reddetme gerektirmez, çünkü bu sadece başka bir üniformadır) ve ters normal cdf'yi uygulayın. Eğer kuyrukta iseniz bu başarısız olabilir unutmayın]

    enter image description here

  4. Başka yaklaşımlar da var; aynı Wikipedia sayfası, çeşitli dağıtımlar için çalışması gereken ziggurat yöntemini uyarlamaktadır .

Aynı Wikipedia linki kesildi normaller üretmek için fonksiyonları ile iki özel paketleri (CRAN üzerindeki her ikisi) bahseder:

MSMR paket işlevi vardır rtnormhesaplar bir kesik normal çektiği. truncnormR Paket ayrıca normal kesilmiş çekilebilecek işlevlere sahiptir.


Etrafa bakıldığında, bunun çoğu diğer soruların cevaplarıyla kaplıdır (ancak bu soru sadece kesilmiş normalden daha genel olduğu için tam olarak çoğaltılmaz) ...

a. Bu cevap

b. Xi'an'ın arXiv belgesine (diğer bazı değerli cevaplarla birlikte) bağlantısı olan cevabı burada .


2

Çabuk ve kirli yaklaşım 68-95-99.7 kuralını kullanmaktır .

Normal bir dağılımda, değerlerin% 99.7'si ortalamanın 3 standart sapmasına girer. Dolayısıyla, ortalamanızı istediğiniz minimum değerin ve maksimum değerin ortasına ayarlarsanız ve standart sapmanızı ortalamanızın 1 / 3'üne ayarlarsanız, istenen aralıkta (çoğunlukla) değerler alırsınız. Sonra gerisini temizleyebilirsiniz.

minVal <- 0
maxVal <- 100
mn <- (maxVal - minVal)/2
# Generate numbers (mostly) from min to max
x <- rnorm(count, mean = mn, sd = mn/3)
# Do something about the out-of-bounds generated values
x <- pmax(minVal, x)
x <- pmin(maxVal, x)

Kısa süre önce aynı problemle karşılaştım ve test verileri için rastgele öğrenci notları oluşturmaya çalıştım . Yukarıdaki kodda, kullandım pmaxve pminsınırların dışındaki değerleri min veya maks. Sınır değerleriyle değiştirdim. Bu benim amacım için işe yarıyor, çünkü oldukça az miktarda veri üretiyorum, ancak daha büyük miktarlar için minimum ve maksimum değerlerde fark edilir çarpmalar verecektir. Bu nedenle amaçlarınıza bağlı olarak, bu değerleri silmek, NAs ile değiştirmek veya sınırlar içinde olana kadar "yeniden yuvarlamak" daha iyi olabilir .


Neden bunu yapmıyorsun? Normal rasgele sayılar üretmek ve kesilmesi gerekenleri düşürmek o kadar basittir ki, istenen kesilme yoğunluk alanının% 100'üne yakın olmadığı sürece bu konuda karmaşık olması gerekmez.
Carl

2
Belki de orijinal soruyu yanlış yorumluyorum. R'de doğrudan istatistiklerle ilgili olmayan bir programlama görevinin nasıl elde edileceğini anlamaya çalışırken bu soruya rastladım ve şimdi bu sayfanın bir programlama yığını değişkeni değil, bir istatistik yığını değişkeni olduğunu fark ettim. :) Benim durumumda, 0 ile 100 arasında değişen belirli bir miktarda rastgele tamsayı oluşturmak istedim ve üretilen değerlerin bu aralıkta güzel bir çan eğrisine düşmesini istedim. Bunu yazdığından beri sample(x=min:max, prob=dnorm(...))bunu yapmanın belki daha kolay bir yolu olduğunu fark ettim .
Aaron Wells

@Glen_b Aaron Wells, sample(x=min:max, prob=dnorm(...))cevabınızdan biraz daha kısa görünüyor.
Carl

Ancak, sample()hilenin yalnızca rastgele tamsayılar veya başka bir ayrık, önceden tanımlanmış değerler kümesi seçmeye çalıştığınızda yararlı olduğunu unutmayın.
Aaron Wells

1

Buradaki cevapların hiçbiri, keyfi olarak çok sayıda üretilen değerin reddedilmesini içermeyen kesik normal değişkenler oluşturmak için etkili bir yöntem vermez. Belirtilen alt ve üst sınırlarla kesilmiş bir normal dağılımdan değerler oluşturmak istiyorsanızbir<b, bu - reddedilmeden ---, kesme işleminin izin verdiği kantil aralığında tekdüze nicelikler üreterek ve ters dönüşüm örneklemesi kullanarak yapılabilir karşılık gelen normal değerleri elde etmek için .

İzin Vermek Φ"Normal" dağılımın CDF'sini belirtir. Biz üretmek istiyoruzX1,...,XN- kesik normal dağılımdan (ortalama parametre ile) μ ve varyans parametresi σ2) alt ve üst kesme sınırlarıyla bir<b. Bu şöyle yapılabilir:

Xben=μ+σΦ-1(Uben)U1,...,UN-~IID U[Φ(bir-μσ),Φ(b-μσ)].

Kesik dağılımdan üretilen değerler için dahili bir işlev yoktur, ancak rastgele değişkenler oluşturmak için normal işlevleri kullanarak bu yöntemi programlamak önemsizdir. İşte bu yöntemi birkaç kod satırında uygulayan basit bir Rişlev rtruncnorm.

rtruncnorm <- function(N, mean = 0, sd = 1, a = -Inf, b = Inf) {
  if (a > b) stop('Error: Truncation range is empty');
  U <- runif(N, pnorm(a, mean, sd), pnorm(b, mean, sd));
  qnorm(U, mean, sd); }

Bu üretecek bir vektörlenmiş fonksiyonudur Nkesildi normal dağılımdan Rasgele değişkenlerin. Aynı yöntemle diğer kesik dağılımlar için fonksiyonları programlamak kolay olacaktır. Ayrıca, kesikli dağılım için ilişkili yoğunluk ve kuantil fonksiyonları programlamak çok zor olmayacaktır.


Kesme işleminin dağılımın ortalamasını ve varyansını değiştirdiğini unutmayın. μ ve σ2Hangi değil ortalama ve kesilmiş dağılımının varyansı.

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.