C.W.K.
Stream
Lesson 03 of 07 · published

Dataset Size 와 Diversity

~18 min · datasets, coverage, sampling

Level 0Guesser
0 XP0/55 lessons0/10 achievements
0/150 XP to next level150 XP to go0% complete

Diversity 가 size 이기지만 size 도 충분히 필요해

'case 몇 개 필요해?' 는 잘못된 질문이야. 옳은 질문은: '우리 case 가 신경 쓰는 모든 동작을 충분한 sample 로 대표해, 신경 쓰는 regression 을 감지할 만큼?'

통계적 floor

binary pass/fail metric 에서 95% confidence 로 5% pass-rate 변화 감지하려면 대략 400 case 필요. 10% 변화 감지하려면 ~100. case 20개만 있으면 suite 가 진짜 regression 과 noise 구분 못 해 — 평균이 10pp 움직여도.

Diversity 차원

  • Topic / domain — coding, medical, legal, casual chat 모두 다른 실패 mode.
  • Difficulty — easy, medium, hard, edge. easy case 만 있는 suite 는 중요한 regression 숨겨.
  • Length — 짧은 input 과 긴 input 은 다른 model 동작 trigger. 항상 둘 다 포함.
  • Language / locale — 적어도 top 3 user 언어 sample.
  • User intent — informational, navigational, transactional, exploratory.
  • Time — 여러 날에 걸쳐 sample. Monday-only sample 은 weekend traffic 놓쳐.
원칙: 10개 차원 고르게 cover 하는 100-case dataset 이 다 똑같이 생긴 1,000-case dataset 보다 더 많이 알려줘.

Imbalance 가 거짓말해

dataset 80% 가 'easy English chitchat' 이면 평균 pass rate 가 그걸 reflect 하고 나머지 20% regression 숨겨. 항상 aggregate 옆에 per-tag pass rate report 해. aggregate 는 exec 용, per-tag breakdown 은 engineer 용.

Code

Binary pass-rate detection 의 sample size·python
from math import ceil

def sample_size_for_difference(p1, p2, alpha=0.05, power=0.8):
    """Approximate two-proportion z-test sample size per group."""
    from statistics import NormalDist
    z_alpha = NormalDist().inv_cdf(1 - alpha / 2)
    z_beta  = NormalDist().inv_cdf(power)
    p_bar = (p1 + p2) / 2
    numerator = (z_alpha * (2 * p_bar * (1 - p_bar)) ** 0.5
                 + z_beta * (p1 * (1 - p1) + p2 * (1 - p2)) ** 0.5) ** 2
    return ceil(numerator / (p1 - p2) ** 2)

print(sample_size_for_difference(0.90, 0.85))  # ~462 — to detect a 5pt drop
print(sample_size_for_difference(0.90, 0.80))  # ~120 — to detect a 10pt drop
Per-tag pass rate 가 aggregate 이겨·python
from collections import defaultdict

def pass_rate_by_tag(results):
    by_tag = defaultdict(lambda: [0, 0])  # [passed, total]
    for r in results:
        for tag in r["tags"]:
            by_tag[tag][1] += 1
            if r["score"] >= 1.0:
                by_tag[tag][0] += 1
    return {tag: passed / total for tag, (passed, total) in by_tag.items()}

# Output:
# {"easy": 0.95, "hard": 0.62, "long": 0.71, "polish": 0.40}
# Aggregate said 88%. Polish is on fire.  ← that's the real story

External links

Exercise

product 에 중요한 차원 list (topic, length, language, intent 등). 현재 dataset 이걸 기준으로 audit. 가장 under-represented 차원에 이번주 case 10개 추가.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.