AB 테스트 소개와 Google Optimize 예제

최범수·2021년 10월 11일
3

메인 랜딩 페이지의 헤드 카피를 바꾸면 정말로 성과가 좋아질까요? 만약 성과가 좋아졌다고 해도, "헤드 카피를 바꿨기 때문에 좋아졌다"라고 확신할 수 있을까요?
AB테스트를 하면 어떤 변화가 어떤 영향을 끼쳤는지 정량적으로 측정할 수 있습니다. 이 글은 AB테스트에 대한 소개와 Google Optimize를 사용하여 AB테스트를 진행하는 코드를 담고 있습니다.


AB 테스트란?

동일한 기간동안 웹 사이트를 방문한 사용자를 임의의 그룹으로 분류하여, 각 그룹에게 다른 웹 사이트를 보여주고 어떤 그룹이 더 성과가 좋은지 정량적으로 판단하는 방법

A그룹 : 대조군

B그룹 : 실험군

대조군과 실험군 중에 "어떤 UI의 유저가 견적 의뢰를 더 많이 할까?"

대조군과 실험군의 견적 의뢰 비율을 측정하고, 수치상으로 더 높은 견적 의뢰 비율을 보인 UI를 선택한다.



왜 AB 테스트를 해야 하는가

1. 제품 개선 가설이 실제로 맞는지 판단하기 위해

상품 구매율을 올리기 위한 가설을 수립

"메인랜딩에서 카테고리를 상위에 노출시키면, 상품 구매율이 증가할 것이다."

정말로 구매율이 증가할 것이라고 확신할 수 없고, 개선안이 오히려 결과를 더 나빠지게 할 수도 있다.

따라서, 가설이 실제로 제품 개선에 도움이 되는지 테스트를 진행해야 한다.



2. 기간에 의한 외부 요인을 차단하기 위해

독립 변수

  • 결과에 영향을 끼칠 것이라고 가정한 변수

종속 변수

  • 독립 변수에 영향을 받아 변경될 것이라고 가정한 변수

통제 변수

  • 독립 변수가 아닌데, 종속 변수에 영향을 끼칠 수 있는 변수

"메인랜딩에서 카테고리를 상위에 노출시키면, 상품 구매율이 증가할 것이다."

  • 독립 변수 : 메인랜딩 카테고리의 상위 노출 여부
  • 종속 변수 : 상품 구매율, 상품 구매 페이지 진입율, 메인랜딩 체류 시간 등
  • 통제 변수 : 유저의 구매 의지, 마케팅 타켓과 예산 변화, 기간(외부 요인)

Before/After Test

A그룹과 B그룹을 서로 다른 기간에 성과 측정을 하는 테스트

사용자를 임의로 나누고 표본이 많다면 유저의 특성은 그룹간 차이가 없다고 가정할 수 있다.

마케팅도 테스트 기간동안 동일하게 유지하여 통제할 수 있다. (테스트로 인해 마케팅이 영향을 받는 것은 바람직하지는 않다.)

그러나, 기간과 그로 인한 외부 요인은 통제가 불가능


B기간에 복날이 포함되어 있었다면, 삼계탕, 도가니탕, 홍삼 등의 구매율이 증가할 수 밖에 없다.

A기간에는 복날이 포함되지 않아서 구매율이 상대적을 낮았고, B기간이 실험의 위너로 결정된다.

즉, 통제 변수가 결과에 영향을 주게 되는 상황

AB 테스트는 동기간에 서로 다른 그룹을 테스트하기 때문에,
기간과 외부 요인이라는 강력한 변수를 통제할 수 있다.



무엇에 대해 AB 테스트를 하는가

UI/UX

  • 랜딩 페이지에 버튼을 더 강하게 노출하면, 구매율이 높아질까?
  • 헤드 카피 워딩을 변경하면, 유저가 다음 페이지로 더 많이 넘어갈까?

알고리즘

  • 유저의 지난 구매내역으로 추천해주는 것보다, 최근 구매 상품을 구매한 다른 유저들의 구매 상품을 추천해주는 것이 구매율이 올라갈까?
  • 푸쉬 알림을 점심시간보다 저녁시간에 발송하는게 더 응답률이 높아질까?


AB 테스트 사용자 분리 방법

노출 분산 방식

  • 페이지가 로딩될 때마다 A그룹인지, B그룹인지 분류하는 방식
    • 첫 접속시 A그룹이여도, 재접속시 A그룹이 될 수도 있고, B그룹이 될 수도 있다.
  • 랜덤성이 가장 높아서, 통계적 유의성이 높다.
  • UI/UX 테스트인 경우, 사용자에게 혼란을 줄 수 있다.
  • 알고리즘 AB 테스트에 적합한 방식

사용자 분산 방식

  • 사용자를 그룹으로 분류한 후, 계속 해당 그룹으로 유지시키는 방식
    • 첫 접속시 A그룹으로 지정하면, 다음에 접속해도 A그룹
  • 한명의 사용자는 계속 하나의 UI/UX만 보게 된다.
  • 특정 사용자에 의해 결과값이 오염될 수 있어서, 표본이 더 많이 필요하다.
  • UI/UX AB 테스트에 적합한 방식

시간 분할 방식

  • 시간대를 세밀하게 분할하여, 시간대별로 그룹을 나누는 방식
    • 홀수 초에 접속하면 A그룹, 짝수 초에 접속하면 B그룹
  • 설계상의 문제로 분산 방식 사용이 어려울 때, 쉽게 사용할 수 있는 방법


