ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 04-7 정규분포 그래프 그리기 : matplotlib를 활용한 데이터 시각화 그리고 확률 밀도 함수
    데이터 분석/파이썬으로 배우는 데이터 분석을 위한 통계학 2022. 3. 22. 22:58

     이제 이 단원의 마지막이야! 끝이 멋있어야지? 정규분포 그래프를 그려볼거야!

     

     일단 정규분포 그래프를 그리기 위해선 표준화를 해야 될 거고, 표준화를 하기 위해선 원점수가 필요할거야. 여태까지 배운 내용들을.. 기억하지?

     

     기억이 잘 나지 않을수도 있으니까 정리해 줄게!

     

     1. 원점수들이 있다면, N(점수들의 총 개수)와 m(산술 평균)을 구할 수 있다.

     2. N과 m을 안다면 v(분산)과 s(표준편차)를 구할 수 있다.

     3. m과 s를 안다면 원점수를 표준화 할 수 있다.

     4. 표준화를 한다면 표준정규분포표를 이용해 백분위를 쉽게 알 수 있다.

     

     그럼 원점수들을 가지고 직접 그래프를 그려보면 뭔가 보이지 않을까..?

     

     대신 이번에는 준비된 데이터가 아니라 동전을 던져 볼거야. 동전을 10번 던졌을 때 앞면이 나오는 횟수는 어떻게 될까?

     정말 운이 없다면 10번 모두 뒷면이 나올 수도 있을거야. 반대로 정말 운이 좋다면 10번 모두 앞면이 나올 수도 있을거구. 동전을 던졌을 때 앞면이나 뒷면이 나올 확률은 1/2이기 때문에 앞면이든 뒷면이든 10번 모두 같은 면이 나올 확률은 1/2의 10승이 되겠지? 1/1024 말야.

     그럼 동전을 10번 던졌을 때 딱 한 번만 앞면이 나오고 9번은 뒷면이 나온다면? 첫 번째 던졌을 때만 앞면이 나오고 나머지 9번은 뒷면이 나올 수도 있고, 아니면 두 번째 던졌을 때만 앞면이 나오고 나머지 9번은 뒷면이 나올 수도 있지. 이런 경우가 10개야. 어차피 앞면이 나올 확률과 뒷면이 나올 확률은 같으니, 1/2의 10승에서 경우의 수를 곱해주면 되겠다. 10/1024가 되겠네.

     마지막으로 동전을 10번 던졌을 때 앞면과 뒷면이 반반씩 나올 확률은 어떻게 될까? 전체 경우의 수가 1024이고 앞면이나 뒷면이 5번 나오는 경우는 10C5(C:combination)로 252가 돼. 252/1024가 되겠네!

     이런 확률들을 표로 정리해 볼게.

     

    동전 10개를 던졌을 때의 확률
    앞10 뒤0 앞9 뒤1 앞8 뒤2 앞7 뒤3 앞6 뒤4 앞5 뒤5 앞4 뒤6 앞3 뒤7 앞2 뒤8 앞1 뒤 9 앞0 뒤10
    1/1024 10/1024 45/1025 120/1024 210/1024 252/1024 210/1024 120/1024 45/1025 10/1024 1/1024

     

     어차피 앞면이 3번 나오나 뒷면이 3번 나오나 확률은 같기 때문에 앞면이 5개, 뒷면이 5개 나올 확률을 기준으로 대칭적인 표를 만들 수 있어. 그럼 이 숫자들을 가지고 그래프를 그릴 수 있지 않을까?

     

    -

     

     먼저 동전 10개를 던졌을 때의 확률을 살펴봐야 하는데.. 이 숫자들을 그대로 파이썬으로 옮기기엔 너무 귀찮지? 그리고 우리는 동전이 10개가 아니라 100개, 1000개일 때도 살펴볼건데.. 그런 확률들을 일일히 구하는게 귀찮잖아. 그래서 파이썬의 모듈을 활용해서 조합(combination)을 쉽게 계산해 볼거야.

     방법은 간단해. 파이썬 기본 라이브러리의 'itertools' 라는 모듈을 사용하면 되지! 조합은 itertools 모듈의 'combinations' 함수를 사용하면 쉽게 구할 수 있어 같이 해 볼까?

     

     일단 동전이 10개니까 10개의 숫자가 담긴 리스트를 하나 만들어 줄거야. 우리가 배운 리스트와 for문을 사용하면 1부터 10까지 숫자를 담은 리스트를 만들 수 있겠지? 아래의 코드처럼 말야.

     

     

    하지만 이 방법은 파이썬 스러운 방법은 아니야. 파이썬 스럽다는 것은.. 파이썬에서 허용되는 문법으로 다른 언어보다 더 쉽게 코드를 구현할 수 있는 방법을 뜻 해. 아래의 코드가 파이썬 스러운, '리스트 컴프리헨션(comprehension)'으로 작성한 코드야. 결과나 내용은 위의 코드와 같아

     

     

    두 코드 모두 똑같이 1부터 10까지의 정수를 담았어. 하지만 아래의 코드가 훨씬 간단하지? 앞으로는 아래의 코드 처럼 컴프리헨션을 사용해서 작성하는 일이 종종 있을 거니까 기억해 둬!

     

     동전 10개가 준비 되었다면 앞면과 뒷면의 조합이 어떻게 되는지 살펴봐야겠지?

     조합을 사용하기 위해 itertools 모듈에서 combinations를 import 해 볼게.

     

     

     'combi'에 nums에서 0개의 항목을 선택하는 경우의 수, 즉 10C0을 담아놓고 출력하려고 했더니!

     

    <itertools.combinations object at 0x7f5b51bfe4a0>

     

     라고 출력되는 것을 볼 수 있어. combi에는 itertools.combinations의 객체(object)가 담겨있다는 뜻이야. 우리가 알고 싶은 것은 경우의 수, 즉 이 객체의 항목들의 길이가 되겠지? 길이는 'len()' 함수를 사용하면 알 수 있을 테지만, 이 객체는 리스트가 아니라서 리스트의 형태로 변환해 준 다음 len() 함수를 이용해야 돼. 아래의 코드처럼 말야.

     

     

    combi 의 길이를 출력 했더니 1이 출력 되었네! 1이 뜻하는 바는 10개의 동전을 던져서 앞면이 하나도 나오질 않는 경우의 수를 뜻 해. 동전 10개를 던져서 나오는 모든 경우의 수가 1024개 였으니, 확률은 1024분의 1이 되겠지? 전체 경우의 수를 'total'이라는 마지막으로 확률까지 계산해서 출력해 보면 아래의 코드와 같을거야.

     

     

     우리는 동전 10개를 던져서 앞면이 한 번도 나오질 않을 확률을 구해봤어. 그럼 앞면이 1번 나오거나 2번 나오는 경우들도 전부 다 구할 수 있겠지? 'pers'라는 리스트에 위에서 만든 표와 같은 형태의 확률들을 담아볼까?

     

     

     출력 결과를 보니 0.24609375를 기준으로 대칭은 확률값들을 구할 수 있었어! 우리가 위에서 표로 정리했던 내용과 같지? 그리고 이 확률들을 다 더하면 전체를 뜻하는 1이 나올거야. 당연하겠지만 말야.

     

     우리는 이제 이 확률값들을 가지고 그래프를 그려 볼거야. 그래프를 그리기 위해서는 'matplotlib' 라는 라이브러리를 사용할건데 이 맷플롯 라이브러리는 파이썬에서 데이터 시각화를 위해 정말 많이 쓰이는 라이브러리니까 꼭 기억해! matplotlib의 'pyplot' 모듈을 사용하면 그래프를 쉽게 그릴 수 있어. 일단 그래프의 껍데기를 만들어 볼까?

     

     그래프의 껍데기를 그리기 위한 함수들로는

     

    pyplot.title('그래프 제목')
    pyplot.xlabel('x축 레이블')
    pyplot.ylabel('y축 레이블')
    pyplot.grid() # 그리드 추가

     

     이런 것들이 있어. 어떻게 그려지는지 아래의 코드를 실행해 볼까?

     

     

     코드를 실행하면 그래프의 틀과 범례등이 자동으로 시각화 되는 것을 볼 수 있어! 어때? 굉장하지! 여기에 값을 추가하면 어떻게 하면 될까? 먼저 X와 Y라는 값들을 만들어 줄거야. 값은 하나만 있어도 되지만 중요한 것은! X와 Y가 일대일 매칭이 되어야 돼. X값들이 10개 있다면 Y값들도 10개 있어야 하다는 거야. 그래야 2차원 좌표평면 상에 점을 찍을 수 있으니까!

     그래프에 점을 찍기 위해선 'scatter()' 함수를 사용하면 돼.

     

    scatter(X, Y)

     

     X와 Y의 데이터가 일대일 매칭이라면 그래프에 점을 찍을 수 있어 아래의 코드처럼 말야!

     

     

     X의 1은 Y의 6과, X의 2는 Y의 7에 대응하고 있어. 순서대로 일대일 매칭의 순서쌍으로 나타내면,

     (1, 6), (2, 7), (3, 8), (4, 9), (5, 10)

     과 같아. 위의 순서쌍 좌표를 그래프의 나타낸 것이 실행 결과이지! 어렵지 않지?

     

     이번에는 그래프에 선을 그려 볼게. 선은 점과 점을 연결하면 되겠지? 선을 그릴 떈 'plot()'이라는 함수를 사용하면 돼. 

     

    plot(X, Y)

     

     좌표는 X와 Y로 준비되어 있기 때문에 그대로 사용하면 돼. 아래의 코드처럼 말야.

     

     

     대신 이번에는 선과 점을 구분하기 위해서 점을 빨간색으로 표시해 줬어. scatter() 함수에 'color='red''가 추가된게 보이지?

     

     맷플롯 라이브러리를 사용해서 그래프 그리는 법을 배웠으니까 본격적으로 우리가 가지고 있는 확률 데이터로 그래프를 그려볼까? X축은 앞면의 개수, Y축은 그에따른 확률이라고 해 볼게. 확률값은 위에서 한 번 구했기 때문에 그 과정을 그대로 가져다 쓰면 돼.

     

     

     앗! 이 모양은!

     우리가 전 시간에 배웠던 '표준정규분포'와 매우 흡사하게 보여! 우연일까?

     

     아니야. 앞서 우리가 구해본 확률값들에 대해 그래프를 그렸더니 정규분포를 따르잖아. 이것이 '확률밀도함수'의 개념이야. 연속된 확률변수의 분포를 나타내어보면 정규분포를 따를 수 밖에 없다는 것이지. 자세한 내용은

     

    https://ko.wikipedia.org/wiki/확률_밀도_함수

     

    확률 밀도 함수 - 위키백과, 우리 모두의 백과사전

     

    ko.wikipedia.org

     위 링크를 참고하면 돼!

     

     이제 정규분포의 놀라움에 대해 감이 오지? 다음 시간부터는 또 다른 재미있는 것에 대해 다뤄보도록 할게! 안녕!

Designed by Tistory.