비즈니스 현실9 분 읽기

실험을 설계했더니 통계적으로 불가능했다

매출 상위 앱 3개에 새 크리에이티브 자산을 붙이고 전후를 비교할 계획이었습니다. 실행 전에 검정력을 계산했더니, 이 앱들은 어떤 현실적 기간에도 효과를 검출할 수 없었습니다. 효과를 재는 앱과 효과를 보는 앱을 분리해야 했습니다.

#app-store#statistics#ab-testing#reality-check
개념 도식: +30% 리프트 검출에 필요한 일수. 매출 상위 앱은 299일·280일로 30일 선 밖, 노출 538/일인 매출 0원 앱만 9일로 선 안.
같은 자산을 붙여도 한쪽은 9일이면 측정되고, 다른 쪽은 299일이 걸린다.

Apple이 App Store 검색 결과와 헤더에 쓰는 새 크리에이티브 자산 규격을 열었습니다. 계획은 흔했습니다 — 매출 상위 앱 3개에 이 자산을 붙이고, 2주 전후 퍼널을 비교해 효과를 잰다. 자산을 만들고, 붙이고, before/after를 본다.

실행하기 전에 검정력을 계산해 봤습니다. 계획이 성립하지 않았습니다.

매출 상위 앱은 노출이 두 자릿수였다

매출 상위 앱들은 노출이 하루 20~48회입니다. 이 표본으로는 어떤 현실적 기간에도 효과를 검출할 수 없습니다.

2-proportion z-test, power 80%, α=.05 양측 기준으로 각 창에 필요한 일수를 계산하면 이렇게 나옵니다. 크리에이티브 자산은 iOS 27+에서만 렌더되므로 유효 노출은 노출 × iOS27 점유율이고, 점유율을 30%로 가정했습니다.

노출/일 +30% 리프트 +50% +100%
Quieta 20 299일 116일 34일
Throne 48 280일 109일 32일
Cyra 41 162일 63일 18일
Plotta 538 9일 3일 <1일
Heardle 203 46일 18일 5일

매출 상위 두 앱은 리프트가 +100%여도 한 달이 넘게 걸리고, 그마저 노출 자체의 변동에 묻힙니다. 반면 매출이 $0인 앱 하나(Plotta)가 노출 538/일이라 며칠 단위로 읽힙니다.

측정 코호트와 수익 코호트를 분리한다

여기서 결론이 뒤집혔습니다. 효과를 재는 앱과 효과를 보는 앱은 서로 달라야 합니다.

  • 측정용 = 노출이 많은 앱. 매출은 $0이지만, 레버의 크기를 재는 데는 이쪽이 유일한 수단입니다.
  • 수익용 = 매출 상위 앱. 자산은 똑같이 붙이되, "퍼널로 검증됐다"는 판정은 하지 않습니다. 측정 앱에서 잰 효과크기를 이식 근거로 씁니다.

직관에 반합니다. 그런데 노출이 두 자릿수인 앱에서 A/B를 하겠다는 원래 계획이 더 비직관적이었습니다. 매출 0원 앱이 여기서는 자산 아니라 계측기 역할을 합니다. 왜 이 앱들이 이렇게 노출이 적은지, 그 노출 총량 문제 자체는 여기 → 노출 1위 앱의 매출은 0원이었다.

여기서 멈추고 여쭙겠습니다. 당신이라면? 계산 없이 매출 상위 3개에 붙이고 두 달 뒤 "효과 없음"을 받겠습니까 — 그게 효과가 없어서가 아니라 볼 수 없어서인데도? 아니면 측정과 수익을 다른 앱에 나누겠습니까?

같은 규격의 자산인데, 결과가 나오는 속도가 이렇게 다릅니다. 왼쪽(Quieta)은 노출 20/일이라 299일, 오른쪽(Plotta)은 538/일이라 9일.

