~11 min · selection-bias, self-selection, non-response, polling
Level 0통계 초심자
0 XP0/55 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete
"자료는 세상에서 저절로 표본이 되어 오지 않아. 누가 들어오고 누가 빠지는지 결정하는 문이 있고, 그 문이 결론을 바꿀 수 있어."
선택편향이 생기는 곳
표본에 들어올 가능성이 우리가 측정하려는 특성과 관련되면 표본의 분포가 모집단과 달라질 수 있어.
자기선택: 의견이 강하거나 시간이 있는 사람이 더 자주 참여해.
비응답: 응답하지 않은 사람이 응답자와 체계적으로 다를 수 있어.
포함범위: 연락수단, 지역, 언어, 플랫폼 때문에 어떤 집단이 애초에 표집틀에서 빠져.
생존: 결과까지 남은 사례만 관찰돼.
편의표본: 접근하기 쉬운 사람을 모집단처럼 다뤄.
표본이 확률표본이 아니라고 언제나 쓸모없는 건 아니야. 어떤 모집단에 어떤 방식으로 일반화할 수 있는지 한계를 밝혀야 한다는 뜻이야.
1936과 1948을 섞지 마
전화번호부와 자동차 등록명부를 활용한 거대한 우편조사가 Roosevelt의 승리를 놓친 유명한 사건은 1936년 Literary Digest 여론조사야. 표집틀이 당시 더 부유한 유권자를 과대표집했고 응답자 자기선택도 겹쳤어. 큰 표본이 편향된 표집을 구하지 못한 사례지.
1948년 Truman–Dewey 선거의 실패는 다른 이야기야. 주요 여론조사들은 비확률 할당표집을 사용했고, 현장 조사자의 선택이 할당 안에서 편향될 수 있었어. 일부 조사는 선거일보다 일찍 멈춰 막판 변화를 놓쳤고, 투표율과 부동층 처리에도 문제가 있었지. "1948년에는 부유한 공화당원만 전화가 있어서 틀렸다"고 쓰면 두 사건을 합쳐버려.
1948년 뒤 미국 여론조사 업계는 점차 확률표집으로 이동했어. 교훈은 특정 통신수단 하나가 아니라 표집틀, 조사원 선택, 비응답, 조사시점과 투표자 모형을 함께 점검해야 한다는 거야.
현대의 선택문
소셜 미디어 투표와 댓글감성은 플랫폼을 쓰고, 게시물을 보고, 반응하기로 한 사람들의 자료야. 전체 국민이나 전체 고객의 무작위 표본이 아니지. 가중치로 관찰 가능한 차이를 줄일 수는 있지만 관찰하지 못한 선택요인까지 자동으로 사라지지는 않아.
운영 원칙
숫자를 보기 전에 표본이 들어온 문을 그려봐. 표집틀에 누가 있었나? 실제로 누가 선택됐나? 누가 응답했나? 어떤 시점에 측정했나? 가중치는 무엇을 보정했고 무엇을 못 했나? 선택과 결과가 관련되면 표본크기가 커져도 편향은 남을 수 있어.
Code
선택 편향: 응답이 결과와 상관·python
import numpy as np
rng = np.random.default_rng(270)
# 어떤 질문에 대해 참 50/50 분할인 인구 시뮬.
# 근데 (양쪽 모두) 그것에 대해 강하게 느끼는 사람이 3배 더 응답할 가능성.
# 여론조사 샘플이 강한 의견 쪽으로 편향.
N = 100_000
true_opinion = rng.choice(['yes', 'no'], size=N, p=[0.5, 0.5])
strength = rng.choice(['mild', 'strong'], size=N, p=[0.7, 0.3])
# 응답 확률이 강도에 의존.
response_prob = np.where(strength == 'strong', 0.6, 0.2)
responded = rng.random(N) < response_prob
sample = true_opinion[responded]
yes_pct_sample = (sample == 'yes').mean() * 100
yes_pct_true = (true_opinion == 'yes').mean() * 100
print(f"참 인구 yes 율: {yes_pct_true:.2f}%")
print(f"여론조사 샘플 yes 율: {yes_pct_sample:.2f}%")
# 이 시뮬에서 yes 율이 방향이 아니라 강도에 필터가 있어서 비슷.
# 이제 강도를 방향과 상관되게 변경 ('yes' 라 말하는 사람이 더 열정적)...
response_prob2 = np.where(
(true_opinion == 'yes') & (strength == 'strong'), 0.7,
np.where((true_opinion == 'no') & (strength == 'strong'), 0.5,
0.2)
)
responded2 = rng.random(N) < response_prob2
sample2 = true_opinion[responded2]
yes_pct_sample2 = (sample2 == 'yes').mean() * 100
print(f"\n*'yes' 지지자가 더 응답할 때 (선택 편향):*")
print(f"여론조사 샘플 yes 율: {yes_pct_sample2:.2f}%")
print(f"참 yes 율: {yes_pct_true:.2f}%")
# 여론조사가 이제 'yes' 를 과대-추정, 단순히 'yes' 유권자가 더 응답할 의향이 있어서.
# 이게 평이한 숫자로의 선택 편향.