ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 07-3 파이썬으로 표집 분포 구하기
    데이터 분석/파이썬으로 배우는 데이터 분석을 위한 통계학 2022. 4. 13. 18:29

     물론 이론적 표집 분포는 이론일 뿐이지. 모집단에서 표본집단을 무수히 추출해서 표집 분포를 구해내는 것이 불가능 하니까. 그럼 무조건 경험적 표집을 해야만 할까?

     

     이전 시대에는 불가능 해 보였던 일들이 기술의 발전으로 가능해 졌어. 무수히 많지는 않지만 옛날 사람들에게는 무수히 많은 것 처럼 보일만큼의 일들을 컴퓨터가 해낼 수 있게 되었거든. 우리가 지금 통계학을 배우는 목적이기도 하지. 데이터 분석을 위한 통계학!

     

     우리는 앞서 김교수의 갑작 시험의 사례를 통해 표본을 10번 추출하는 것만으로도 평균(mean)들의 평균이 모집단의 평균(mu)와 비슷해 지는 것을 보았어. 그렇다면, 10번이 아니라 100번, 1000번, 그 이상의 표본들로 표집 분포를 구해보면 어떨까? 과거에는 불가능 하다고 생각되었던 일들을 해 보면 어떨까?

     

    -

     

    random 모듈

     

     먼저 우리는 무선 표본추출을 위해 random 모듈에 대해 배울거야. random 모듈은 말 그대로 무작위 적인 것들을 할 수 있게 해 줘. 간단한 것 부터 해볼까?

     

    -

     

    randint()

     

     1부터 6까지의 숫자가 있어. 여기서 하나의 숫자를 무작위로 고를거야. 이 때는 random 모듈의 randint() 함수를 쓰면 돼. 정육면체 주사위가 있다면 주사위를 굴리면 쉬울텐데..

     

    randint(a, b)

     

     randint() 함수는 a부터 b까지의 정수 범위 중에서 하나의 숫자를 무작위로 뽑아서 돌려주는 함수야. 아래의 코드를 실행해 볼까?

     

     

     위의 코드를 실행시켜 보면 실행할 때 마다 1/6 확률로 1, 2, 3, 4, 5, 6 중에서 하나의 숫자가 출력되는 것을 볼 수 있어. 무작위라는 뜻이 각 요소들이 모두 같은 확률을 가지고 있다는 뜻이니까 말야! 와! 파이썬으로 주사위를 만들었네!

     

     이번에는 리스트를 활용해 볼 거야. 1, 2, 3, 4, 5, 6 이라는 숫자들이 담겨있는 리스트에서 하나의 항목을 무작위로 뽑을거야. 일단 우리가 배운 randint() 함수를 활용해 볼까? 리스트의 인덱스를 활용하면 하나의 숫자를 뽑을 수 있겠지? 단, 리스트의 첫 번째 항목의 인덱스가 0부터 시작한다는 것을 잊지마!

     

     

     numbers라는 리스트에 1부터 6까지의 정수를 담아놨어. 그리고 randint() 함수를 통해 0부터 5까지의 정수 중에서 하나의 숫자를 고르는거지. 마지막으로 numbers에서 이 무작위의 정수를 인덱스로 가지고 있는 항목을 출력해 주기만 하면 돼. 간단하지?

     

    -

     

    choice()

     

     또 다른 방법은 random 모듈의 choice() 함수를 사용하는거야.

     

    choice(seq)

     

     choice() 함수는 소괄호 안의 시퀀스에 속한 요소 중에 하나를 무작위로 골라줘. numbers 라는 시퀀스를 활용해서 choice() 함수로 하나의 숫자를 무작위로 고른다면 아래와 같을거야.

     

     

     어때? 활용할 시퀀스가 있는 상태라면 randint() 함수로 인데스를 활용하는 것 보다 choice() 함수를 활용하는 것이 더 직관적이지? 하지만 randint() 함수도 써먹을 곳이 많으니 꼭 알고 있어야 돼!

     

    -

     

    choices()

     

     다음으로는 choice()와 비슷한 choices() 함수를 사용해 볼거야. 둘의 차이는 함수 이름만 봐도 알 수 있겠지? 하나의 요소가 아니라 여러개의 요소를 무작위로 돌려주는 함수야.

     

    choices(population, k=몇개?)

     

     주의할 점은 choices() 함수에서는 표본의 크기를 'k'라고 했는데, 우리가 배우는 과정에서는 표본의 크기, 즉 표본 집단이 가지고 있는 요소들의 개수는 'n'이라고 했잖아? 이게 서로 헷갈릴 수 있을거 같아.. 그래서 되도록이면 choices() 함수는 사용하지 않으려고 해..

     암튼 choices() 함수는 모집단(population)에서 k번 무작위로 뽑아줘. 만약 모집단이 numbers이고 3번 무작위로 뽑아서 숫자들을 만든다면 아래와 같은 코드로 구현할 수 있어.

     

     

     실행해 보면 numbers에서 3개의 숫자를 무작위로 뽑아내는 것 처럼 보이지만, 실행하다보면 중복으로 숫자가 뽑혀서 나오는 것을 볼 수 있어. 이런 추출을 복원 추출 (sampling with replacement) 이라고 해. 뽑히는 집단은 그대로 있고 그때 그때 마다 정해진 확률로 뽑아내는거지!

     

    -

     

    sample()

     

     하지만 이렇게 복원 추출을 하면 우리가 원하는 표본을 얻을 수 없잖아? 표본 추출을 할 땐 중복으로 뽑히면 안되니까 말야. 그래서 이번에는 sample() 이라는 함수를 사용할거야. 사용법은 choices() 함수와 거의 같아.

     

    sample(population, 몇개?)

     

     sample() 함수는 choices() 함수와 달리 비복원 추출 (sampling without replacement) 을 하게 해줘. 뽑히는 집단에서 뽑히는 놈을 뽑아냈다면, 그 놈은 더이상 뽑히는 집단에 없는거야. 뽑아 낸 순간 모집단이 달라진거지. 우리가 원하던 것이군! 코드도 choices() 코드와 문법이 같으니 쉽게 작성할 수 있겠다!

     

     

     이번에는 위의 코드를 아무리 많이 실행시켜보아도 중복으로 숫자가 뽑히지 않는 것을 볼 수 있어. 아주 좋지?

     

    -

     

    경험적 표집 분포와 이론적 표집 분포 그 사이 어딘가

     

     필요한 것들을 다 배웠으니 김교수의 갑작 통계 시험의 점수를 가지고 표집 분포를 만들어 볼까? 이번에는 통계적 수치들을 쉽게 구할 수 있는 statistics 라이브러리를 활용해 볼게. 전에 한 번 써 봤던 라이브러리지? statistics 라이브러리를 활용해서 모집단의 평균 M과 모집단의 표준편차 S를 구해 볼거야.

     모집단은 학생 20명의 점수로 할게.

     

    [6, 9, 0, 3, 1, 5, 7, 7, 1, 3, 2, 5, 1, 2, 1, 2, 7, 8, 1, 7]

     

     여러분들도 직접 모집단의 평균과 표준편차를 구해봐!

     

     

     

     코드를 실행해 보면 M은 3.9, sigma는 약 2.81로 출력되는 것을 볼 수 있어. 만약 라이브러리를 사용하지 않고 직접 표준편차를 구했는데 약 2.88이 나왔다면 N이 아니라 n-1로 나눈 것이니 조심해야 돼! 모집단의 분산을 구할 땐 N으로 나누고, 표본집단의 분산을 구할 땐 n-1로 나누는 자유도의 개념!

     

     다음으로는 모집단에서 4명의 학생들을 뽑는 표본 추출을 해 볼거야. random 모듈의 sample() 함수를 사용하면 간단하게 뽑을 수 있겠지? 우리도 4명씩 10개의 표본 추출을 해 보자구!

     

     

     코드가 무식하지만 암튼 10개의 표본을 순식간에 만들었어! 하지만 100개, 1000개로 많아지면 이렇게는 못하겠지? 반복문을 이용해서 코드를 줄여 볼게! 이왕 줄이는거 표본들의 평균도 같이 출력해 보자구!

     

     

     for문을 이용해서 쉽게 10번으로 늘렸다면 100번으로도, 1000번으로도 쉽게 늘릴 수 있겠지?

     

     이제 이 표본들의 평균을 가지고 표본들의 평균들의 평균도 구해보고 표본들의 평균들의 표준편차도 구해볼게!

     

     

     표본들의 평균들의 평균은 mean_of_means에, 표본들의 평균들의 표준편차는 stdev_of_means에 담아서 출력해 봤어. 그랬더니 정리된 수치들이 이쁘게 출력되는 것을 볼 수있네!

     

     마지막으로 표본의 크기와 표본의 개수까지 사용자에게 입력받아서, 과거에는 불가능해 보였던 표본의 개수까지 만들어 볼까? 단, 표본의 크기(표본 집단의 요소들의 개수)는 n으로, 표본의 개수(표본 집단들의 개수)는 k로 정해줬어. 위에서 사용했던 choices() 함수와는 다르지? 암튼 여러분들이 직접 수치를 입력해봐! 10만개는 어때? (100만개는 너무 오래 걸리니 하지 마세요..)

     

     

     나는 위의 코드에서 표본의 크기를 4, 표본의 개수를 10만개로 정하고 코드를 실행해 봤어. 시간이 약간 걸렸지만 그래도 수 초 만에 결과가 출력되는 것을 볼 수 있었지. 과거의 통계학자들은 꿈도 꾸지 못했을 만큼의 계산을 지금 시대에서는 프로그래밍을 조금 배운 중학생들도 할 수 있게 되었으니 참 세상 좋아졌어. 옛날 통계학자들이 보면 아주 놀라워 하겠지?

     

     표본의 크기를 4로 하고 표본의 개수를 10만개로 정해서 실행시켜 봤더니 표본들의 평균들의 평균은 약 3.9였어. 모집단의 평균 M과 거의 같았지. 여러번 반복해서 코드를 실행해 봐도 결과는 비슷했어. 표본의 크기가 커질수록, 표본의 개수가 커질수록 평균은 모집단과 비슷해 지겠지. 10만개 까지 안가도 돼. 표본의 크기가 4일 때 표본의 개수가 1만개만 되어도 굉장히 비슷해 지거든.

     

     어때? 통계학을 그냥 배우는 것 보다 프로그래밍으로 배운다면 새로운 경험을 할 수 있겠지? 아주 놀라운 일이야. 교과서, 전공책에서 배웠던 '경험적'이라는 단어와 '이론적'이라는 단어 사이의 차원을 경험할 수 있는 거니까 말야!

     

     안뇽~

Designed by Tistory.