ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 8. 표본 분포, 중심극한정리
    초간단 통계 2022. 12. 8. 15:01
    반응형

    모집단의 모수를 추정하기 위해 표본을 추출했다. 

    표본이라는 건 모집단과 비슷할수록 좋은 표본일 거다...
    상식적으로 표본의 크기가 클수록 모집단과 가까워진다는 것은 당연한데...

    표본을 키우는 방식 말고 조금 다른 방향으로 접근해 보자.  

    표본을 여러 개 추출하는 것에서 시작하자.
    똑똑한 분들이 여러 개의 샘플들의 분포에서 뭔가 경향성을 찾았거든...  

    1~1000번까지 1000명의 사람이 있고
    10명씩으로 구성된 표본을 수십 ~ 수백 개 ~ 또는 그 이상 추출한다고 생각하자. 

    표본의 크기는 모두 같고 표본은 겹칠 수 있다.
    즉 1번 사람이 여러 표본에 포함될 수도 있다. 

    표본을 매우 많이 (극한) 추출할 때
    이 표본 각각의 평균들은 정규분포를 드러낸다.

    이를 중심 극한 정리라고 한다. 

    이것이 재미있는 것은
    모집단이 어떤 분포를 가지던지 (=모집단의 분포와 상관 없이)
    표본의 평균으로 만든 분포는 정규분포를 가진다는 것....
    (이 이유는 차후에 알아보자....)

     

    https://namu.wiki/w/%EC%A4%91%EC%8B%AC%EA%B7%B9%ED%95%9C%EC%A0%95%EB%A6%AC?from=%EC%A4%91%EC%8B%AC%20%EA%B7%B9%ED%95%9C%20%EC%A0%95%EB%A6%AC 

     

    중심극한정리 - 나무위키

    이 저작물은 CC BY-NC-SA 2.0 KR에 따라 이용할 수 있습니다. (단, 라이선스가 명시된 일부 문서 및 삽화 제외) 기여하신 문서의 저작권은 각 기여자에게 있으며, 각 기여자는 기여하신 부분의 저작권

    namu.wiki

     

    먼저 모집단이
    '균일 분포'에 가까울 때
    표본 평균의 분포를
    코드로 확인해 보자. 

     

    먼저 균일 분포를 ...

    randint(a,b,c)는 a이상 b이하의 숫자를 랜덤으로 c개 뽑는 함수이다.  
    랜덤은 각 숫자의 뽑힐 확률은 같다는 의미. 

    아래의 코드는 1 이상 1000 이하의 숫자를 랜덤으로 십만 회 뽑은 뒤
    이 숫자들의 히스토그램을 출력해 본 것이다. 
    세로축은 숫자들이 등장한 횟수(도수)이며, 
    가로축은 숫자 값(계급), 100개의 계급으로 나누었다. 

    10만 회를 100개의 계급으로 나누었으니
    계급당 1000 정도의 도수이다. 

    히스토그램으로 확인하면 이것이 균일 분포에 가까움을 쉽게 알 수 있다. 

    import matplotlib.pyplot as plt
    import numpy as np
    
    plt.hist(np.random.randint(1, 1000, 100_000), bins=100)
    plt.show()

     

    표본 평균의 분포를 코딩해 보자. 

    1. 1~1000까지 숫자 중에 중복 가능한 10개를 랜덤으로 뽑는다. (=샘플)
    2. 샘플의 평균을 구해서 temp 배열에 집어넣는다. 
    3. 1, 2를 1000회 반복한다.
    4. temp의 히스토그램을 출력한다. 
    import matplotlib.pyplot as plt
    import numpy as np
    
    temp = []
    for _ in range(1000):
        temp.append(np.mean(np.random.randint(1, 1000, 10)))
    plt.hist(temp, bins=100)
    plt.show()

    1000회로는 약하다~!

    10000회... 고고

    import matplotlib.pyplot as plt
    import numpy as np
    
    plt.hist([np.mean(np.random.randint(1, 1000, 10)) for _ in range(10000)], bins=100)
    plt.show()

    10만회 정도 되면 누가 봐도 정규분포. 

    import matplotlib.pyplot as plt
    import numpy as np
    
    plt.hist([np.mean(np.random.randint(1, 1000, 10)) for _ in range(100_000)], bins=100)
    plt.show()

     

    왜 이럴까?

    모집단이 어떤 분포를 가지던지 간에
    표본 평균의 분포는 정규분포가 나오는 이유는 뭘까....

    이 페이지에서 일단 확인을... 

    https://onlinestatbook.com/stat_sim/sampling_dist/index.html

     

    Sampling Distributions

     

    onlinestatbook.com

    이렇게 이상한 모집단을 만들어 줘도.... 
    샘플 평균의 분포는 정규분포가 된다. 

    샘플은 모집단의 모양과 어느 정도 비슷하게 나오지만... 이와 상관 없이.
    '샘플의 평균'은 샘플 구성원의 가운데에 즈음에 있고,
    샘플을 수없이 뽑다 보면 이 샘플들의 평균 또한 가운데 모이기 때문에...
    '샘플의 평균'의 분포는 정규 분포를 가지게 된다. 

    그리하야... 샘플을 아주 많이 뽑으면...
    표본 평균의 평균모집단의 평균과 같아진다... 

    이건 직관적이니까 바로 이해가 될 것 같고...

    중심 극한 정리에서 재미있는 점 중 하나가
    모집단의 평균과 표준 편차를 알면 표본 평균의 표준 편차를 알 수 있는 점이다. 

    표본 내의 원소의 갯수가 많아질수록 표본 평균의 표준 편차가 작아짐은 충분히 이해가 갈 것이라 생각된다...  

    모집단에서 표본 1개씩을 (수십만 번) 뽑은 뒤 그 평균의 편차를 내고 분산을 계산한다고 생각하면...   
    모집단에서 표본 2개씩을 (수십만 번) 뽑은 뒤 그 평균의 편차를 내고 분산을 계산한다고 생각하면...   
    모집단에서 표본 3개씩을 (수십만 번) 뽑은 뒤 그 평균의 편차를 내고 분산을 계산한다고 생각하면...   
    .
    .
    .
    표본이 점점 커져서 모집단의 1/3 정도의 크기가 된다면...
    표본이 점점 커져서 모집단의 1/2 정도의 크기가 된다면...
    표본이 점점 커져서 모집단의 정도의 크기가 된다면...
    분산과 표준편차는 점점 줄어들 것을 예상할 수 있다.
    (표본 내 원소 중복 가능, 표본 크기는 균일) 

    그 줄어듬을 똑똑한 분들이 열심히 계산해주셨다. 
    표본 평균의 표준편차는 = 모집단의 표준 편차를 표본 개수의 제곱근으로 나눠주면 된다. 

    표본 평균의 표준 편차
    (모집단의 표준 편차) / (표본 개수) ** 0.5 = σ / (n ** 0.5) 
    가 된다...

     

    똑똑한 형님들이 행여 실수를 하지 않았나
    검증하고 싶은 분들은 파이썬으로 확인을 해보자.  

    # import matplotlib.pyplot as plt
    from random import choice
    
    
    def calc_mean(numbers: list or tuple):
        """ 평균 """
        return sum(numbers) / len(numbers)
    
    
    def calc_sd(numbers):
        """ 표준 편차 """
        mean = calc_mean(numbers)  # 평균
        temp = 0
        for num in numbers:
            temp += (num - mean) ** 2
        variance = temp / len(numbers)  # 분산
        return variance ** .5  # 표준 편차
    
    
    def main(population, sample_size, sample_num):
        population_mean = calc_mean(population)
        print('모집단의 평균:', population_mean)
    
        population_sd = calc_sd(population)
        print(f'모집단의 표준 편차: {population_sd:.4f}')
    
        samples = tuple(tuple(choice(population) for _ in range(sample_size))
                        for _ in range(sample_num))
    
        sample_means = [calc_mean(sample) for sample in samples]
        # print('표본 평균(샘플 각각의 평균)', sample_means)
    
        # plt.hist(sample_means)
        # plt.show()
    
        sample_means_mean = calc_mean(sample_means)
        print(f'표본 평균의 평균: {sample_means_mean:.4f}')
    
        sample_means_sd = calc_sd(sample_means)
        print(f'표본 평균의 표준 편차: {sample_means_sd:.4f}')
    
        print(f'공식을 이용한 표본 평균의 표준 편차: {population_sd / sample_size ** .5:.2f}')
        # 공식을 이용한 표본 평균의 표준 편차
    
    
    main((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10), 3, 100_000)
    모집단의 평균: 5.0
    모집단의 표준 편차: 3.1623
    표본 평균의 평균: 5.0049
    표본 평균의 표준 편차: 1.8252
    공식을 이용한 표본 평균의 표준 편차: 1.83

    형님들을 믿고 외워도 된다는 확신이 들지 않는가?
    표본 평균의 표준 편차는 (모집단의 표준 편차) / (표본 개수) ** 0.5

    반응형
Designed by Tistory.