By. Buzzvil
안녕하세요. 모바일 첫화면 미디어 플랫폼 버즈빌의 Business Intelligence Manager Elia 입니다.
저희 버즈빌에서는 여타 모바일 환경에서 작업하는 회사와 마찬가지로 무수히 많은 a/b 테스팅을 통해 프로덕트를 개선하고 있습니다. 이번 포스팅에서는 a/b 테스팅을 실제로 수행할 때 주로 발생하는 궁금증에 대해서 경험적으로 느낀 바를 공유하려 합니다.
먼저 이 글을 써야겠다고 생각하게 된 것은, 옆자리에 앉은 PM Jim의 질문에서 시작되었습니다.
“a/b 테스팅할 때, 샘플 사이즈를 어떻게 정해요?”
이 질문은 스타트업 관련, 데이터 관련 컨퍼런스에서 항상 등장하는 주제라서, 한 번 정리해 보면 (hopefully) 많은 사람들한테 도움이 될 수 있을 것 같았습니다. 그리하여 이왕 하는 김에 a/b testing 관련해서 그간 생각해왔던 이것저것을 샘플링과 해석으로 나눠서 정리해보려 합니다.
보통 a/b testing에 들어가는 통계 기법(?)은 t-test입니다. 그룹 a의 평균값과 그룹 b의 평균값이 같은 것인지 다른 것인지를 추정하는 테스트입니다. (group A와 group B의 값은 쉽게 관찰 가능한 것인데, 둘이 같은지 다른지를 판단한다는 것이 헷갈리실 수 있겠지만 이는 interpretation 부분에서 다루겠습니다)
일반적으로 학계에서 많이 쓰이는 알파 에러율 5%와 테스팅 파워 95%를 위해서는 샘플이 120 정도만 되면 됩니다. 이는 실제 인더스트리에서 행해지는 테스트의 샘플 사이즈에 비하면 크지 않은 숫자이므로, 모바일 환경에서 테스트를 진행할 때에는 크게 걱정할 필요가 없는 수준입니다. (반대로 만약 샘플 사이즈가 120보다 작다면, 많은 어려움에 봉착할 수 있습니다.)
샘플 사이즈가 충족되었다면, 그 다음에 알아봐야 할 문제가 진짜 문제입니다. 보통 a/b testing이 혼선을 겪는 부분이 이 부분부터입니다.
첫번째는 샘플들이 충분히 랜덤하게 추출되어야 한다는 부분입니다. 여기서 랜덤 샘플링이 필요한 이유는, a/b testing에서 확인해보고자 하는 stimulus가 오롯이 잘 표현되어야 하기 때문입니다.
예를 들어서 모바일 환경에서의 a/b testing 중 가장 많이 등장하는 KPI 중 하나인 CTR을 생각해봅시다. 샘플을 500명씩 뽑아서, group A에게는 초록색 글자를 보여주고 group B에게는 파란색 글자를 보여줘서, 파란색과 초록색 중 CTR이 높은 쪽으로 폰트 색깔을 바꾸는 테스트를 가정해 봅시다.
group A와 group B가 랜덤으로 배정되어야만 두 그룹의 유일한 차이점은 폰트 색깔이 될 것이고, 그럴 때에 폰트 색깔이 만들어내는 차이점을 온전히 관찰할 수 있습니다.
만약 group A에 초록색을 좋아하는 유저들이 모여있다면?
만약 group A에 폰트 색깔과 관계없이 CTR이 높은 유저들이 모여있다면?
그럴 경우에는 결과가 ‘group A = 3% vs group B = 1%’라고 나온다고 하더라도, ‘초록색이 만들어내는 CTR > 파란색이 만들어내는 CTR’이라고 결론지을 수 없습니다.
그럼 어떻게 랜덤 샘플링을 할 수 있을까요? 일반적으로는 유저를 가입 시점으로 줄을 세워서 자연수를 1부터 N까지 부여한 뒤에 mod function을 이용해서 나머지값을 이용해서 그룹을 지을 수 있습니다. 그룹이 두 개인 경우엔 mod(X, 2)로 만들어서 그룹 0과 그룹 1을 만들 수 있습니다.
서비스에 가입하는 순서의 홀짝 숫자에 따라서 유저군의 특성이 갈릴 위험이 없으므로, 이 방식으로 대부분의 노이즈를 없앨 수 있습니다. 즉, 90% 이상 random sampling이 가능해집니다. 남아있는 10%는 경험에서 체득한 팁이므로 서비스의 특성에 따라 적용되지 않을 수도 있습니다.
sample은 population을 반영해야 합니다.
population을 랜덤하게 반영해야 한다는 것이 위에 기술된 내용이었고, 이번 단락에서는 sample이 population을 반영해야 한다는 보다 근본적인 이야기를 다뤄보려 합니다.
sample이 population을 온전히 반영하지 못하면 실망스러운 결과가 발생할 수 있습니다.
실제 버즈빌에서 있었던 예를 들어서 설명드리겠습니다. 사용된 숫자는 이해를 돕기위해 예시로 사용하였습니다.
버즈빌에서는 랜덤 샘플링의 이론에 충실하게 NRU만을 대상으로 테스트를 진행할 때가 있습니다.
위의 폰트 색깔의 예시를 이어나가면, 초록색 글씨와 파란색 글씨의 차이를 구분하기 위해서, 유저들이 아무런 선입견 없이 파란색과 초록색의 차이에 어떻게 반응하는지를 확인해보기 위해 샘플을 NRU로 한정한 적이 있습니다.
오래된 유저들은 기존의 색깔인 초록색에 익숙한 경험이 있을테니, 새로운 색인 파란색에 더 민감하게 반응할 것이라는 가정이 있었고, 이러한 “노이즈”를 없애기 위하여 샘플을 NRU로 한정한 것이었습니다.
그리하여 테스트를 통해 ‘초록색 = 3% vs 파란색 = 3.6%’로 20% 발전이라는 야심찬 계획을 가지고 파란색을 전체 유저를 대상으로 구현한 결과! 기존의 3% CTR이 3.15%로 5% 발전하는 실망스러운 경험을 하게 되었습니다.
여러 이유가 있겠지만, sample이 population을 반영하지 못한 부분이 가장 큽니다.
우리의 전체 유저군을 population으로 봤을 때, NRU는 특정한 유저군을 의미합니다. 그들은 새로 서비스에 들어왔기 때문에 지금까지 이뤄진 learning도 없고, 그러므로 폰트 색깔에 대한 선입견도 없습니다.
그렇지만 선입견이 없다는 점이 문제였습니다.
테스트 자체만을 위해서는 깔끔한 샘플링인 것처럼 보였지만, 사실 우리가 테스트를 통해 향상시키고자 하는 목표는 전체 유저의 CTR이지 NRU의 CTR이 아니었습니다. 전체 유저 중 NRU를 제외한 유저들은 각각 서비스 경험에 따라 학습된 부분이 다르고, 그러므로 새로운 font color에 반응하는 정도도 다릅니다.
population의 CTR을 높이고 싶었다면 샘플링 역시 population을 대상으로 수행되었어야 했고, 서비스 이용시간에 따른 learning이 걱정되었다면 learning의 정도가 두 그룹에 고르게 들어가서 상쇄될 수 있도록 가입 순서대로 차례차례 샘플링하면 해결되었을 것입니다.
sampling은 noise를 상쇄할 수 있도록 random하게 수행되어야 하지만, 내가 달성하고자 하는 KPI의 대상이 되는 population을 충실히 반영해야 한다는 대전제를 반드시 기억해야 합니다.
이제 샘플링도 끝났고 각각의 그룹에 각각의 stimulus를 주었습니다. 그러면 각 그룹이 어떤 반응을 보였는지 결과를 해석해야 합니다.
다시 글씨 색깔의 예로 돌아가 봅시다.
population을 대표하는 random sample group A 500명과 group B 500명에게 각각 초록색 글씨와 파란색 글씨를 보여주는 실험을 2주일간 진행하였습니다.
결과는 group A는 CTR 3%이고 group B는 CTR 4%를 기록하였습니다.
그렇다면 group B가 더 좋은 결과를 보인 것인데, 이 결과를 믿어도 되는 것일까요?
group B의 CTR 4%가 group A의 CTR 3%보다 높은 것이 믿을만한 것이라는 질문은 무슨 뜻일까요?
이를 이해하기 위해서 우리는 우선 group A의 CTR 3%가 고정되어있는 숫자가 아니라, 유저별로 혹은 시간이나 날씨와 같은 외부적 환경에 따라 조금씩 바뀔 수 있는 숫자라는 점을 알아야 합니다.
group A의 CTR 3%는 group A에 속한 CTR 평균 10%를 보여주는 유저, 평균 0.1%를 보여주는 유저, 그리고 새벽 3시에 최고로 졸릴 때 글자를 접한 유저, 오후 10시 프라임 타임에 글자를 접한 유저의 모든 경우의 수를 평균해서 보여주는 숫자입니다.
그러므로 똑같은 유저들에게 정확히 같은 조건으로 2주간 실험을 다시 하면 3.1%가 될 수도 있고 2.7%가 될 수도 있습니다. 다만 이번 실험에서 3%를 보였다는 의미입니다.
이는 group B가 보여준 4%도 마찬가지입니다. 다음 실험에서는 3.5%가 나올 수도 있고, 4.2%가 나올 수도 있습니다.
다시 원래의 질문으로 돌아가면, “group B의 CTR 4%가 group A의 3%보다 높은 것이 믿을만한 것인가?”라는 질문은, 다시 말하면 “지금 보여주는 차이 1%가, 과연 다음 실험에서도(그래서 전체에게 적용되면 영구적으로) 반복될 것인가?”라는 질문과 마찬가지입니다.
위 질문을 통계적으로 해석하면 과연 3%와 4%라는 값이 같은 분포에서 나왔는지 다른 분포에서 나왔는지를 묻는 것입니다.
만약 위와 같이 3%와 4%가 같은 분포에서 나왔다면, 다음에 똑같은 조건으로 실험을 한다면 2.5% vs 4.5%가 나올 수도 있고, 이와 같은 확률로 3% vs 2%가 나올 수 있습니다. 이런 경우에는 원래 질문인 “믿을만한 것인가?”에 “믿을 수 없다”는 대답이 나오는 것이고, 이는 결국 “다음 실험에도 지금과 같은 결과가 나올 것이라고 장담할 수 없다”는 것입니다.
3%와 4%가 정말 의미가 있는 차이를 가지려면 둘이 다른 분포를 가져야 합니다.
위와 같이 3%와 4%가 서로 다른 분포에서 나온 것이라면, 다음 실험에서도 3%와 4%의 차이가 유지될 확률이 높고, 그러할 때에 “group B의 CTR 4%가 group A의 3%보다 높은 것이 믿을만한 것이다”라고 할 수 있습니다.
문제는, 우리는 둘이 같은 분포에서 나왔는지 다른 분포에서 나왔는지 알 길이 없다는 것입니다. 단지 우리가 알 수 있는 것은 group A는 3%를 보였다는 것이고 group B는 4%를 보였다는 사실 뿐입니다. 이 정보를 가지고 우리는 통계적인 추정을 해야하는 것이고, 그것이 a/b testing에서 하고자 하는 t-test가 도와주는 부분입니다.
결과를 보는 방법은 매우 쉽습니다. 구글에 조금만 찾아보면 많은 계산기가 등장하므로 아무 것이나 찾아서 하셔도 좋고, 이 글에서 조금 편의를 제공하자면 https://abtestguide.com/calc/ 를 이용하셔도 좋습니다. (버즈빌과는 아무 관계가 없는 사이트입니다)
어차피 프로그램이 매우 편하게 계산해 주지만, 혹시 궁금하신 분을 위해서 약간의 설명을 추가하자면, 기본적으로 그룹의 크기와 관계가 있습니다. 직관적으로 생각해도 각각 10명에게 테스트를 해서 3%와 4%의 차이가 나오는 것과 10,000명에게 테스트해서 3%와 4%의 차이가 나는 것은 신뢰도가 다를 수밖에 없을 것입니다.
각각 10,000명의 샘플을 가지고 3%와 4%가 나온다면, 두 그룹이 다른 분포를 형성하고 있을 확률이 보다 높다고 할 수 있을 것입니다.
저희의 예를 위에다 입력해보니, significant 하지 않다는 결과가 도출되었습니다. 이는 즉, 다음 번에 똑같은 조건으로 실험을 하면 group A의 결과가 group B의 결과보다 작게 나오는 것이 반복될 확률이 충분히 크지 않다는 의미입니다.
confidence를 95로 설정했으므로 보다 정확히 말하면 “실험을 무한히 반복할 때, group A의 CTR이 group B의 CTR보다 낮은 경우가 95% 이하로 발생할 확률이 점점 커진다”라는 말입니다.
물론 개인적으로는 a/b testing을 할 때 신뢰도 95%에 너무 집착할 필요가 없다는 입장입니다. 무한히 했을 때 95% 이상 같은 결과가 반복되지 않는다 하더라도 회사로서는 충분히 좋은 의미가 있을 수 있으니, 이 부분에 관해서는 사용자가 스스로 설정하면 될 것 같습니다.
매일매일을 독립적인 테스트라고 생각하면 훨씬 간단할 수 있습니다
버즈빌에서는 테스트를 진행할 때 많은 경우 결과를 일별로 끊어서 그래프를 확인합니다.
group A와 group B가 2주일간 보여준 결과를 하나의 실험이라고 본 것이 위에 적어놓은 내용이라면, 2주일 동안 매일매일을 새로운 실험으로 보고 14개의 실험을 한 경우라고 생각해본다고 가정해봅시다.
매일매일 group B가 group A에 비해서 높은 결과를 보였다면, 사실 위에서 계산한 과정을 거치지 않아도, 둘이 확실히 다르다고 확신하셔도 무방합니다. 동전을 던져서 앞면이 나올 확률은 50%지만, 동전을 14번 던져서 14번 앞면이 나올 확률은 거의 0%에 가깝기 때문인 것과 같은 이치입니다.
테스트를 한 번 수행해서 나온 값 3%와 4%는 통계적으로 유의미한 결과인지 생각해봐야 하지만, 14번동안 일관되게 “group A’s CTR < group B’s CTR”이라면 group B의 CTR이 유의미하게 높다고 봐도 무방할 것입니다.
결과가 매일매일 엎치락뒤치락 하다면, 위와 같이 전체 값을 놓고 판별해보는 과정이 필요할 것이고, 14번 동안 10번은 B가 높고 4번은 A가 높은 수준이라면, 아마 더 깊이 분석해보지 않아도 높은 확률로 실제로 B가 높을 것입니다.
진짜 현실적으로 판단하기 어려운 때가 매일매일의 값은 일반적으로 B가 높은데, 어떤 특수한 날 A의 값이 이상한 정도로 높은 때, 즉 아웃라이어가 있을 때입니다.
그럴 때는 보통
아웃라이어를 만들어내는 유저를 찾아보고 샘플에 포함시키는 것이 합당한지 판단해본다.
실험의 외부적인 요소가 그 아웃라이어를 만들어내지 않았을지 알아본다. (데이터의 인풋 자체가 잘못됐을 가능성 조사)
등을 통해 문제를 해결할 수 있습니다.
데이터를 시간별, 일별, 주간별로 쪼개어 보면 하나로 합쳐져 있을 때 보이지 않았던 많은 인사이트를 얻을 수 있고, 운이 좋으면 통계 분석을 건너뛰고도 정확한 결론을 내릴 수 있는 가능성이 있으므로 반드시 추천하는 팁입니다. 한 번의 큰 테스트도 좋지만, 14번의 작은 테스트 역시 더 많은 인사이트를 줄 수 있는 것과 같은 이치입니다.
이상으로 a/b 테스팅과 관련된 포스팅을 마치겠습니다.
읽다가 궁금하신 사항이나 맞지 않는 정보가 담겨있다고 생각하시는 부분 있으면 언제든지 문의주시기 바랍니다.
독자 여러분의 a/b 테스팅에 조금이나마 도움이 되기를 바랍니다. 감사합니다.