구간 $ (a, b) $ 내에서 정규 분포에 따라 난수를 생성해야합니다. (저는 R에서 작업 중입니다.)

rnorm(n,mean,sd) 함수가 정규 분포에 따라 난수를 생성한다는 것을 알고 있지만 그 범위 내에서 간격 제한을 설정하는 방법은 무엇입니까? 이를 위해 사용할 수있는 특정 R 함수가 있습니까?

코멘트

  • 이 작업을 수행하려는 이유는 무엇입니까? ' 제한되어 있다면 ' 정말 정상이 아닐 수 있습니다. 달성하려는 목표는 무엇입니까?
  • x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
  • @Hugh that ' … ' 얼마나 많은 임의 값을 얻는 지 상관하지 않는 한.

답변

잘린 분포 및 특정 예에서 시뮬레이션하려는 것 같습니다. , 잘린 법선 .

그렇게하는 방법에는 여러 가지가 있습니다. 실력 있는.

일반적인 예에 대한 몇 가지 접근 방식을 설명하겠습니다.

  1. 다음은 한 번에 하나씩 생성하는 매우 간단한 방법입니다 (일종의 의사 코드에서 ) :

    $ \ tt {repeat} $ N에서 $ x_i $ 생성 (평균, SD) $ \ tt {until} $ 하한 $ \ leq x_i \ leq $ 상한

    여기에 이미지 설명 입력

    분포의 대부분이 범위 내에있는 경우 이는 상당히 합리적이지만 다음과 같은 경우 상당히 느려질 수 있습니다. 거의 항상 한계 밖에서 생성됩니다.

    R에서는 경계 내 영역을 계산하여 한 번에 하나씩 반복하는 것을 피할 수 있고, 버리고 난 후에 거의 확신 할 수있는 충분한 값을 생성 할 수 있습니다. 경계를 벗어난 값은 여전히 필요한만큼 많은 값을 가졌습니다.

  2. 간격에 걸쳐 적절한 주요 화 함수와 함께 accept-reject를 사용할 수 있습니다 (일부 경우 uniform은 충분히 좋다). 한계가 s.d에 비해 합리적으로 좁은 경우 그러나 당신은 “꼬리에 멀지 않았습니다. 예를 들어 균일 전공은 정상에서 잘 작동합니다.

    여기에 이미지 설명 입력

  3. 합리적으로 효율적인 cdf 및 역 cdf가있는 경우 (예 : pnormqnorm R의 정규 분포) 잘린 정규 분포에 대한 Wikipedia 페이지 시뮬레이션 섹션의 첫 번째 단락에 설명 된 inverse-cdf 방법을 사용할 수 있습니다. [실제로 이것은 잘린 uniform (필요한 분위수에서 잘림, 실제로는 전혀 거부가 필요하지 않습니다. 이는 단지 또 다른 균일이기 때문에)를 취하는 것과 동일합니다. 여기에 역 정규 cdf를 적용합니다. “뒤쪽에있는 경우 실패 할 수 있습니다.]

    여기에 이미지 설명 입력

  4. 다른 접근 방식이 있습니다. 동일한 Wikipedia 페이지에서 다양한 배포에서 작동하는 ziggurat 방법을 채택한다고 언급합니다.

동일한 Wikipedia 링크 는 잘린 법선을 생성하는 기능이있는 두 개의 특정 패키지 (둘 다 CRAN에 있음)를 언급합니다.

R의 MSM 패키지에는 잘린 부분에서 그리기를 계산하는 rtnorm 함수가 있습니다. R의 truncnorm 패키지에는 잘린 노멀에서 그리는 기능도 있습니다.


주변을 둘러 보면 다른 질문에 대한 답변에서 많은 내용을 다루고 있습니다 (그러나이 질문은 잘린 정상보다 더 일반적이기 때문에 정확히 중복되지는 않습니다) …

a에서 추가 토론을 참조하십시오. 이 답변

b. Xi “an”의 답변은 여기 이며, 여기에는 그의 arXiv 논문에 대한 링크가 있습니다 (다른 가치있는 답변과 함께).

답변

빠르고 간단한 접근 방식은 68-95-99.7 규칙 .

정규 분포에서 값의 99.7 %는 평균의 3 표준 편차 내에 있습니다. 따라서 평균을 원하는 최소값과 최대 값의 중간으로 설정하고 표준 편차를 평균의 1/3로 설정하면 원하는 간격 내에있는 (대부분) 값을 얻을 수 있습니다. 그런 다음 나머지 부분 만 정리하면됩니다.

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) 

