구간 내 정규 분포에 따라 난수를 생성해야합니다 . (저는 R에서 일하고 있습니다.)
함수 rnorm(n,mean,sd)
가 정규 분포에 따라 임의의 숫자를 생성 한다는 것을 알고 있지만 그 범위 내에서 간격 제한을 설정하는 방법은 무엇입니까? 사용할 수있는 특정 R 기능이 있습니까?
x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
구간 내 정규 분포에 따라 난수를 생성해야합니다 . (저는 R에서 일하고 있습니다.)
함수 rnorm(n,mean,sd)
가 정규 분포에 따라 임의의 숫자를 생성 한다는 것을 알고 있지만 그 범위 내에서 간격 제한을 설정하는 방법은 무엇입니까? 사용할 수있는 특정 R 기능이 있습니까?
x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
답변:
잘린 분포 와 특정 예에서 잘린 법선 을 시뮬레이트하려는 것처럼 들립니다 .
그렇게하는 방법에는 여러 가지가 있는데, 간단하고 비교적 효율적입니다.
일반적인 예제에 대한 몇 가지 접근법을 설명하겠습니다.
다음은 한 번에 하나씩 생성하는 매우 간단한 방법입니다 (의사 코드의 일종).
는N (평균, SD)에서 를생성합니다. lower upper
대부분의 분포가 범위 내에 있으면 상당히 합리적이지만 거의 항상 한계를 벗어나면 상당히 느려질 수 있습니다.
R에서는 경계 내 영역을 계산하여 한 번에 하나씩 루프를 피하고 경계 외부의 값을 버린 후에도 필요한만큼 많은 값을 가질 수있을 정도로 충분한 값을 생성 할 수 있습니다.
간격에 걸쳐 적절한 메이저 기능과 함께 accept-reject를 사용할 수 있습니다 (일부 경우 유니폼이 충분할 것입니다). 한계가 sd에 비해 합리적으로 좁 았지만 꼬리까지 멀지 않은 경우, 예를 들어 균일 한 전공이 정상적으로 작동합니다.
합리적으로 효율적인 cdf 및 역 cdf (예 : R의 정규 분포 pnorm
와 같은 qnorm
)가 있는 경우 잘린 normal에있는 Wikipedia 페이지 의 시뮬레이션 섹션의 첫 번째 단락에 설명 된 inverse-cdf 방법을 사용할 수 있습니다 . [실제로 이것은 잘린 유니폼 (필요한 Quantile에서 잘린 것, 실제로는 전혀 다른 유니폼이 아니기 때문에 전혀 거부가 필요하지 않음) 을 취하는 것과 동일 하고 역 정규 cdf를 적용합니다. 꼬리가 멀어지면 실패 할 수 있습니다.]
다른 접근법이 있습니다. 같은 Wikipedia 페이지에는 다양한 배포판에서 작동 하는 ziggurat 방법의 적용에 대해 언급 되어 있습니다.
같은 위키 백과 링크는 잘립니다 법선을 생성하는 기능이 개 특정 패키지 (CRAN에 모두)를 언급한다 :
MSM
R 의 패키지rtnorm
에는 잘린 법선에서 그림을 계산 하는 함수 가 있습니다.truncnorm
R 의 패키지에는 잘린 법선을 그리는 기능도 있습니다.
주위를 둘러 보면이 질문에 대한 많은 답변이 다른 질문에 대한 답변으로 다루어집니다 (그러나이 질문이 잘린 정상보다 더 일반적이기 때문에 정확하게 중복되지는 않습니다).
ㅏ. 이 답변
비. Xi'an의 답변은 here 이며, 그의 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)
나는 최근에 같은 문제에 직면 하여 시험 데이터에 대한 무작위 학생 성적 을 생성하려고 시도했다 . 위의 코드에서, 내가 사용했습니다 pmax
및 pmin
최소 또는 최대의-경계 값이 범위를 벗어날 값을 바꿀 수 있습니다. 이것은 상당히 적은 양의 데이터를 생성하기 때문에 내 목적을 위해 작동하지만 더 많은 양의 경우 최소 및 최대 값에서 눈에 띄는 충돌이 발생합니다. 따라서 목적에 따라 해당 값을 버리고 NA
s로 바꾸 거나 인바운드 될 때까지 "다시 롤"하는 것이 좋습니다.
sample(x=min:max, prob=dnorm(...))
는 더 쉬운 방법 이라는 것을 깨달았습니다 .
sample(x=min:max, prob=dnorm(...))
귀하의 답변보다 약간 짧은 것 같습니다.
sample()
트릭은 임의의 정수 또는 다른 일련의 미리 정의 된 값을 선택하려는 경우에만 유용합니다.
잘린 분포에서 생성 된 값에 대한 기본 제공 함수는 없지만 임의 변수 생성을위한 일반 함수를 사용하여이 방법을 프로그래밍하는 것은 쉽지 않습니다. 다음은 몇 줄의 코드로이 메소드를 구현 하는 간단한 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 랜덤 변수를 생성하는 벡터화 된 함수입니다 . 같은 방법으로 다른 잘린 분포에 대한 기능을 쉽게 프로그래밍 할 수 있습니다. 또한 잘린 분포에 대한 관련 밀도 및 Quantile 함수를 프로그래밍하는 것도 어렵지 않습니다.