측정 불가 쪽: Quieta 검색 결과 크리에이티브(노출 20/일)
측정 가능 쪽: Plotta 검색 결과 크리에이티브(노출 538/일)

두 번째 함정 — 베이스라인은 지금 떠놔야 한다

ASC의 ONGOING 분석 리포트에는 일간 인스턴스 보존 한계가 있습니다. 2026-08-06에 28일 pre 창(06-0907-06)을 요청하면 8일치만 돌아옵니다. 같은 요청의 post 창(07-0708-03)은 28/28 완전합니다. 대략 60일 이전 일간 데이터는 소실됩니다.

크리에이티브 자산은 가을(9~11월)에 열립니다. 그때 가서 "붙이기 전 베이스라인"을 재구성하려 하면 데이터가 이미 없습니다. 지금 캡처해서 파일로 남기는 것 외에 방법이 없습니다.

이건 자산과 무관하게 일반화됩니다. 미래에 측정할 계획이 있으면, 측정 시점이 아니라 지금 베이스라인을 떠야 합니다. 데이터 보존 기간은 대부분의 분석 API에 조용히 걸려 있고, 필요해진 시점에는 이미 늦습니다. 그래서 주간 스냅샷을 launchd로 걸어 자동으로 떠 두게 했습니다.

코드/수치

베이스라인 실측(asc_funnel_window_compare.py, 14일 창):

app Impr/d PPV(Impr→PV)
Plotta 538 12.0%
Reelo 282 2.0%
Heardle 203 6.6%
Itda 149 3.9%
Throne 48 4.7%
Cyra 41 9.0%
Quieta 20 9.9%

제작 완료분:

release_tools/creative_assets.py build --app all
→ 140장 (헤더 3840×1646 / 검색 결과 3840×2560, 안전영역 면적의 17~23%)
   Quieta·Throne·Cyra 18로케일 + Plotta 16로케일

베이스라인 보존 자동화:

release_tools/asc_funnel_snapshot.py         # dated JSON + md
주간 launchd: com.ootssu.asc-funnel-snapshot (월 14:20, --if-older-than 7)

한 가지 함정: launchd에서는 pyenv shim이 아니라 실경로 인터프리터를 써야 동작합니다.

이 결론의 한계

  • 원래 계획(매출 상위 3개 전후 비교)은 폐기했습니다. 자산 제작은 유효하지만 측정 설계는 처음부터 성립하지 않았습니다.
  • iOS 27 점유율 30%는 가정값입니다. 실제를 모릅니다. 점유율이 더 낮으면 필요 일수는 더 늘어납니다.
  • pre/post 비교 자체가 열등한 설계입니다. 계절성과 노출 변동이 그대로 섞입니다. 제품 페이지 최적화(appStoreVersionExperimentsV2)의 동시 트래픽 분할이 우월하고, 헤더 자산은 그 테스트 대상으로 명시돼 있습니다. 다만 검색 결과 자산이 여기 포함되는지는 가을에 확인해야 합니다. 지금 세운 대안도 최선이 아니라 차선입니다.
  • 여기 쓰인 노출 수치는 3배 중복 집계를 제거한 값입니다. dedupe 전 숫자로 검정력을 계산했다면 필요 일수를 1/3로 낙관했을 것이고, 계획이 성립한다고 잘못 판단했을 것입니다.

솔직한 부분

이 글의 교훈은 "자산 붙이지 마라"가 아닙니다. 자산은 다 만들었고 붙일 겁니다. 교훈은 실행 전에 검정력부터 계산하라입니다. 계산은 30분이면 끝나는데, 그걸 건너뛰면 몇 달 뒤에 "효과 없음"이라는 거짓 결론을 받습니다 — 효과가 없어서가 아니라 볼 수 없어서 나온 결론을요.

다음에 A/B를 계획하신다면, 자산 만들기 전에 딱 하나만 물어보세요. 이 표본으로, 검출하려는 효과크기를, 현실적 기간 안에 볼 수 있습니까?

관련 글