'초기하분포'에 해당되는 글 1건

  1. 2015.09.13 R 초기하분포 (Hypergeometric distribution) : dhyper(x, m, n, k)

이산형 확률 분포에는

 

 - 이항분포 (Binomial distribution)

    : binom()

 

 - 초기하분포 (Hypergeometric distribution)

    : hyper()

 

 - 포아송 분포 (Poisson distribution)

    : pois()

 

등이 있습니다.

 

이전 포스팅에서 이산형 확률 분포(Discrete probability distribution) 중에서 베르누이 시행을 따르는 이항분포(binomial distribution)에 대해서 알아보았습니다.  이항분포는 모집단에서 표본을 추출하고 다시 샘플링한 표본을 다시 모집단에 집어넣고 (다른 말로 '복원') 또 표본 추출하는 작업을 하게 됩니다.  이렇다 보니 성공할 확률 p 가 항상 동일합니다.

 

그런데, 만약 모집단에서 표본을 추출하고 그것을 다시 모집단에 집어넣지 않는다면 (다른 말로 '복원하지 않는다면') 그때는 이런 과정을 베르누이 시행이라고 할 수가 없게 되고, 확률도 표본을 추출할 때마다 자꾸 바뀌게 됩니다.  쉽게 예를 들어서 빨간 공 5개, 파란 공 5개가 들어있는 주머니가 있다고 했을 때 처음에는 빨간 공이 뽑힐 확률이 5/10 = 0.5 이지만, 만약에 첫번째로 주머니에서 공을 하나 뽑았을 때 그것이 빨간 공이었다면 두번째에 뽑을 때 그것이 빨간공일 확률은 4/9 = 0.44444로 바뀌게 됩니다. (첫번째에 빨간공을 하나 뽑고 그것을 다시 주머니에 집어넣지(복원하지) 않았으므로...)

 

이처럼 성공확률이 p, 크기가 N인 모집단에서 n 개의 표본을 비복원으로 추출할 때 성공이 일어나는 횟수를 X라고 하면, X는 "모수 N, n, p인 초기하 분포를 따른다"고 합니다.

 

 

 

 

 

만약 초기하분포에서 성공이 일어날 확률 p를 일정하게 했을 때 모집단의 수 N을 무한대로 크게 하면 샘플을 복원추출하느냐 비복원추출하느냐가 별 의미가 없어지게 되므로 초기하분포는 이항분포로 근사하게 됩니다.  위의 예를 인용하자면 빨간공이 5억개, 파란공이 5억개 들어있는 주머니에서 공을 5개를 샘플로 뽑는다고 했을 때 1번째에 빨간공이 나왔을 때 2번째에 빨간공이 나올 확률은 복원추출이냐 비복원추출이냐가 성공확률 p에 거의 영향이 없다는 뜻입니다.  

 

따라서 모집단을 구성하는 개체가 성공(success, 1)/실패(failure, 0)의 두 가지 경우의 수만을 가지고 있는데, 모집단 N이 작을 때는 복원추출이면 이항분포, 비복원추출이면 초기하분포를 사용해야 하며, 만약 모집단 N이 충분히(?) 클 경우에는 초기하분포가 이항분포로 근사하므로 둘 중 아무거나 사용해도 대세에는 지장없다고 알고 있으면 되겠습니다.

 

 

초기하분포의 밀도 함수, 누적분포 함수, 분위수 함수, 난수 발생을 위한 R 함수 및 모수는 아래와 같습니다.

 

구분 

초기하분포 R 함수 / 모수 

 밀도 함수

d

  dhyper(x, m, n, k)

 누적분포 함수

p

  phyper(q, m, n, k, lower.tail = TRUE/FALSE)

 분위수 함수

q

  qhyper(p, m, n, k, lower.tail = TRUE/FALSE)

 난수 발생

r

  rhyper(nn, m, n, k)

 

* 참고: 모집단이 m과 n의 개체로 구성되어 있는데 k개의 표본을 추출

           lower.tail = TRUE 이면 확률변수 x를 기준으로 왼쪽 꼬리를 의미

 

 

초기하분포 그래프 (Hypergeometric distribution plot) 을 예로 하나 그려보면 아래와 같습니다.

 

 
> plot(dhyper(x=c(0:20), m=5, n=20, k=5), 
+      type='h', 
+      main = "Hypergeometric distribution, with m=5, n=20, k=5")

 

 

 

 

 

 

 

 

(1) P(X = 4) 확률 계산 : dhyper(x, m, n, k)

 

문제) 어떤 바리스타가 아메리카노 향 냄새를 맡아보기만 하면 "콜롬비아 원두"로 만든 것인지 아닌지를 맞출 수 있다고 주장하였다고 합니다.  그래서 그 바리스타를 데려다가 실험을 해보았습니다.  "콜롬비아 원두"로 만든 아메리카노 5잔 (m=5), 콜롬비아 원두 말고 다른 지역 원두로 만든 아메리카노 20잔 (n=20) 을 만들어 놓고 그 바리스타에게 "콜롬비아 원두"로 만든 아메리카노 5잔을 골라내 보라고 시켰습니다.  이때 "콜롬비아 원두"로 만든 아메리카노를 4잔 골라낼 확률은?

 

 
> dhyper(x=4, m=5, n=20, k=5)
 
