Database for Everything

[R 프로그램] Cookie Cats 게임 데이터_A/B Test(1) 본문

R

[R 프로그램] Cookie Cats 게임 데이터_A/B Test(1)

Yeenn 2022. 3. 29. 02:37
728x90

 https://www.kaggle.com/code/mursideyarkin/mobile-games-ab-testing-with-cookie-cats/data

 

Mobile Games AB Testing with Cookie Cats

Explore and run machine learning code with Kaggle Notebooks | Using data from Mobile Games A/B Testing - Cookie Cats

www.kaggle.com

 

A/B Test란?

: 기존 서비스(A)와 새로 적용하고 싶은 서비스(B)를 통계적인 방법으로 비교하여 새로운 서비스가 기존 서비스에 비해 효과가 있는지 알아보는 방법

 

 A/B Test의 단계

1. 가설설정

2. 메트릭 정의

-가설이 참인지 거짓인지 결정하는 측정 기준 

-하나의 가설에 2개 이상이 될 수 있음

3. 실험 설계

4. 결과 도출

-검정 결과 통계적으로 유의한 차이가 있다면 새롭게 적용한 서비스가 기존의 서비스보다 낫다는 결론을 내릴 수 있음


● 데이터셋 설명

-페이지 상단의 Kaggle 링크를 클릭하면, Cookie Cats 게임에 관한 데이터를 다운받을 수 있다.

-가설 검정을 통해 a/b test를 진행할 수 있는 지표들이 포함된 데이터셋을 확인할 수 있다.

변수 설명
user_id 게임 플레이어의 고유 ID
version 게임 플레이어가 gate_30 또는 gate_40에 해당하는지 여부
sum_gameronds 게임 플레이어가 게임을 설치한 후 2주동안 플레이한 횟수
retention_1 게임 플레이어가 게임을 설치한 후 하루 뒤에 다시 접속했는지 여부
retention_7 게임 플레이어가 게임을 설치한 후 일주일 뒤에 다시 접속했는지 여부 

 

 

 

● 데이터 Load

데이터를 불러온 후, head()와 str()를 통해 데이터를 탐색한다.

#데이터 불러오기
cat<-read.csv("cookie_cats.csv")

#데이터 확인하기
head(cat)
#  userid version sum_gamerounds retention_1 retention_7
#1    116 gate_30              3       FALSE       FALSE
#2    337 gate_30             38        TRUE       FALSE
#3    377 gate_40            165        TRUE       FALSE
#4    483 gate_40              1       FALSE       FALSE
#5    488 gate_40            179        TRUE        TRUE
#6    540 gate_40            187        TRUE        TRUE

str(cat)
#'data.frame':	90189 obs. of  5 variables:
# $ userid        : int  116 337 377 483 488 540 1066 1444 1574 1587 ...
# $ version       : chr  "gate_30" "gate_30" "gate_40" "gate_40" ...
# $ sum_gamerounds: int  3 38 165 1 179 187 0 2 108 153 ...
# $ retention_1   : logi  FALSE TRUE TRUE FALSE TRUE TRUE ...
# $ retention_7   : logi  FALSE FALSE FALSE FALSE TRUE TRUE ...

 

 

 

● EDA 위한 데이터 타입 변형

분석에 사용할 범주형 변수들을 factor형으로 data타입을 변형하였다. (version, retention_1, retention_7)

#데이터 type 변경
cat$version <- factor(cat$version)
cat$retention_1 <- factor(cat$retention_1)
cat$retention_7 <- factor(cat$retention_7)

 

 

 

● EDA (version(gate_30/gate_40) 크기 비교)

gate_30과 gate_40(version)의 비율을 살펴보았다.

시각화를 통해 살펴본 결과, gate_30=44700, gate_40=45489로, gate_40 그룹에 속하는 게임 플레이어 수가 gate_30 그룹에 속하는 게임 플레이어 수보다 아주 조금 더 많았다. 

#EDA
library(ggplot2)
library(dplyr)
cat %>% 
  group_by(version) %>% 
  count() %>% 
  ggplot(aes(x=version, y=n, fill=version))+geom_bar(stat="identity")+geom_text(aes(label=n), size=8)

 

 

 

● EDA (game 설치한 후 2주동안 게임을 플레이한 횟수)

게임을 설치한 후 2주 동안 게임을 플레이 한 횟수를 시각화를 통해 살펴보았다.

