개념
발사됐다고 쓸 만한 것은 아니다
레슨 5에서 태그가 설계대로 발사되는지 확인했다. 그런데 태그가 정상으로 발사돼도 모여 있는 데이터는 쓸 수 없는 상태 일 수 있다. 같은 구매가 두 번 집계되거나, 특정 브라우저에서만 체계적으로 빠져 있거나, A/B 테스트 배정 비율이 설계와 다르거나.
수집 데이터를 제품처럼 본다면 품질 특성도 제품처럼 나뉜다.
| 특성 | 묻는 질문 | 이 레슨에서 |
|---|---|---|
| 유일성 | 같은 사건이 두 번 기록되지 않았는가 | 중복 |
| 완전성 | 일어난 사건이 빠짐없이 기록됐는가 | 누락 |
| 정확성 | 기록된 값이 실제 값과 같은가 | 기준선 대조 |
| 일관성 | 앞뒤 사건의 순서·관계가 맞는가 | 순서 이상 |
| 대표성 | 표본이 의도한 모집단을 대표하는가 | SRM |
앞의 넷은 레슨 2에서 데이터베이스를 상대로 한 일과 같은 종류다. 마지막 하나가 새롭고, 실험 문화가 있는 조직에서 가장 값비싼 결함을 만든다.
중복 — 어디서 두 번이 되나
원인은 몇 가지로 정리된다.
- 사용자 재시도 — 결제 완료 페이지에서 새로고침, 뒤로가기 후 다시 진입
- SPA 라우팅 — 화면 전환이 페이지 로드가 아니라 상태 변경이라, 같은 컴포넌트가 다시 마운트되면서 이벤트가 재발사
- 이중 구현 — gtag 직접 호출과 GTM 태그가 같은 이벤트를 각각 보냄. 담당자가 다르면 서로 모른다
- 서버·클라이언트 양쪽 전송 — 측정 프로토콜(서버 전송)과 웹 태그를 같이 쓰는데 중복 제거 키가 없음
- 재시도 로직 — 네트워크 실패 시 클라이언트가 자동 재전송
탐지는 레슨 2의 중복 패턴 그대로다. 분석 도구의 원본 데이터를 조회할 수 있다면(BigQuery 연동 등) 업무 키로 세어 본다.
-- 같은 거래가 두 번 이상 수집됐다
SELECT transaction_id, COUNT(*) AS event_count
FROM analytics_events
WHERE event_name = 'purchase'
AND event_date BETWEEN '2026-09-01' AND '2026-09-24'
GROUP BY transaction_id
HAVING COUNT(*) >= 2
ORDER BY event_count DESC;원본 접근이 없다면 합계 대조 로도 잡힌다. 분석 도구의 구매 건수와 DB 의 주문 건수를 같은 기간으로 비교했을 때 분석 쪽이 더 크면 중복이다.
막는 방법은 하나로 모인다. 모든 전환 이벤트에 유일한 업무 키를 실어 보내는 것. GA4 의 purchase 는 transaction_id 가 그 역할을 하고, 실제로 GA4 는 같은 transaction_id 의
중복을 걸러 준다. 그래서 transaction_id 를 매 요청마다 새로 생성하는 구현 이 특히 위험하다 — 중복 제거 장치를 스스로 무력화한 셈이 된다. 설계 리뷰에서 반드시 확인할 항목이다.
누락 — 빠진 것은 티가 안 난다
중복은 숫자가 커져서 눈에 띄지만 누락은 조용하다. 원인은 이렇다.
| 원인 | 성격 | 특징 |
|---|---|---|
| 광고·추적 차단기 | 외부 요인 | 막을 수 없다. 비율을 알고 있어야 한다 |
| 동의 거부(consent) | 정상 동작 | 법적으로 맞는 동작이다. 결함이 아니다 |
| 페이지 이탈 전 전송 실패 | 구현 결함 | 클릭 직후 페이지가 넘어가면 요청이 취소된다 |
| JS 오류로 태그 코드 미실행 | 구현 결함 | 콘솔에 흔적이 남는다(레슨 3) |
| 앱 백그라운드 전환·종료 | 플랫폼 제약 | 모바일 앱에서 특히 잦다 |
| 느린 네트워크에서 타임아웃 | 환경 | 저사양·해외 사용자에게 편중된다 |
중요한 것은 앞의 둘과 나머지를 나누는 것 이다. 차단기와 동의 거부는 결함이 아니라 알고 있어야 하는 상수 다. 반면 이탈 전 전송 실패나 JS 오류는 고칠 수 있는 결함이고, 특정 브라우저·기기에 편중되므로 분석 결과를 왜곡한다.
누락은 기준선과 비교해야 보인다. 이 모듈의 결론 중 하나가 여기 있다 — 정본(source of truth)은 데이터베이스다. 분석 도구는 근사치이고, 둘이 다르면 DB 가 맞다.
격차율 = (DB 건수 - 분석 도구 건수) / DB 건수
예) 9월 1~24일 DB 주문 12,480건 / GA4 purchase 11,356건
격차율 = (12,480 - 11,356) / 12,480 = 9.0%이 9%가 정상인지 아닌지는 평소 값을 알아야 판단할 수 있다. 그래서 첫 작업은 기준선을 재는 것이다. 주 단위로 격차율을 기록해 두면 어느 날 15%로 튀었을 때 바로 알아챈다. 값 자체보다 변화 가 신호다.
격차율을 쪼개 보면 원인이 좁혀진다. 브라우저별·기기별·유입 경로별로 나눴을 때 한 구간만 격차가 크면 그 구간이 범인이다.
| 구간 | DB | GA4 | 격차율 |
|---|---|---|---|
| Chrome 데스크톱 | 5,200 | 4,940 | 5.0% |
| Safari iOS | 4,100 | 3,362 | 18.0% |
| Android Chrome | 3,180 | 3,054 | 4.0% |
Safari 한 줄만 튀면 ITP·쿠키 정책 같은 플랫폼 차이일 수도, iOS 웹뷰에서 태그가 깨진 구현 결함일 수도 있다. 어느 쪽인지는 그 환경에서 레슨 5의 절차를 다시 돌려 보면 판별된다.
순서 이상
퍼널 단계는 순서가 있다. 뒤 단계가 앞 단계보다 많으면 논리적으로 불가능하다.
-- 세션별 단계 건수 — begin_checkout 없이 purchase 만 있는 세션
SELECT session_id,
SUM(CASE WHEN event_name = 'begin_checkout' THEN 1 ELSE 0 END) AS checkout_cnt,
SUM(CASE WHEN event_name = 'purchase' THEN 1 ELSE 0 END) AS purchase_cnt
FROM analytics_events
WHERE event_date = '2026-09-24'
GROUP BY session_id
HAVING SUM(CASE WHEN event_name = 'purchase' THEN 1 ELSE 0 END) >= 1
AND SUM(CASE WHEN event_name = 'begin_checkout' THEN 1 ELSE 0 END) = 0;이런 세션이 대량으로 나오면 앞 단계 태그가 일부 경로에서 누락된 것이다(예: 장바구니를 거치지 않는 바로구매 흐름에 begin_checkout 이 안 붙음). 퍼널 전환율이 100%를 넘는 구간 이
보인다면 같은 원인이다.
SRM — 표본비 불일치
A/B 테스트를 50:50 으로 설계했는데 실제 배정이 50:50 이 아니면 표본비 불일치(Sample Ratio Mismatch, SRM) 다. 이것이 심각한 이유는 비율 자체가 아니라, 비율이 틀어졌다는 것은 사용자가 무작위로 나뉘지 않았다는 증거 이기 때문이다. 무작위성이 깨지면 실험 결과 전체가 무효가 된다.
더 나쁜 것이 있다. 빠진 사용자는 보통 아무나가 아니다. 예를 들어 B안의 페이지가 느려서 로딩 전에 이탈한 사용자가 기록되지 않았다면, B안에서 사라진 사람들은 하필 가장 참을성이 없거나 네트워크가 느린 사용자 다. 남은 사람만 보면 B안이 더 좋아 보인다.
판정은 카이제곱 적합도 검정 으로 한다. 공식은 단순하다.
χ² = Σ (관측값 - 기대값)² / 기대값 자유도 = 그룹 수 - 1예시 1 — 50:50 설계, 2만 명
관측: A = 10,342 B = 9,658 (합계 20,000)
기대: A = 10,000 B = 10,000
χ² = (10,342 - 10,000)² / 10,000 + (9,658 - 10,000)² / 10,000
= 342² / 10,000 + 342² / 10,000
= 11.6964 + 11.6964
= 23.39 (자유도 1)
p ≈ 0.0000013p 값이 0.0000013 이다. 무작위 배정이 정상일 때 이만큼 치우칠 확률이 100만 분의 1 정도라는 뜻이다. SRM 으로 판정한다.
예시 2 — 같은 설계, 치우침이 작을 때
관측: A = 10,050 B = 9,950
χ² = 50²/10,000 + 50²/10,000 = 0.25 + 0.25 = 0.5 p ≈ 0.48p 가 0.48 이므로 이 정도 차이는 우연으로 충분히 설명된다. SRM 아님.
예시 3 — 90:10 설계에서는 작은 쪽이 민감하다
설계 90:10, 총 20,000명
관측: A = 17,700 B = 2,300
기대: A = 18,000 B = 2,000
χ² = 300²/18,000 + 300²/2,000 = 5.0 + 45.0 = 50.0 p ≈ 1.5e-12같은 300명 차이인데 작은 쪽(기대 2,000)에서 훨씬 큰 값이 나온다. 불균등 배분 실험에서는 작은 그룹의 소수 누락도 SRM 이 된다.
판정 임계값. Microsoft 의 실험 플랫폼은 오탐을 줄이기 위해 p < 0.0005 라는 보수적인 기준을 쓴다고 공개 문서에서 밝히고 있다. 업계에서는 p < 0.01 을 쓰는 곳도 있다. 팀이 어느
기준을 쓰는지 먼저 정하고 문서에 적는 것 이 QA 가 할 일이다. 기준이 없으면 판정할 때마다 논쟁이 붙는다.
계산은 손으로 해도 되고 코드로 해도 된다.
from scipy.stats import chisquare
observed = [10342, 9658]
total = sum(observed)
expected = [total * 0.5, total * 0.5] # 설계 비율을 그대로 적는다
stat, p = chisquare(f_obs=observed, f_exp=expected)
print(f"chi2={stat:.2f} p={p:.8f}")검정할 때 반드시 지킬 것.
- 사용자 단위로 센다. 세션·페이지뷰 단위로 세면 그룹별 행동 차이 때문에 비율이 달라지는 것이 당연해져 검정이 무의미해진다
- 설계 비율을 확인하고 넣는다. 50:50 인 줄 알았는데 램프업 중이라 90:10 이었던 경우가 흔하다
- 세그먼트별로도 본다. 전체는 정상인데 특정 브라우저·국가·신규/재방문 구간에서만 SRM 이 나오면 원인이 거의 특정된다
SRM 의 원인 은 공개 문헌에서 네 단계로 정리돼 있다 — 배정 단계(버킷팅 오류, 잘못된 사용자 ID, 이전 실험의 잔류 효과), 실행 단계(리다이렉트, 변형별 이탈 차이), 로그 처리 단계(조인 오류), 분석 단계(편향된 세그먼트 조건). 여기에 실험자의 조작(변형별 순차 램프업)도 더해진다. 이 분류가 유용한 이유는 어느 단계를 먼저 볼지 순서를 정해 주기 때문이다.
SRM 이 나오면 할 일은 하나다. 결과 분석을 멈추는 것. 원인을 찾기 전에 "그래도 B안이 좋아 보인다"를 말하면 안 된다. 사라진 사용자가 결과를 어느 방향으로 얼마나 밀었는지 알 수 없기
때문이다. QA 가 이 말을 할 수 있는 근거가 위의 p 값이다. 숫자가 있으면 논쟁이 짧아진다.
실험 설계 전반 — 표본 크기 산정, 실험 기간, 다중 검정 문제 — 은 모듈 49의 A/B 테스트 품질 검증 레슨이 다룬다. 여기서는 수집된 데이터가 분석할 만한 상태인가 만 판정한다.
QA 의 점검 시점
| 시점 | 확인 |
|---|---|
| 실험 시작 전 | 배정 비율 설계값 문서화, 배정 단위(사용자/세션) 확인, 노출 이벤트 구현 확인 |
| 시작 후 첫날 | SRM 검정 1회. 여기서 걸리면 손실이 하루로 끝난다 |
| 실험 중 매일 | SRM 재검정, 전체 이벤트 수 급변 여부 |
| 분석 전 | SRM 최종 검정, 세그먼트별 SRM, 중복·누락 격차율 |
첫날 검정이 가장 값싸다. 2주짜리 실험이 끝난 뒤 SRM 을 발견하면 2주가 날아간다.
실무에서 왜 필요한가
수집 데이터의 결함은 틀린 결정을 만든다. 중복 purchase 로 전환율이 1.4배로 보이면 그 채널에 광고비가 더 들어가고, 누락으로 특정 브라우저의 전환이 낮게 잡히면 멀쩡한 기능이
"성과가 없다"며 롤백된다. 기능 결함은 사용자 한 명의 경험을 망치지만, 데이터 결함은 조직 전체의 판단을 망친다.
그리고 이 일은 QA 가 하기에 구조적으로 맞다. 데이터를 쓰는 사람(마케터·PM)은 자기 도구 안에서만 보므로 기준선과 대조할 수 없고, 구현하는 사람(개발자)은 자기 코드가 동작하는 것만 확인한다. DB 와 분석 도구를 양쪽에서 조회해 대조할 수 있는 사람이 QA 다. 이 모듈의 레슨 1·2가 여기서 쓰이는 이유다.
마지막으로, SRM 판정은 QA 가 "아니오"라고 말할 근거를 숫자로 갖는 드문 장면 이다. 결함 심각도 논쟁은 흔히 주관으로 흐르지만 p = 0.0000013 은 반박하기 어렵다. 이런 종류의 근거를
하나씩 늘려 가는 것이 QA 의 영향력이 커지는 방식이다.