Data Science!/이론

[수학] 파이썬으로 배워보는 확률 - 3편 중심극한정리 (난이도 : 중상)

양국남자 2021. 9. 23. 22:30

인터넷을 좀 하신 분들이라면, 세상은 정규분포 라는 말을 한번쯤은 들으셨을겁니다. 짤방으로도 유명하죠.

 

예시를 들어보자면 전 주변에 롤 골드 이상이 많았습니다.(저도 골드 3) 하지만 현실 유저는 브실이 대다수라고 하죠. 누구 롤 못한다 갈구기 전에 제가 과몰입자가 아닌지 먼저 보라는(...) 짤방입니다.

 

이 현상을 수학적으로 유식하게 말하자면 중심 극한 정리 라고 합니다. 1강에서 확률의 정의 언급할때 나온 수학자 라플라스의 정의를 빌리자면, 수많은 독립 확률 변수 n개의 평균의 분포는 n 이 적당히 크다면 정규분포에 가까워진다는 정리입니다. 어렵게 들리지만, 저번에 했던 부루마불 시뮬레이션으로 돌아가 봅시다. 주사위 하나를 굴릴때, 모든 눈의 확률은 1/6 으로 동일했습니다. 하지만, 주사위 두개를 굴리는 순간 분포가 어떻게 변했나요? 

 

7을 중심으로 솟은 정규분포 커브가 됩니다.

7이 가장 많이 나오는 정규분포 표로 변했던 걸 기억하실 겁니다. 주사위의 눈들은 상호간에 영향을 주지 않는 독립 확률을 따르는데, 두개만 굴려도 정규분포 표로 변하는 마법을 볼 수 있었습니다.

 

진짜 세상이 정규분포인지 실습을 통해 검증해 봅시다.

 

프로젝트에 넣을 까 했는데, 그냥 여기서 실습을 하나 해 봅시다.

일단, 개발 환경을 구축해 줍시다.

 

#그래프를 그리기 위해 matplotlib 를 임포트 해줍니다.
%matplotlib inline 
import matplotlib.pyplot as plt
from statistics import mean
from random import normalvariate, triangular, choice, vonmisesvariate, uniform

#정규분포 함수 정의해줍시다.
def normal(mu=0, sigma=1): return random.normalvariate(mu, sigma)

#히스토그램 그리는 함수
def repeated_hist(dist, n=10**6, bins=100):
    samples = [dist() for _ in range(n)]
    plt.hist(samples, bins=bins, density=True)
    plt.title('{} (μ = {:.1f})'.format(dist.__name__, mean(samples)))
    plt.grid(axis='x')
    plt.yticks([], '')
    plt.show()

 

재미를 위해 좀 대중적인 소재를 가지고 실습을 해 봅시다. 농구 어때요? 다섯명의 선수의 득점 확률은 비종속 독립 변수잖아요? 커리가 넣는다고 듀런트가 못 넣고 그 반대는 일어나지 않으니까요.

 

빅데이터, AI등에 입문하게 된 계기가 된 스테픈커리 짤입니다... 스테판커리, 제임스하든, 같은 수백억원의 인간병기를 부리는 병법을 만들 수 있단 말이지...?

 

골든스테이트 워리어스가 NBA 역사에 족적을 남긴 2015~2016 시즌 실제 데이터 기준으로 선수들의 득점분포를 무작위로 생성해봤습니다.

 

#골든스테이트 워리어즈 4명에 치트선수 하나 재미로 넣었습니다.
def stephen_curry(): return max(0, normal(12.1, 3) + 3 * triangular(1, 13, 4))                     # 30.1
def klay_thompson(): return max(0, triangular(8, 22, 15.3) + choice((0, 3 * triangular(1, 9, 4)))) # 22.1
def draymond_green(): return max(0, vonmisesvariate(30, 2) * 3.08)                                  # 14.0
def harrison_barnes(): return max(0, choice((normal(6.7, 1.5), normal(16.7, 2.5))))                  # 11.7
def yangguk_cheat(): return max(0, normal(17, 3) + uniform(0, 40))                                 # 37.0
#마지막은 치트선수 양국남자입니다. 치트선수라서 스테픈커리보다 잘해요.

team = (stephen_curry, klay_thompson, draymond_green, harrison_barnes, yangguk_cheat)

def Team(team=team): return sum(player() for player in team)

마지막 5번째 선수는 정규분포를 깰 기대를 가지고 영입된 치트선수 양국남자 입니다.

 

#도표를 그려줍시다.
for player in team: 
    repeated_hist(player, bins=range(70))

역시 사기 치트선수 양국남자가 잘하긴 하는데... 양국남자 이미 약간 정규분포의 냄새가 납니다. 스테픈 커리 역시 약간 왼쪽 정규분포 그래프 같네요.

 이제는 골든스테이트 워리어스의 득점을 다 더해서 분포 그래프를 그려 줍시다.

#득점을 더해서 분포 그래프를 그려줍시다
repeated_hist(Team, bins=range(50, 180))

득점은 정규분포

 

정규분포 그래프가 나오네요. 치트 선수 양국남자도 정규분포의 세상에서 도망칠 수 없었습니다.

 

이상 확률 강의는 마치고, 다음에는 데이터사이언스 이론 강의로 뵙겠습니다.

 

확률 ipynb 파일은 Google Colab 에서 열람하실 수 있습니다.