[1] 0.001882176

 

 

이 문제의 경우 비복원추출에 해당하므로 초기하분포를 따른다고 볼 수 있으며, 총 25잔의 아메리카노 커피, "콜롬비아 원두"로 만든 것은 5잔인데 이 중에서 "콜롬비아 원두"로 만든 아메리카노를 4잔 골라낼 확률이 0.188% 이므로, 이 정도면 우연히 뽑아냈다고 보기는 힘들겠지요?  매우 예민한 코를 가진 바리스타라고 인정해줄 만 하겠습니다.

 

 

  

이해를 돕기 위해서 문제 하나 더 풀어보겠습니다.

 

문제 2) TV를 생산하는 제조회사에서 생산한 TV 100 대 중에서 품질이 양호한 TV가 95대, 불량품이 5대가 재고창고에 들어있다고 합니다.  이 재고 창고에서 TV 10개를 비복원추출한다고 했을 때 불량품이 3개가 포함되어 있을 확률은?

 

 
> dhyper(x=3, m=5, n=95, k=10)
 
[1] 0.006383528

 

 

 

 

 

(2) P(X <= 4) 확률 값 계산 : phyper(q, m, n, k, lower.tail=TRUE)

 

 

> # (2) P(X <= 4) 확률 값 계산 : phyper(q, m, n, k, lower.tail=TRUE)

 
> phyper(q=4, m=5, n=20, k=5, lower.tail=TRUE)
 
[1] 0.9999812
 

 

 

phyper() 함수를 사용하지 않는다면, 추천할만한 방법은 아니지만 좀 무식하게 dhyper()함수로 X가 0, 1, 2, 3, 4 일 때의 개별 밀도함수를 구해서 sum()해주는 방법을 사용해도 결과는 똑같습니다.  개념 이해하는데 참고만 하세요.

 

 

 
> dhyper(x=0, m=5, n=20, k=5)
 
[1] 0.2918125
 

> dhyper(x=1, m=5, n=20, k=5)
 
[1] 0.4559571
 
> dhyper(x=2, m=5, n=20, k=5)
 
[1] 0.214568
 
> dhyper(x=3, m=5, n=20, k=5)
 
[1] 0.03576134
 
> dhyper(x=4, m=5, n=20, k=5)
 
[1] 0.001882176
> 
 
 
 
> sum(dhyper(x=c(0:4), m=5, n=20, k=5))
 
[1] 0.9999812
 

 

 

 

(3) 특정 확률에 해당하는 분위수 구하기 : qhyper(p, m, n, k, lower.tail = TRUE/FALSE)

 

 
> dhyper(x=3, m=5, n=20, k=5)
 
[1] 0.03576134
> 

> qhyper(p=0.03576134, m=5, n=20, k=5, lower.tail=F)
 
[1] 3
 
#-------------------------------
 
> phyper(q=3, m=5, n=20, k=5, lower.tail = T)
 
[1] 0.998099
> 
 
> qhyper(p=0.998099, m=5, n=20, k=5, lower.tail=T)
 
[1] 3
 

 

위의 첫번째 예제를 보면 dhyper(x=3, m=5, n=20, k=5) = 0.03576134 입니다.  즉, m이 5개, n이 20개 들어있는 모집단에서 5번 비복원추출했을 때 확률변수 x가 3번 발생할 확률이 0.03576134라는 뜻입니다.

 

그런데 만약 확률 0.03576134를 알고 있을 때 이에 해당하는 확률 변수 x를 구하는 것이 위의 첫번째 예제에서 qhyper(p=0.03576134, m=5, n=20, k=5, lower.tail=FALSE) = 3 으로 문제를 푼 것입니다.

 

 