히스토그램이 왼쪽으로 매우 치우친 형태를 보이고 있다. (분포형태가 한 쪽으로 몰려 있어 잘 보이지 않아 scale_x_continuous, scale_y_continuous로 축 범위를 조정해주었다.)

 

게임의 경우, 게임을 플레이한 횟수가 특정한 규칙에 따라 패턴이 나타나기 보다는 개별 플레이어에 따라 많은 차이를 보이기 때문에 이러한 분포를 보이는 것으로 유추할 수 있었다. 

#게임 횟수 범위 확인
range(cat$sum_gamerounds)

#히스토그램 한 눈에 들어오게 축 범위 조정
diff(range(cat$sum_gamerounds))/30
cat %>% ggplot(aes(x=sum_gamerounds))+geom_histogram()+
  scale_x_continuous(limits = c(0, 1000))+
  scale_y_continuous(limits = c(0, 25000))

 

 

 

● EDA (game 설치한 후 1일 뒤에 다시 접속했는지)

게임을 설치한 후 하루 뒤에 다시 접속했는지 여부를 시각화를 통해 살펴보았다.

1일 뒤에 다시 접속한 플레이어 수(True=40153)가 다시 접속하지 않은 플레이어 수(False=50036)보다 적지만, 차이가 비교적 적은 편임을 확인할 수 있다. 

#EDA(retention_1)
cat %>% 
  group_by(retention_1) %>% 
  count() %>% 
  ggplot(aes(x=retention_1, y=n, fill=retention_1)) +
  geom_bar(stat="identity")+
  geom_text(aes(label=n), size=8)

 

 

 

● EDA (game 설치한 후 7일 뒤에 다시 접속했는지)

게임을 설치한 후 일주일 뒤에 다시 접속했는지 여부를 시각화를 통해 살펴보았다.

7일 뒤에 다시 접속한 플레이어 수가 다시 접속하지 않은 플레이어 수보다 압도적으로 적다. (True=16787 < False=73408)

 

7일 뒤에 다시 접속한 플레이어는 1일 뒤에만 다시 접속한 플레이어보다 게임에 대한 로열티가 더욱 높은 고객일 수 밖에 없다. 지속적인 관심을 보여야지만 일정한 시간 후에도 게임에 다시 접속하고자 할 것이기 때문이다. 

#EDA(retention_7)
cat %>% 
  group_by(retention_7) %>% 
  count() %>% 
  ggplot(aes(x=retention_7, y=n, fill=retention_7))+
  geom_bar(stat="identity")+
  geom_text(aes(label=n), size=8)

 

 


1. A/B test 가설 설정

1. sum_gamerounds 관련

-gate_30에 해당하는 플레이어보다 gate_40에 해당하는 플레이어의 2주동안 평균 게임 플레이 횟수가 더 많을 것이다.

 

2. retention_1 관련

-gate_30에 해당하는 플레이어보다 gate_40에 해당하는 플레이어의 하루 뒤 다시 접속하는 비율이 더 높을 것이다.

 

3. retention_7 관련

-gate_30에 해당하는 플레이어보다 gate_40에 해당하는 플레이어의 일주일 뒤 다시 접속하는 비율이 더 높을 것이다. 

 

2. 메트릭 정의 

1. 가설 1) 2주동안 평균 게임 플레이 횟수

2. 가설 2) 게임에 1일 뒤 다시 접속하는 비율

3. 가설 3) 게임에 7일 뒤 다시 접속하는 비율

 

3. 실험 설계

-대조군: gate_30

-실험군: gate_40


1. sum_gamerounds 관련

-gate_30에 해당하는 플레이어보다 gate_40에 해당하는 플레이어의 2주동안 평균 게임 플레이 횟수가 더 많을 것이다. (H1: gate_40 > gate_30)

#가정1 
#등분산성 검정
var.test(sum_gamerounds ~ version, cat)
#	F test to compare two variances

#data:  sum_gamerounds by version
#F = 6.1767, num df = 44699, denom df = 45488, p-value < 2.2e-16
#alternative hypothesis: true ratio of variances is not equal to 1
#95 percent confidence interval:
# 6.063685 6.291747
#sample estimates:
#ratio of variances 
#          6.176659 
          
#독립표본 t검정
t.test(sum_gamerounds ~ version, cat, var.equal = FALSE)

#	Welch Two Sample t-test