저는 최근에 를 생성하려고 시도하면서 동일한 문제에 직면했습니다. 시험 데이터에 대한 무작위 학생 성적 . 위 코드에서 저는 pmaxpmin를 사용하여 범위를 벗어난 값을 최소 또는 최대 인바운드로 대체했습니다. 값.이것은 제 목적에 적합합니다. 왜냐하면 저는 상당히 적은 양의 데이터를 생성하기 때문입니다. 그러나 더 많은 양의 경우 최소값과 최대 값에서 눈에 띄는 범프를 줄 것입니다. 따라서 목적에 따라 이러한 값을 버리고 대체하는 것이 좋습니다. NA를 사용하거나 인바운드가 될 때까지 “다시 굴림”합니다.

댓글

  • 왜 이러는 거죠? 정상적인 난수를 생성하고 잘림이 필요한 숫자를 삭제하는 것은 매우 간단하므로 원하는 잘림이 영역의 100 %에 가까워지지 않는 한 ' 복잡 할 필요가 없습니다. 밀도의.
  • 아마도 ' 원래 질문을 잘못 해석 한 것 같습니다. R에서 직접 통계와 관련이없는 프로그래밍 작업을 수행하는 방법을 알아 내다가이 질문을 발견했는데 '이 페이지가 통계 stackexchange라는 것을 알았습니다. , 프로그래밍 stackexchange가 아닙니다. 🙂 제 경우에는 0에서 100까지의 값을 가진 특정 양의 임의의 정수를 생성하고 싶었고 생성 된 값이 해당 범위에 걸쳐 멋진 종 모양의 곡선에 떨어지길 원했습니다. 이 글을 작성한 후 ' sample(x=min:max, prob=dnorm(...))가 더 쉬운 방법 일 수 있다는 것을 깨달았습니다.
  • @Glen_b Aaron Wells는 sample(x=min:max, prob=dnorm(...))를 언급했는데 이는 귀하의 답변보다 약간 짧아 보입니다.
  • 그러나 sample() 트릭은 유용합니다. ' 임의의 정수 또는 기타 불연속적인 사전 정의 된 값 집합을 선택하려는 경우

답변

여기에있는 답변 중 어느 것도 임의로 큰 거부를 포함하지 않는 잘린 일반 변수를 생성하는 효율적인 방법을 제공하지 않습니다. 생성 된 값의 수. 지정된 하한 및 상한이 $ a < b $ 인 잘린 정규 분포에서 값을 생성하려는 경우 절단에 의해 허용되는 분위수 범위에 대해 균일 분위수를 생성하고 역 변환 샘플링 을 사용하여 해당 정규 값을 가져옴으로써 — 거부없이 — 수행 할 수 있습니다. .

$ \ Phi $ 는 표준 정규 분포의 CDF를 나타냅니다. 잘린 정규 분포에서 $ X_1, …, X_N $ 을 생성하려고합니다 (평균 매개 변수 $ \ mu $ 및 분산 매개 변수 $ \ sigma ^ 2 $ ) $ ^ \ dagger $ 자르기 상한선 $ a < b $ . 다음과 같이 수행 할 수 있습니다.

$$ X_i = \ mu + \ sigma \ cdot \ Phi ^ {-1} (U_i) \ quad \ quad \ 쿼드 U_1, …, U_N \ sim \ text {IID U} \ Big [\ Phi \ Big (\ frac {a- \ mu} {\ sigma} \ Big), \ Phi \ Big (\ frac {b- \ mu} {\ sigma} \ Big) \ Big]. $$

잘린 분포에서 생성 된 값에 대한 내장 함수는 없지만 다음을 사용하여이 방법을 프로그래밍하는 것은 간단합니다. 랜덤 변수 생성을위한 일반 함수. 다음은 몇 줄의 코드로이 메서드를 구현하는 간단한 R 함수 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); } 

이것은 잘린 정규 분포에서 N IID 랜덤 변수를 생성하는 벡터화 된 함수입니다. 동일한 방법을 통해 다른 잘린 분포에 대한 함수를 쉽게 프로그래밍 할 수 있습니다. 잘린 분포에 대한 관련 밀도 및 분위수 함수를 프로그래밍하는 것도 그리 어렵지 않습니다.


$ ^ \ dagger $ 잘림은 분포의 평균과 분산을 변경하므로 $ \ mu $ $ \ sigma ^ 2 $ 는 잘린 분포의 평균 및 분산이 아닙니다 .

답변

h2>

세 가지 방법이 저에게 효과적이었습니다.

  1. rnorm ()과 함께 sample () 사용 :

    sample(x=min:max, replace= TRUE, rnorm(n, mean))

  2. msm 패키지 및 rtnorm 함수 사용 :

    rtnorm(n, mean, lower=min, upper=max)

  3. rnorm ()을 사용하고 Hugh가 위에 게시 한대로 하한 및 상한을 지정합니다.

    sample <- rnorm(n, mean=mean); sample <- sample[x > min & x < max]

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다