위의 두번째 예제에서는 phyper(q=3, m=5, n=20, lower.tail = T = 0.998099 로서 phyper() 함수를 사용했으므로 누적분포함수에 대한 확률을 계산한 것입니다.  이처럼 누적확률분포의 분위수를 계산하려면 이번에는 qhyper(p, m, n, k, lower.tail=TRUE) 처럼 lower.tail=TRUE 옵션을 설정해주면 되겠습니다.

 

 

 

(4) 난수 발생 : rhyper(nn, m, n, k)

 

m=5, n=20 인 초기하분포에서 비복원으로 5개를 추출하는 것을 1000번 모의실험한 후에 도수분포표를 구해보겠습니다.

 

 
> random_hyper <- rhyper(1000, m=5, n=20, k=5)
 
> random_hyper
 
   [1] 1 0 0 0 0 0 1 0 3 1 0 1 1 1 1 2 0 3 0 1 2 2 1 2 0 1 1 1 3 0 1 1 0 2 1 2 1 0 0 1 2 0 1 2 0 2
  [47] 1 2 1 1 1 1 2 1 1 2 2 1 1 2 1 0 1 1 1 3 1 0 1 1 0 0 1 1 0 1 2 0 0 0 1 1 0 1 1 0 1 0 0 1 1 1
  [93] 2 1 2 1 0 0 0 1 1 3 1 1 2 0 1 2 1 1 0 0 1 2 0 1 2 1 1 0 1 1 1 0 1 1 2 0 2 0 1 1 0 0 1 2 2 1
 [139] 0 2 2 1 3 0 2 2 1 1 0 3 0 0 1 1 1 0 0 2 2 0 3 0 3 2 0 0 0 2 1 1 1 1 1 0 0 0 0 0 0 0 1 1 0 0
 [185] 1 2 1 0 2 0 1 1 1 0 2 2 1 1 0 1 1 0 0 0 2 1 3 1 2 2 1 2 1 1 1 1 2 0 1 1 0 0 2 0 2 1 0 1 1 2
 [231] 2 2 0 3 1 1 1 2 1 3 2 1 2 1 2 0 0 1 0 0 1 2 2 2 1 1 1 4 1 2 0 2 1 1 1 1 1 1 1 1 0 1 0 2 0 0
 [277] 1 1 0 2 1 0 3 1 0 0 1 2 2 2 0 2 1 1 0 3 1 2 1 2 0 1 1 1 2 1 0 1 2 1 0 0 3 0 2 2 0 1 1 0 1 0
 [323] 2 2 1 1 3 1 1 0 1 2 0 0 0 0 0 3 2 0 2 2 1 1 1 2 1 0 1 1 2 0 0 1 2 0 0 2 1 2 1 2 2 2 1 1 0 1
 [369] 1 2 1 2 1 0 1 0 1 1 1 0 2 2 1 0 2 0 0 0 1 0 2 1 1 2 1 1 0 1 0 1 2 1 0 1 1 0 3 2 2 3 0 1 0 1
 [415] 1 0 0 0 2 2 1 2 1 1 1 0 2 2 2 0 1 2 3 2 1 1 0 1 1 1 1 0 1 2 3 1 0 1 2 2 0 1 1 2 1 0 2 1 0 1
 [461] 1 1 1 0 0 0 1 1 2 0 1 2 1 0 1 1 1 0 1 3 2 0 0 1 1 1 1 3 0 0 3 2 0 2 0 1 1 0 0 2 1 0 1 0 1 1
 [507] 0 1 1 2 1 1 1 1 1 2 0 0 1 2 0 1 0 1 0 1 1 1 1 0 1 3 0 1 0 1 2 3 1 1 1 2 0 2 1 1 0 0 2 2 2 0
 [553] 1 1 1 0 1 0 1 0 1 1 0 2 0 0 1 1 2 1 1 0 0 0 1 1 1 1 3 2 0 2 0 2 0 2 1 0 0 1 2 1 1 2 1 0 0 2
 [599] 0 0 0 1 1 2 1 1 2 2 1 0 1 3 1 2 2 2 2 1 0 2 1 4 3 3 0 3 1 2 2 1 1 2 1 2 3 2 2 0 1 1 2 3 1 0
 [645] 1 1 2 1 1 1 1 1 1 1 2 1 1 2 0 2 2 1 2 0 1 0 3 2 0 2 1 0 1 1 0 0 0 1 1 0 3 0 2 1 1 1 2 1 1 0
 [691] 1 0 1 1 0 2 2 1 1 2 0 0 0 2 0 1 1 3 0 0 1 2 0 0 0 2 1 2 0 1 1 1 0 2 2 1 3 0 1 3 2 0 1 2 1 1
 [737] 1 0 1 1 2 1 1 1 2 1 1 1 0 2 0 1 1 1 0 2 0 1 1 0 1 1 1 1 1 0 0 0 2 0 0 1 2 1 2 0 1 1 1 0 0 0
 [783] 1 1 1 0 0 0 3 0 2 1 2 1 1 1 0 1 1 1 0 1 0 0 2 0 1 4 0 1 0 1 2 0 2 0 1 1 1 1 1 0 2 2 1 1 2 1
 [829] 0 0 0 1 2 2 1 2 1 1 1 0 2 1 1 1 1 1 3 1 1 2 1 2 1 3 1 0 1 1 0 3 0 0 1 1 2 1 0 0 0 0 1 1 1 2
 [875] 3 0 1 0 0 1 0 0 2 0 1 0 1 0 0 0 0 0 2 0 1 2 0 2 0 1 1 1 0 0 0 1 1 2 2 2 1 0 1 3 1 2 1 1 2 1
 [921] 3 0 1 2 2 1 0 1 1 0 0 2 1 0 0 1 2 1 1 1 1 1 1 0 0 1 1 0 0 1 2 0 1 2 1 2 1 1 0 1 1 0 0 0 1 1
 [967] 2 1 1 0 0 0 2 1 1 0 0 2 1 1 0 2 2 2 0 1 2 2 0 2 3 2 2 1 0 1 1 0 0 0
 
 
> table(random_hyper)
random_hyper
  0   1   2   3   4 
302 434 215  46   3

 

 

많은 도움 되었기를 바랍니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡'를 꾸욱 눌러주세요. ^^

 

 

728x90
반응형
Posted by Rfriend
,