4강 — 샘플링과 대표성
🎯 학습 목표
- 리뷰 10만 건을 전부 분석하지 않고 일부만 봐도 되는 이유를 설명할 수 있다
- 모집단·표본·대표성이 무엇인지 이해할 수 있다 (여론조사·국 끓이기 비유)
- 층화 샘플링이 왜 단순 무작위보다 나은지 설명할 수 있다
- 몇 개를 뽑아야 할지, 신뢰수준·오차범위가 무엇인지 판단할 수 있다
📖 해설
지난 시간에 임베딩을 배웠죠. 그런데 고민이 생깁니다. 리뷰가 10만 건이면 전부 임베딩하는 데 API 호출 10만 번, 저장 공간 300MB 이상, 시간도 엄청나게 듭니다. 정말 다 분석해야 할까요? 통계학은 "아니오"라고 답합니다. 잘 뽑은 1,000건이 10만 건과 거의 같은 결론을 냅니다. 오늘 배울 샘플링은 비용을 90% 이상 줄이면서 정확도는 95%를 유지하는 방법이에요.
1. 전수조사는 왜 문제인가
지난 시간 임베딩을 다시 떠올려 보면, 텍스트 한 건을 768차원 벡터로 바꾸면 벡터 하나가 약 3KB를 차지했습니다. 그러면 10만 건은 10만 × 3KB ≈ 300MB가 되고, API 호출 비용도 건수에 정비례해 늘어납니다. 데이터가 많을수록 비용이 비례해서 커진다는 게 핵심이에요. 전부 다 분석하는 전수조사의 문제는 여기서 출발하는 세 가지입니다.
- 비용 폭발 — 임베딩 API를 10만 번 호출하면 수만 원, 저장 300MB 이상. 매달 분석하면 연 수십만~수백만 원, 규모에 따라 수천만 원까지 갑니다.
- 시간 — 10만 건 처리에 API 호출만 몇 시간. 실시간으로 리뷰 트렌드를 보고 싶다면 이 지연이 발목을 잡습니다.
- 불필요한 정밀도 — 우리가 알고 싶은 건 "대략 긍정이 몇 %인가, 주요 불만이 뭔가"입니다. 99.9% 정확도가 필요한 게 아니에요. 95%면 충분합니다. 긍정 비율을
72.347%처럼 소수점 셋째 자리까지 알 필요는 없잖아요.
그래서 해결책이 샘플링입니다. 10만 건 중 1,000건만 잘 뽑으면 비용은 1%대로, 정확도는 95% 이상 유지할 수 있습니다.
2. 여론조사는 어떻게 1,000명으로 5,000만을 알까
선거 여론조사는 1,000명에게 물어 "지지율 45%, 오차범위 ±3.1%"라고 발표합니다. 인구 5,000만 명 중 1,000명이면 0.002%인데 어떻게 전체를 알까요? 세 조건이 맞으면 가능합니다.
- 무작위 추출 — 모든 사람이 뽑힐 확률이 같아야 합니다. 서울 사람만, 젊은 사람만 뽑으면 안 돼요.
- 충분한 크기 — 통계학적으로 1,000명 정도면 전체 추정에 충분합니다(수학적으로 증명된 사실).
- 대표성 — 지역·연령·성별 비율을 실제 인구 비율과 맞춥니다(서울 20%, 경기 25%처럼).
3. 핵심 비유 — 국 끓일 때 한 숟가락
큰 냄비에 국을 끓입니다. 간을 보려고 국을 다 마실까요? 아니죠. 한 숟가락만 떠서 맛보면 됩니다. 단, 조건이 있어요. 국이 잘 섞여 있어야 합니다. 소금이 바닥에 가라앉아 있으면 위는 싱겁고 아래는 짜니까요.
- 모집단(population) = 큰 냄비의 국 전체 = 리뷰 10만 건
- 표본(sample) = 한 숟가락 = 우리가 뽑은 1,000건
- 추정(estimation) = 한 숟갈 맛으로 "국 전체가 짜다/싱겁다"를 판단하는 것 = 표본으로 전체 경향을 미루어 아는 것
샘플링 분석은 늘 이 세 단계로 흐릅니다 — 모집단(전체)에서 표본(일부)을 뽑고, 그 표본으로 전체를 추정합니다. 잘 섞인 국이면 한 숟갈로 전체 간을 알 수 있듯, 잘 뽑은 표본이면 일부로 전체를 알 수 있습니다. 문제는 "어떻게 잘 섞느냐 = 어떻게 잘 뽑느냐"예요.
| 전수조사 | 샘플링 | |
|---|---|---|
| 대상 | 10만 건 전체 | 대표성 있는 1,000건 |
| 비용 | 100% | 약 1% |
| 시간 | 수 시간 | 수 분 |
| 정확도 | 이론상 100% | 95% 이상 |
정확도 100%와 95%의 차이가 중요할까요? "긍정 72%"든 "긍정 70~74%"든 비즈니스 의사결정은 거의 같습니다. 오히려 전수조사는 과도한 정밀도일 수 있어요.
4. 단순 무작위 vs 층화 샘플링
- 단순 무작위 샘플링 — 전체에서 그냥 랜덤하게 뽑기. 간단하지만 운이 나쁘면 편향될 수 있습니다. 전체가 긍정 70%인데 우연히 긍정 90%가 뽑힐 수도 있어요(확률은 낮지만 가능).
- 층화 샘플링(stratified sampling) — 먼저 그룹(층)으로 나누고, 각 그룹에서 비율에 맞게 뽑습니다. 전체가 긍정 70%·부정 30%면, 1,000건을 뽑을 때 긍정에서 700건·부정에서 300건. 그러면 샘플도 정확히 70:30이 됩니다.
5. 리뷰 데이터의 층화 기준 4가지
- 추천 여부 (가장 기본) — 추천 80%·비추천 20%면 샘플도 그 비율로. 안 그러면 긍정/부정으로 편향됩니다.
- 플레이 시간 — 1시간 미만 유저와 100시간 이상 유저는 리뷰가 다릅니다("튜토리얼 어렵다"는 초보 vs "엔드 콘텐츠 부족"한 고인물). 둘 다 들어야 균형이 잡혀요.
- 작성 시점 — 출시 직후 리뷰는 버그 불만이 많고, 1년 후 리뷰는 업데이트 평가가 많습니다. 시기별로 뽑으면 게임의 변화 과정이 보입니다.
- 리뷰 길이 — 짧은 리뷰는 "재밌어요" 정도지만, 긴 리뷰는 구체적 장단점을 담습니다. 긴 리뷰가 10%뿐이어도 그 10%를 포함해야 깊은 인사이트가 나옵니다.
6. 몇 개를 뽑아야 할까 — 샘플 크기
결론부터: 대부분 1,000개면 충분합니다(통계학적으로 검증된 수치).
| 샘플 크기 | 오차범위 | 해석 예시 | 용도 |
|---|---|---|---|
| 100개 | ±10% | 긍정 60~80% | 대략적 경향만 |
| 400개 | ±5% | 긍정 65~75% | 실용적, 빠른 탐색 |
| 1,000개 | ±3% | 긍정 67~74% | 신뢰할 수준, 비즈니스 의사결정 충분 |
| 10,000개 | ±1% | — | 더 정밀하나 보통 불필요(비용 10배) |
재미있는 점: 모집단이 10만 건이든 100만 건이든 필요한 샘플 크기는 비슷합니다(약 1,000개). 이게 통계학의 힘이에요.
7. 신뢰수준 & 오차범위
- 신뢰수준 95% — 같은 방식으로 100번 샘플링하면 95번은 정확한 범위 안에 들어간다는 뜻. 업계 표준입니다(99%도 있지만 보통 95%).
- 오차범위 ±3% — 실제 값이 이 범위 안에 있다는 뜻. 1,000개 샘플이면 대략 ±3%.
합쳐서 해석하면 — "긍정 70%, 신뢰수준 95%, 오차범위 ±3%"는 실제 전체 리뷰의 긍정 비율이 67~73%일 확률이 95%라는 의미입니다. 이 정도면 "대략 70% 정도 긍정이구나" 판단하기 충분하죠. 공식을 외울 필요는 없고, "1,000개 뽑으면 ±3%" 정도만 기억하면 됩니다.
8. 좋은 샘플링 체크리스트
- 대표성 — 전체와 샘플의 비율이 일치할 것. 특정 그룹(예: 100시간 이상 유저)이 누락되지 않을 것. 극단값(아주 긴/짧은 리뷰)도 포함할 것.
- 크기 — 최소 400개, 정밀하면 1,000개, 그룹별로 나누면 각 그룹에 최소 100개씩. 부정 리뷰가 30개뿐이면 부정 분석의 신뢰도가 낮습니다.
- 무작위성 — 시간순 앞에서만 뽑으면 초기 리뷰만 들어갑니다. 그리고 랜덤 시드(random seed)를 고정해 두면 다음에도 같은 결과를 재현할 수 있습니다.
9. 잘못된 샘플링의 함정
- 시간 편향 — 최근 1,000개만 뽑았는데, 이 게임이 출시 초엔 버그가 심했다가 나중에 고쳐졌다면? "버그 없는 좋은 게임"으로 오판하고, 초기에 이탈한 유저들의 불만을 놓칩니다.
- 길이 편향 — 분석하기 좋으라고 100자 이상 리뷰만 뽑았는데, 짧은 리뷰는 대부분 "재밌어요"(긍정)였다면? 긴 리뷰는 불만을 자세히 쓰는 경우가 많아 부정 편향된 샘플이 됩니다.
- 추천 편향 — 추천 리뷰만 뽑아 분석하면 그 안의 개선점을 놓칩니다.
그래서 시기별·길이별·추천 여부별로 비율을 맞춰 뽑는 층화 샘플링이 중요합니다.
10. 실제 적용 + 코드
전체 10만 건, 추천 80%·비추천 20%라면 1,000건은 추천 800·비추천 200. 플레이 시간으로도 나눌 수 있고(1시간 미만 40%·1~10시간 35%·10시간 이상 25% → 400·350·250), 두 기준을 동시에 적용하는 것을 교차 층화라고 합니다. 파이썬에서는 판다스(pandas)의 groupby와 sample을 조합하면 쉽게 구현돼요.
import pandas as pd
# df: 리뷰 데이터프레임 (예: 'recommend' 추천여부 컬럼이 있다고 가정)
# 목표: 전체 1,000건을 추천/비추천 '비율을 유지'하며 뽑기(층화 샘플링)
n_total = 1000
# 그룹별로 전체 비율(frac)에 맞춰 같은 비율로 뽑으면 자동으로 층화가 된다
frac = n_total / len(df)
sample = (
df.groupby('recommend', group_keys=False) # 추천/비추천 그룹으로 나누고
.apply(lambda g: g.sample(frac=frac, # 각 그룹에서 같은 비율로
random_state=42)) # random_state=시드 고정(재현 가능)
)
# 검증: 원본과 샘플의 추천 비율이 비슷한지 확인
print("원본 비율:\n", df['recommend'].value_counts(normalize=True))
print("샘플 비율:\n", sample['recommend'].value_counts(normalize=True))
random_state=42처럼 시드를 고정하면, 다음에 다시 돌려도 똑같은 1,000건이 뽑혀 결과를 재현할 수 있습니다. 결과적으로 이 1,000건이 10만 건 전체를 대표하게 되고, 비용은 약 99% 절감됩니다.
🔑 핵심 용어
| 용어 | 쉬운 설명 |
|---|---|
| 모집단(population) | 분석 대상 전체 (리뷰 10만 건) |
| 표본(sample) | 거기서 뽑은 일부 (1,000건) |
| 추정(estimation) | 표본으로 전체 경향을 미루어 판단하는 것 (한 숟갈로 국 전체 간 보기) |
| 대표성 | 표본이 전체의 비율·특성을 잘 반영하는 정도 |
| 층화 샘플링 | 그룹으로 나눠 비율 맞게 뽑기 |
| 교차 층화 | 두 기준(추천×플레이시간 등)을 동시에 적용 |
| 신뢰수준 95% | 100번 뽑으면 95번은 범위 안 |
| 오차범위 ±3% | 실제 값이 들어 있는 폭 (1,000개 ≈ ±3%) |
| 랜덤 시드 | 같은 결과를 재현하게 고정하는 값 (random_state) |
groupby / sample |
판다스의 그룹 나누기 / 무작위 추출 함수 |
🎮 게임 기획자 시점
층화 기준(추천 여부·플레이 시간·작성 시점·리뷰 길이)이 곧 유저 세그먼트입니다. "초보 vs 고인물", "출시 초기 vs 1년 후" 유저의 목소리를 비율대로 다 담는 건, 라이트~헤비 유저를 균형 있게 보는 기획 감각과 똑같아요. 특히 시간 편향의 함정(최근 리뷰만 보면 초기 이탈 유저 불만을 놓침)은, 리텐션 분석에서 "남아 있는 유저만 보면 떠난 유저가 왜 떠났는지 모른다"는 생존자 편향과 정확히 같은 문제입니다.
⚠️ 흔한 오해 / 짚고 갈 점
- "데이터는 많을수록 좋다"가 항상 옳진 않습니다. 편향된 데이터가 많으면 틀린 결론을 더 확신하게 됩니다. 잘 뽑은 1,000건 > 편향된 10만 건.
- 샘플링은 "대충"이 아니라 과학적 방법입니다. 대표성이 정확도를 결정해요.
✅ 30초 정리
- 전수조사는 비용·시간·과도한 정밀도 때문에 비효율적입니다. 잘 뽑은 1,000건이면 충분해요.
- 층화 샘플링으로 추천·플레이시간·시점·길이 비율을 맞춰 뽑아야 대표성이 생깁니다.
- 1,000개 ≈ 오차 ±3%, 모집단이 10만이든 100만이든 비슷. 비용 99%↓·정확도 95% 유지.
▶️ 다음 강 연결
여기까지가 14차시 프로젝트 "리뷰 샘플링 설계"의 재료입니다(groupby+sample, 시드 고정으로 직접 실습). 깨끗하게 정제하고 대표성 있게 뽑은 데이터가 준비됐으니, 이제 드디어 AI에게 분석을 시킬 차례예요. 다음 5강에서 LLM API를 처음 연동합니다.