#data:  sum_gamerounds by version
#t = 0.88544, df = 58595, p-value = 0.3759
#alternative hypothesis: true difference in means between group gate_30 and group gate_40 is not equal to 0
#95 percent confidence interval:
# -1.404728  3.719705
#sample estimates:
#mean in group gate_30 mean in group gate_40 
#            52.45626              51.29878

t검정을 진행하기 전, 등분산성 검정을 진행하였고, 이에 따라 등분산성 가정을 만족하지 않는 t검정을 진행하였다. 

t검정결과의 p-value 값이 0.3759 로 0.05보다 크기 때문에 귀무가설이 채택되었으며, gate_40이 gate_30보다 유의미하게 높다고 할 수 없다. 

 

 

 

2. retention_1 관련

-gate_30에 해당하는 플레이어보다 gate_40에 해당하는 플레이어의 하루 뒤 다시 접속하는 비율이 더 높을 것이다. (H1: gate_40>gate_30)

#가정2
#시각화 확인
cat %>% 
  group_by(version, retention_1) %>% 
  count() %>% 
  ggplot(aes(x=version, y=n, fill=retention_1)) +
  geom_bar(stat="identity", position = "dodge")+
  geom_text(aes(label=n), size=8)

 

범주형 변수이기 때문에, 이표본 모비율 차이검정을 수행하기 위해 prop.test()를 사용하였다.

+addmargins()로 version별 sum을 나타내는 table을 만들었다. 

#table만들기
addmargins(table(cat$version, cat$retention_1), margin=2)
         
#          FALSE  TRUE   Sum
#  gate_30 24666 20034 44700
#  gate_40 25370 20119 45489
  
#이표본 모비율 차이 검정
prop.test(x=c(20034, 20119), n=c(44700, 45489), alter="less")

#	2-sample test for equality of proportions with continuity correction

#data:  c(20034, 20119) out of c(44700, 45489)
#X-squared = 3.1591, df = 1, p-value = 0.9622
#alternative hypothesis: less
#395 percent confidence interval:
# -1.00000000  0.01137164
#sample estimates:
#   prop 1    prop 2 
#0.4481879 0.4422827

t검정결과의 p-value 값이 0.9622 로 0.05보다 크기 때문에 귀무가설이 채택되었으며, gate_40이 gate_30보다 유의미하게 높다고 할 수 없다. 

 

 

3. retention_7 관련

-gate_30에 해당하는 플레이어보다 gate_40에 해당하는 플레이어의 일주일 뒤 다시 접속하는 비율이 더 높을 것이다. (H1: gate_40>gate_30)

#가정3
#시각화 확인
cat %>% 
  group_by(version, retention_7) %>% 
  count() %>% 
  ggplot(aes(x=version, y=n, fill=retention_7))+
  geom_bar(stat="identity", position = "dodge")+
  geom_text(aes(label=n), size=8)

 

retention_1 관련 가설과 동일한 방식으로 검정을 진행하였다.

#table만들기
addmargins(table(cat$version, cat$retention_7), margin=2)
         
#          FALSE  TRUE   Sum
#  gate_30 36198  8502 44700
#  gate_40 37210  8279 45489
  
#이표본 모비율 차이 검정
prop.test(x=c(8502, 8279), n=c(44700, 45489), alter="less")

#	2-sample test for equality of proportions with continuity correction

#data:  c(8502, 8279) out of c(44700, 45489)
#X-squared = 9.9591, df = 1, p-value = 0.9992
#alternative hypothesis: less
#95 percent confidence interval:
# -1.00000000  0.01248696
#sample estimates:
#   prop 1    prop 2 
#0.1902013 0.1820000

t검정결과의 p-value 값이 0.9992로 0.05보다 크기 때문에 귀무가설이 채택되었으며, gate_40이 gate_30보다 유의미하게 높다고 할 수 없다. 

 

 

 

결론


▶ gate_30 ver.에 비해 gate_40 ver.의 2주동안 평균 게임 플레이 횟수, 1일 뒤 다시 접속하는 비율, 7일 뒤 다시 접속하는 비율 모두 통계적으로 높다고 할 수 없다는 결과를 보였다.


▶ 수정된 gate_40 ver.의 게임이 플레이어의 retention 향상에 유의미한 영향을 미치지 못했음을 의미하며, 이를 통해


-기존의 gate_30버전을 유지

-gate_40버전을 수정하여 활용


하는 2가지 대안을 적용하여 게임을 운용하는 것이 고객 유입을 이끄는 데 효과적일 것이라고 판단된다. 

 

728x90
Comments