Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

노력하는문돌이

Random Number (1) : Uniform distribution 본문

통계 공부/시뮬레이션

Random Number (1) : Uniform distribution

성균관_해태 2021. 3. 13. 17:07

통계적 시뮬레이션 수업의 내용을 바탕으로 이해한 바를 다시 정리해보자

(모든 내용은 성균관대 김재직 교수님의 수업 내용을 바탕으로 작성하였습니다!)

1. Uniform distribution을 따르는 Random number 생성하기

컴퓨터 연산을 통해서 random number을 만드는 방법에는 LCG와 MCG가 있다. 두개의 방법 모두 우리가 흔히
random이라면 떠올리는 무작위 시행이라기보다는, 수리적 계산을 이용해서 난수를 생성하는 방식이다.

(흔히 떠올리는 무작위 시행으로는 동전을 던진다던가, 룰렛을 돌린다던가 등이 있다)

 

 

1-1. LCG (Linear Congruential Generator)

쉽게 그림을 그리자면, 어떤 수 X를 다른 수 M으로 나누어서 생기는 0과 1사이의 값들을 이용하여 난수를 만들어내는 방식이다. 

 

(교수님 교안에서 가져온 알고리즘에 대한 설명)

X0를 먼저 지정한뒤, 2번의 식을 이용하여 차례로 X1, X2, X3, X4, X5 ... 을 만들어나가는 방식으로 구성되어 있다. 이때, 각각의 X는 지정된 수 m으로 나눈 나머지의 값을 갖게 된다. 때문에 모든 X들은 0부터 M-1의 값을 가지게 되고, 따라서 이들을 다시 m으로 나눈 u들은 [0,1] 값을 가지게 된다. 

 

만약 우리가 N개를 추출할 계획인데, N > m 인 경우에는 한 가지 생각해야하는 것이 있다. N이 m보다 클 경우, m만큼 동일한 숫자들이 반복적으로 추출된다. 간단한 예로 N이 20이라하고 m이 5라고 한다면, ([1,2,3,4,5], [1,2,3,4,5] ..) 와

같은 형식들로 반복되기 때문에 보통 m은 컴퓨터가 표현할 수 있는 가장 큰 숫자로 둔다.

 

1-2.  MCG (Multiplicative Congruential Generator)

LCG와 동일하지만, C가 없다고 생각하면 된다. [ X_n = a * X_n-1 mod m ] 식으로 구성되어 있으며, 이를 m으로 나누어

각각의 u들을 만들어내는 방식이다. 마찬가지로 m이 n보다 작을 경우 동일한 숫자가 반복되어 나타나게 된다.

이를 피하는 방법 중 하나는 m+1번째마다 새로운 seed값을 넣어서 새롭게 조합을 바꾸어 숫자를 생성할 수 있다.

 

2. 코드로 구현하기 (R)

## LCG

LCG <- function(seed, a, c, m, n){
  ## seed : initial number
  ## a,c : number for generating X
  ## m : number for mod
  ## n : number of random numbers
  
  x <- seed
  results = c()
  for(i in 1:n){
    new_x <- (a*x + c ) %% m
    x <- new_x
    uni_num <- new_x / m
    results <- c(results, uni_num)}
    
  return(results)
}

m을 n보다 큰 수로 두고 만 번의 시행을 했을 때, 실제로 uniform distribution과 비슷한 결과가 나온다.

 

(R의 runif 함수와 만든 LCG 함수의 비교)

##MCG

MCG <- function(seed, a, m, n){
  ## seed : initial number
  ## a : number for generating X
  ## m : number for mod
  ## n : number of random numbers
  
  x <- seed
  results = c()
  for(i in 1:n){
    new_x <- (a*x) %% m
    x <- new_x
    uni_num <- new_x / m
    results <- c(results, uni_num)}
    
  return(results)
}

( 직접만든 MCG와 runif 함수 비교)

MCG에서 조심해야할 것은 seed를 0으로 두면 전부 0이 되어 버리니, 0이상의 값을 넣어줘야 한다. 마찬가지로 LCG와 동일하게 나쁘지 않은 결과가 도출되었다.