**난수(Random Number, 亂數)란 정의된 범위내에서 무작위로 추출된 수를 일컫는데, 난수는 누구라도 그 다음에 나올 값을 확신할 수 없어야 한다. 특히 난수 추출에 대해 민감할 수 있는 복권 추첨에서는 난수를 발생하기 위하여 컴퓨터를 사용하지 않는다. 그 대신 도구를 사용하는 물리적인 방법으로 난수를 추출한다고 하는데, 컴퓨터에의해 추출된 난수는 조작의 여지를 남길 수 있기 때문이라고 한다. 그렇지만, 난수 생성이 필요한 곳이 생각보다 광범위하고 이럴 때마다 공정성을 위해서 물리적인 기계를 활용하여 난수를 생성하는 것은 무리가 있다. 따라서, 적절한 경우에 적절한 난수 품질을 갖는 난수를 컴퓨터를 이용하여 생성하여 실생활에 활용하는 것은 의미가 크다.
Ripley(1990)교수가 정의한 난수생성기에서 나온 난수는 다음 특성을 갖추어야 한다.3
진정한 난수(True Random Number) 생성기와 의사난수(Pseudo Random Number) 생성기를 효율성(Efficiency), 결정론(Determinism), 주기성(Periodicity)을 기준으로 비교해보자.
특성 | 의사난수 생성기 | 진정한 난수 생성기 |
---|---|---|
효율성 | 매우 훌륭함 | 나쁨 |
결정론 | 결정론적 특성 | 비결정론적 특성 |
주기성 | 주기성을 띔 | 비주기성을 띔 |
의사난수 생성기와 진정한 난수 생성기는 효율성, 결정론, 주기성 관점에서 서로 다른 특성이 있기 때문에 난수 생성기를 활용하는 응용분야에서 특성에 맞춰 적절히 활용해야만 한다.
응용분야 | 가장 적합한 난수 생성기 |
---|---|
복권과 그리기 | 진정한 난수 생성기 |
게임과 도박 | 진정한 난수 생성기 |
표집 (약물검사) | 진정한 난수 생성기 |
모의실험과 모형 | 의사 난수 생성기 |
보안(데이터 암호화키) | 진정한 난수 생성기 |
예술 | 상황에 맞춰 선택 |
컴퓨터를 활용한 의사 난수 생성기는 크게 두범주로 나눠진다. 하나는 산술 난수 생성기(Arithmetic random number generators), 다른 하나는 재귀 산술 난수 생성기(Recursive arithmetic random number generators)가 있다.
처음 생각해볼 수 있는 의사난수 생성방법은 승법 합동 난수 생성 방법(multiplicative congruential method)으로 다음과 같은 형태를 갖는다.
\[x_n = a \times x_{n-1} \quad \text{법(Modulo)} \quad m \]
\(a,m\)은 주어진 양의 정수가 되면, \(a \times x_{n-1}\)을 \(m\)으로 나눈 나머지가 \(x_n\)에 대입되는 구조가 된다. 따라서 \(x_n\)이 가질 수 있는 값의 범위는 \(\{0, 1,2, \cdots, m-1 \}\)을 갖게 되고 대략 \(\frac{x_n}{m}\)으로 나눗셈을 하게 되면 대략 일양분포\((0,1)\)를 갖는 난수를 취하게 된다.
따라서, \(a,m\)을 적절히 잘 취하게 되면 품질 좋은 난수를 갖게 되어 신중히 선정을 해야 되는데 일반적인 선정기준은 다음과 같다.
또다른 형태의 의사 난수생성방법은 복합 합동 난수생성방법으로 가법항과 승법항이 함께 포함된 형태를 취한다. 즉,
\[x_n = (a \times x_{n-1} + c) \quad \text{법(Modulo)} \quad m \]
예를 들어, \(m = 2^{32}\), \(a = 69069\), \(c = 23606797\) 값을 택하게 되면 나름 품질 좋은 난수를 생성시킬 수 있다.
역산법(Inverse transform sampling)은 확률변수를 넣으면 확률이 계산되는 것을 반대로 확률을 넣어 확률변수를 구하는 방식이다. 즉, 누적확률분포는 항상 \([0,1]\)에서 정의되기 때문에 품질좋은 일양균등분포 난수 생성기가 있고, 역함수를 수식으로 표현할 수 있다면 역산법을 활용하여 난수를 생성할 수 있다.
누적분포함수 \(F_X\)는 함수가 입력값으로 임의 \(x\)가 \(X \leq x\)보다 적은 확률은 \(p\)가 되고 이를 표현하면 다음과 같다.
\[ F_X(x) = \Pr(X \leq x) = p \]
\(p \sim U\)를 활용하여 일양균등분포를 역함수에 입력값으로 넣으면 난수를 생성시킬 수 있다.
\[ F_X^{-1}(u) = x \]
누적정규분포함수(qnorm
)에 일양균등분포난수를 넣으면 정규분포를 따르는 난수를 생성시킬 수 있다. 동일한 방식으로 지수분포를 따르는 난수도 동일하게 생성시킬 수 있고, 이를 fitdistrplus::descdist
함수를 통해 확인을 할 수 있다.
# 1. 난수생성 -----------------------
unif_random_v <- runif(100000)
normal_random_v <- qnorm(unif_random_v)
exp_random_v <- qexp(unif_random_v)
# 2. 생성된 난수 검정 -----------------------
par(mfrow=c(1,2))
fitdistrplus::descdist(normal_random_v, discrete = FALSE, obs.col = "lightpink")
summary statistics
------
min: -5.034473 max: 4.483509
median: 0.002406137
mean: 0.003670916
estimated sd: 0.9968548
estimated skewness: 0.00261609
estimated kurtosis: 3.005615
fitdistrplus::descdist(exp_random_v, discrete = FALSE, obs.col = "lightpink")
summary statistics
------
min: 2.395828e-07 max: 12.51497
median: 0.6950688
mean: 1.001522
estimated sd: 0.9992005
estimated skewness: 2.015967
estimated kurtosis: 9.219926
지수함수를 \(f(x;\lambda) =\lambda e^{-\lambda x}\)와 같이 정의하면 누적분포함수는 \(F(x;\lambda) = 1-e^{-\lambda x}\)와 같이 구할 수 있다. \(F_X^{-1}(u)\)를 구하기 위해 \(F(x;\lambda)=U\)로 둔다.
\[F(x;\lambda)= U = 1-e^{-\lambda x}\] 이것을 \(x\)에 대해서 정리하면 다음과 같다.
\[e^{-\lambda x}=1-U \\ -\lambda x = log(1-U) \\ x = - \frac{1}{\lambda} log(1-U) = \frac{1}{\lambda} log(U) \\ F_X^{-1}(u) = - \frac{1}{\lambda} log(u) \]
지수분포의 역함수를 R코드로 작서아고 난수슬 생성하여 히스토그램과 분포곡선, 지수분포검정, 분위수-분위수그림(QQ plot)을 통해 역산법을 통해서 일양균등분포에서 지수분포를 따르는 표본을 추출할 수 있다는 것을 확인할 수 있다.
# 3. 지수분포 난수 -----------------------
## 3.1. 지수분포 난수 생성 ---------------
inv_exp <- function(sample_size, lambda = 1) {
unif_random_v <- runif(sample_size)
exp_random_v <- -(1/lambda) * log(unif_random_v)
return(exp_random_v)
}
exp_random_v <- inv_exp(100000, 1)
## 3.2. 지수분포 난수 시각화 ---------------
par(mfrow=c(1,3))
#### 3.2.1. 히스토그램과 분포 곡선
MASS::truehist(exp_random_v, nbins = 20, col = "limegreen", main = "지수분포", xlab = "")
curve(dexp(x), from = 1e-10, add = TRUE)
#### 3.2.2. 지수분포검정
fitdistrplus::descdist(exp_random_v, discrete = FALSE, obs.col = "lightpink")
summary statistics
------
min: 3.867345e-05 max: 12.63283
median: 0.690404
mean: 1.002594
estimated sd: 1.005721
estimated skewness: 2.012602
estimated kurtosis: 9.19029
#### 3.2.3. 분위수-분위수 그림
p <- ppoints(100)
q <- quantile(exp_random_v, p=p)
plot(qexp(p) ,q, main="지수분포 분위수-분위수 그림(Q-Q Plot)",
xlab="이론 분위수",ylab="난수 분위수")
qqline(q, distribution=qexp,col="blue", lty=2)