표본 추출 문서의 검증 코드다. if __name__ == "__main__": 아래가 자체 테스트다.

"""표본 추출 검증.

문서: 09.표본 추출 (예시, 카드 C1·C2)
주장:
  1. 비복원 추출은 같은 자료를 두 번 뽑지 않는다. 복원 추출은 두 번 뽑을 수 있다.
     자료 100개에서 복원으로 100개를 뽑으면 서로 다른 자료는 평균 약 63.4개다 (1 - (1 - 1/100)^100).
  2. 층화 추출은 층(예: 등급)마다 같은 비율로 뽑아 표본의 층 비율이 모집단과 정확히 같다.
     희귀 층(1%)이 있을 때 단순 무작위 표본 20개는 그 층을 놓칠 확률이 약 0.818이다 (0.99^20).
"""
import random


def main():
    rnd = random.Random(1)
    data = list(range(100))
    s = rnd.sample(data, 30)
    assert len(set(s)) == 30
    trials = 2000
    avg = sum(len(set(rnd.choices(data, k=100))) for _ in range(trials)) / trials
    expect = 100 * (1 - (1 - 1 / 100) ** 100)
    assert abs(avg - expect) < 0.5 and round(expect, 1) == 63.4
    print(f"[OK] 비복원은 중복 없음, 복원 100번 추출의 서로 다른 개수 평균 {avg:.1f} (이론 {expect:.1f})")

    pop = ["VIP"] * 10 + ["일반"] * 990
    strat = rnd.sample(pop[:10], 1) + rnd.sample(pop[10:], 99)
    assert strat.count("VIP") == 1 and len(strat) == 100
    miss = 0.99 ** 20
    sim = sum("VIP" not in rnd.sample(pop, 20) for _ in range(5000)) / 5000
    assert abs(sim - miss) < 0.03 and round(miss, 3) == 0.818
    print(f"[OK] 층화 표본 100개의 VIP 비율 1% 그대로. 단순 표본 20개가 VIP를 놓칠 확률 {miss:.3f} (모의 {sim:.3f})")
    print("ALL CHECKS PASSED")


if __name__ == "__main__":
    main()