데이터분석

67-(2). A/B Test

장수우 2024. 4. 9. 16:48
학습주제
  • A/B Test 결과 분석이란?
주요 학습 내용
  • A/B 테스트 결과 분석은 과학이 아닌 예술
    • 경험이 중요하다.
    • 가설을 잘 세워야 배우는 것이 있다.
    • 결과 분석은 객관적이고 공개되어야한다.
      - AB 테스트 실험을 제안한 사람이 분석하는 것은 안좋다.
      - 다양한 사람들이 모인 자리에서 결과를 분석하고 여러 의견을 듣는 것이 좋다
      ex) 1.  AB테스트 주간미팅, 시니어 데이터 분석가들이 돌아가면서 수행 (No를 잘 할 수 있어야한다.)
            2. 처음 40분은 기존 테스트들중 결과가 보이는 것들을 리뷰 (p-value가 유의미 한 것들)
            3. 마지막 20분은 새로운 AB 테스트 제안들을 리뷰하고 스케줄
  • Outlier가 A/B 테스트에 미치는 영향
    • 어느 서비스나 매출 등에 있어 큰 손들이 존재
      1. 이런 큰 손들이 어느 버킷에 들어가느냐가 분석에 큰 영향을 끼침
      2. 이런 사용자들을 Whale user라고 부르고 분석에서 제외할 수 있다.
      3. A/B 테스트가 아니더라도 큰 손들의 retention/churn rate을 살펴볼 필요가 있음
    • 봇 유저(scraper bot)가 한쪽으로 몰리는 경우
      1. session/impression등에 큰 영향을 줄 수 있음
      2. 생각보다 큰 문제
      3. 대략 40%의 트래픽까지 봇 트래픽일 수 있음. 음성 봇들은 정체를 밝히지 않음
    • 항상 A/B 테스트 결과는 다양한 관점에서 바라봐야함
  • 잘못된 가설
    • Survivorship Bias
      1. Subscription 서비스라면 Support call을 하는 사람들의 churn rate (이탈율)은 평균보다 높을까?
      2. 가끔은 가설이 덜 중요한 문제를 해결하려는 경우가 있음. 그래서 가설에 대해 많은 질문을 하는 것이 중요
      3. 정말 중요한 지표를 보고 있는가?
        - 성공실패의 기준으로 더 중요한 지표가 있는지 항상 고민?
        - 무슨 테스트이건 기본으로 봐야하는 중요 지표들이 있음 -> 매출액이나 구매율이 대표적
  • AB 테스트 분석 시각화 대시보드 요구 조건
    • AB 테스트 전체 기간에 걸쳐 키 지표가 비교 가능해야 한다
    • 일별로 키 지표의 비교가 가능해야 한다
    • 키 지표의 경우 통계적으로 유의미한지 무의미한지 표시가 되어야 한다 (Color coding)
    • 트래픽(사용자) 메타 데이터가 있다면 이를 바탕으로 필터링이 가능해야 한다
      1. 성별
      2. 나이
      3. 지역
      4. 신규 사용자 vs. 기존 사용자
      5. Acquisition channel
  • AB 테스트들간의 Interaction 이란?
    • 예를 들어 4명의 사용자를 대상으로 2개의 테스트를 동시에 진행한다고 가정
    • A1-B2, A2-B1 조합은 테스트가 되지 않는다.
    • 즉 두 테스트들이 독립적으로 테스트되는 것이 아니다
      - 조합에 따라 결과가 달라지고, 후처리를 통해 영향을 살펴보는 것이 중요하다.(아니면 버킷팅을 미리 해야함)
  • A/B 테스트 Variant 크기 비교
    • A/B 테스트에서 기본은 먼저 Variant간의 트래픽 크기가 동일한지 살펴보는 것
      - 여기서 동일하다는 의미는 통계적으로 차이가 오차 범위안에 있는지를 의미 (보통 95% 신뢰구간을 사용)
    • binomial distribution(이항분포)에 해당 (A 혹은 B)
  • A/B 테스트 QA의 중요성
    • 많은 A/B 테스트는 개발자 혹은 디자이너의 손을 타고 구현이 됨
    • 즉 그 과정에서 A/B 테스트 제안자의 생각이 제대로 반영되지 않을 수 있음
      -  또한 코딩이 필요하다면 항상 버그의 존재 가능성이 있음
      -  이를 제대로 QA하는 것은 A/B 테스트 제안자의 책임이기도 함
    • 특히 A/B 테스트 시스템 자체가 새로 만들어졌거나 변경이 생긴 경우 QA는 더 중요해짐
    • 주기적으로 A/A 테스트를 수행해보는 것이 중요함
  • 만일 A/B 테스트 결과가 전체적으로 안좋지만 특정 사용자층에 대해서만 좋다면?
    - A/B 테스트 결과를 다양한 세그먼트의 사용자별로 보는 것이 중요하다.(4분할 등등)
  • A/B 테스트 성공의 경우 지표는 항상 좋아야 하나?
    • 테스트에 따라서는 지표가 개선되지 않아도 성공으로 간주할 수 있음
      - 운영비용이 적은 방식이라던지 레거시 방식을 새로운 방식으로 교체하는 경우 지표가 같은 경우도 성공으로
        간주 가능
    • 다시 한번 이런 부분이 가설에 분명하게 미리 명시되어 있어야함
  • 모바일 앱 기반 A/B 테스트의 난점
    • 앱단의 시간을 그대로 믿고 사용하면 낭패
      1. 특히 앱이 온라인이 아닌 상황에서 동작가능하는 경우 더 큰 문제가 됨
      2. 앱에서 따라서는 사용자의 오프라인 이벤트를 사용자가 온라인이 되었을 때 전송받음
      3. 이 경우 사용자의 과거 데이터가 AB 테스트 시작 이후에 전송될 수 있음
    • 앱 업데이트가 필요하다면 테스트에 충분한 수의 앱 업데이트를 하는데 시간이 걸림
  • 안 좋은 AB 테스트 가설 예는 무엇이 있나요?
    • 잘못된 가설을 바탕으로 하는 경우
      - CS팀 문의자들의 Churn rate을 낮추겠다
    • 굉장히 임팩트가 작은 기능 구현에 사용하는 경우
      - 즉 가설이 중요한 문제를 다루지 않는 경우
    • B2C 환경에서 다른 가격대를 테스트하는 경우
      - 컨트롤하기가 쉽지 않음
    • 검색엔진 UI와 검색엔진 알고리즘을 동시에 테스트하는 경우
      - 한번에 하나만 테스트
  • A/B 테스트 얼마나 기다려야 하나?
    • 기본적으로는 적어도 일주일은 테스트를 돌려야함
      - 많은 테스트들이 처음에는 통계적 유의미한 차이를 초반에 보이다가 시간이 지나면서 없어짐
    • Data peeking problem
      - 웹 스케일에서는 z-test등에 전통 통계학에서 사용하는 최소 샘플의 크기가 아무 의미가 없음 (시대적 변화)
    • 이는 최소 샘플의 크기와도 연관됨
      - 가설의 일부로 원하는 지표의 성공실패 기준에 따라 최소 트래픽 기준을 미리 설정하는 것이 좋음
      - 도움줄 수 있는 사이트 : https://www.evanmiller.org/ab-testing/sample-size.html
    • 사용자들이 익숙한 UI/UX의 변경은 최소 2-4주를 실행해야함
  • Which Side is Better in A/B Test?
    • Basically NULL Hypothesis (귀무 가설)
      - Assumes A and B are the same
    • 예) A와 B의 구매율은 동일하다
    • CLT를 사용하면 데이터 분포를 정규분포로 변환 가능
    • B-A를 계산하여 동일한지 아닌지 여부를 판단
      - t-test를 사용하여 P value 혹은 Z score를 계산하여 판단
      - 얼마나 발생하기 힘든 일인지를 보는 것! 정규분포라면 양끝단이 됨
    • Normal Distribution (정규 분포) - Bell Curve
      - 평균(μ) 및 표준 편차(σ)가 형상을 결정합니다
    • Standard Normal Distribution
      • 평균 0, 표준편차 1, 그래프 면적 1 
      • Z 분포라 부르기도함
      • 신뢰구간과 z-score (x 축)
        - 90% -> 1.645
        - 95% -> 1.96
        - 99% -> 2.575
      • 양측검정 vs. 단측검정
        - Two-sided vs. one-sided
        - 95% 단측검정이라면
        - 커져야하는 경우 1.645
        - 작아져야하는 경우 -1.645
  • 어떤 관점이 더 좋은가?
    - p-value 값 및 통계적 유의성을 계산해야한다.
    - 더 많은 표본은 더 많은 의외성을 줄 것
    - 모든 데이터가 정규분포를 따르지는 않는다 = 중심극한 정리를 사용한다.
  • Central Limit Theorem (중심 극한 정리)
    • 샘플의 평균은 정규 분포를 따른다
      - 정규 분포로 근사화된 분포의 산술 평균(n > 30)
      - 데이터 표본이 증가함에 따라 표준 편차가 감소함
      - 이는 모집단의 분포와 상관없음
    • 샘플의 크기가 클수록 샘플을 뽑는 수가 클수록 더 정규 분포에 가까워짐
      - 만약 우리가 모집단이 있고 거기에서 충분히 큰 표본을 추출한다면, 그 표본은 평균(각 표본의 평균)은
        대략 정규 분포를 따른다.
    • 모집단에서 샘플을 반복해서 수집 (샘플의 크기는 30 이상)
      1. 각 샘플의 평균을 계산
      2. 평균들의 평균이 모집단 평균과 유사해짐 (샘플 수가 클수록 샘플 수집을 많이 할수록)
      3. 샘플 평균의 히스토그램은 정규분포를 따르게 됨
      4. 수집된 샘플 평균들간의 차이나 합도 정규분포를 따름
    • 샘플링
      import numpy as np
      import seaborn as sns
      import statistics as stat
      
      x = np.random.normal(size=10000) # 표준 정규 분포 데이터 생성
      x[0:10]
      max(x)
      min(x)
      stat.mean(x)
      stat.stdev(x)
      
      sns.displot(x)
      
      ## 정규분포 모집단에서 샘플링
      
      # replace를 False로 지정하면 여기서 샘플된 데이터들은 x에서 제거된다
      x_sample = np.random.choice(x, size=10, replace=False)
      x_sample
      stat.mean(x_sample)
      stat.stdev(x_sample)
      
      def sample_mean(population, sample_size, n_samples):
        sample_means = []
        for i in range(n_samples):
          sample = np.random.choice(population, size=sample_size, replace=False)
          sample_mean = stat.mean(sample)
          sample_means.append(sample_mean)
        print(stat.mean(sample_means),stat.stdev(sample_means))
        return sample_means
        
        sns.displot(sample_mean(x, 10, 10))
        
        
        ##Skewed 분포를 갖는 모집단에서 샘플링
        
        from scipy.stats import skewnorm
      
      s = skewnorm.rvs(12, size=10000)   # 첫번째 값이 0이면 정규분포가 리턴됨
      
      stat.mean(s)
      
      sns.displot(s)
      sns.displot(sample_mean(s, 10, 1000))
      sns.displot(sample_mean(s, 1000, 1000))
      
      ## Multimodal 분포를 갖는 모집단에서 샘플링해보기
      
      m = np.concatenate((np.random.normal(size=10000), np.random.normal(loc = 4.0, size=10000)))
      
      stat.mean(m)
      stat.stdev(m)
      
      sns.displot(m)
      sns.displot(sample_mean(m, 1000, 1000))
      
      ## Uniform 분포를 갖는 모집단에서 샘플링하기
      
      u = np.random.uniform(size=10000)
      
      stat.mean(u)
      stat.stdev(u)
      
      sns.displot(u, kde=False)
      sns.displot(sample_mean(u, 1000, 1000))
반응형

'데이터분석' 카테고리의 다른 글

68. 가상 데이터 기반 A/B 테스트 분석  (0) 2024.04.09
67-(3). A/B Test  (0) 2024.04.09
66-(1). A/B test  (4) 2024.03.05
65. 추천 시스템, 컨텐츠 기반 필터링  (0) 2024.02.28
64. 데이터 마이닝  (1) 2024.02.27