테스트 과정

1. 문제 정의

  • 해결하고자 하는 문제를 정의

상품 페이지에서 구매 완료까지 이어지는 고객이 너무 적다.


2. 가설 수립 및 선정

  • 문제를 해결할 수 있는 방안들을 고민하여 가설을 수립

상품 만족도를 더 강조하면, 구매 완료율이 상승할 것이다.

"이런 상품도 있어요" 섹션을 만들면, 구매 완료율이 상승할 것이다.

ICE 방법론

Impact : 실험을 성공했을 때의 효과가 얼마나 큰지

Confidence : 실험이 성공할 확률. 좋은 레퍼런스가 있으면 높은 점수

Ease : 실험 구현이 얼마나 쉬운지

가설마다 ICE 점수를 매기고 ICE점수가 높은 가설을 선정


3. 목표 설정

  • 문제를 해결하기 위해 어떤 지표를 개선하면 좋을지 선정
  • 수치적인 목표를 설정

상품 페이지에서 구매 완료하는 비율을 0.5%에서 2%로 개선한다.

상품 페이지의 구매하기 버튼 클릭율을 5%에서 30%로 개선한다.

  • 카운터 지표도 설정 - 문제 해결과정에서 안 좋아지면 안 되는 지표

구매자의 만족도가 떨어지지 않도록 한다.


4. 디자인, 개발 및 QA

  • 가설을 바탕으로 프로덕트 디자인/개발
  • 사용자 분기는 서버단에서 트래픽을 분산해주어도 되지만, AB 테스트 툴을 사용하면 훨씬 간단하다.
  • Google Optimize, Optimizely 등의 툴이 존재

5. 신뢰도 측정

  • AB 테스트의 수행 결과가 유의미한지 판단

AA 테스트

  • 해당 실험이 실제로 유의미할지 판단하는 방식
  • 사용자를 임의의 두그룹으로 나누고 똑같은 화면을 보여주고, 지표가 비슷하게 나오는지 체크

P-Value

  • 유의확률 : 유의성 검증 지표
  • 0.05인 경우 '100번 중 5번의 예외경우가 있었음'을 의미 → 낮을 수록 좋다.
  • 표본의 사이즈가 작으면 P-Value의 값이 높아진다.

6. 위너 선정 및 프로덕트 반영

  • A그룹과 B그룹의 목표 지표를 보고 위너 그룹을 설정
  • 위너 그룹의 코드를 프로덕트에 반영


Google Optimize

  • 구글의 AB 테스트, 다변수 테스트, 타켓 맞춤형 페이지 설계 등을 할 수 있는 최적화 도구
  • AB 테스트에서 트래픽을 그룹별로 분산. 기본적으로 사용자 분산 방식
  • 테스트 결과 보고서 제공
gtag('event', 'optimize.callback', {
	name: '<experiment-id>',
	callback: (value) => { ... },
})

gtag 함수를 통해 optimize에 현재 유저의 그룹 응답받을 수 있다.
그룹 정보를 받아서 UI를 변경하거나, API 요청을 다르게 할 수 있다.

gtag 함수를 활용하여 실험군, 대조군에게 보여주고자 하는 UI를 변경한다. 컴포넌트를 교체해주는 방법도 있을 수 있고, HTML 요소에 dataset에 실험군, 대조군 정보를 넣어두고 선택적으로 UI를 보여줄 수도 있다.

아래는 바닐라 자바스크립트로 실험군과 대조군 UI를 다르게 보여주는 예시이다.

<html>
  <head>...</head>
  <body>
    <h1 class="head-title" data-abtest="ex-01" data-variant="a">
      실험군
    </h1>
    <h1 class="head-title" data-abtest="ex-01" data-variant="b">
      대조군
    </h1>
    <button data-abtest="ex-01" data-variant="a">실험군 더보기</button>
    <button data-abtest="ex-01" data-variant="b">대조군 더보기</button>		

    <script>
      function abtest(experimentId, experimentName) {
        const variantMapper = { 1: 'a', 2: 'b' }

        gtag('event', 'optimize.callback', {
          name: experimentId,
          callback: (value) => {
            // gtag value값은 숫자로 들어오는데, 이해하기 쉬운 a, b로 변경해줌
            const variant = variantMapper[value]

            // HTML 문서에서 현재 실험에 해당하는 요소를 모두 선택
            const abtestElements = document.querySelectorAll(
              `[data-abtest="${experimentName}"]`
            )

            // 유저가 실험군이냐, 대조군이냐에 따라 요소를 삭제하거나, 속성만 삭제
            abtestElements.forEach((abTestElement) => {
              if (abTestElement.dataset.variant === variant) {
                delete abTestElement.dataset.abtest
                delete abTestElement.dataset.variant
              } else {
                abTestElement.remove()
              }
            })
          },
        })
      }

      abtest('b6GUWhfjQlSJiCPVWhkWEw', 'ex-01')
    </script>	
  </body>
</html>

깃허브


레퍼런스

AB Test 기본부터 심화까지 -1편

AB Test 기본부터 심화까지 -2편

A/B테스트에서 하면 안되는 7가지 실수

A/B Testing Calculator for Statistical Significance | SurveyMonkey

A/B 테스팅이란

profile
프론트엔드 개발자

0개의 댓글