5장 - A/B 테스트 : 어느 쪽의 배너광고가 반응이 더 좋은가?
Python, R 분석과 프로그래밍/비지니스 활용 사례로 배우는 데이터 분석 : R 2017. 2. 13. 19:51문제인식: 자사 제품의 구매율이 다른 앱과 비교하여 낮음을 확인, 해당 배너 광고의 클릭율이 낮음을 밝힘.
해결 방법: 분석 위한 데이터가 없기 때문에 A/B 테스트를 통해 분석용 로그를 출력하는 데이터 수집. 이후 A/B 테스트 한 후 배너광고 A와 B의 클릭률 산출하여 x2 검정 실행
R 분석 내용
1. 데이터 읽어 들이기
> setwd("C:/파일/temp/r_temp")
> ab.test.imp <-read.csv('section5-ab_test_imp.csv',header=T,stringsAsFactors = F)
> head(ab.test.imp,2)
log_date app_name test_name test_case user_id transaction_id
1 2013-10-01 game-01 sales_test B 36703 25622
2 2013-10-01 game-01 sales_test A 44339 25623
> ab.test.goal <- read.csv('section5-ab_test_goal.csv',header=T,stringsAsFactors = F)
> head(ab.test.goal,2)
log_date app_name test_name test_case user_id transaction_id
1 2013-10-01 game-01 sales_test B 15021 25638
2 2013-10-01 game-01 sales_test B 351 25704
2. ab.test.imp에 ab.test.goal 결합시키기
> ab.test.imp <- merge(ab.test.imp, ab.test.goal, by='transaction_id', all.x=T, suffixes=c('','.g'))
> head(ab.test.imp,2)
-> all.x - logical; if TRUE, then extra rows will be added to the output, one for each row in x that has no matching row in y. These rows will have NAs in those columns that are usually filled with values from y. The default is FALSE, so that only rows with data from both x and y are included in the output.
3. 클릭했는지 하지 않았는지 나타내는 플래그 작성하기
> ab.test.imp$is.goal <-ifelse(is.na(ab.test.imp$user_id.g),0,1)
-> 항목 user_id.g의 값이 없음(NA)인 경우 0, 그렇지 않을 경우 1 입력
4. 클릭률 집계하기
> library(plyr)
> ddply(ab.test.imp,
.(test_case),
summarize,
cvr=sum(is.goal)/length(user_id))
test_case cvr
1 A 0.08025559
2 B 0.11546015
-> cvr = 클릭한 사람의 합계 / 배너광고가 표시된 유저수
배너광고 A의 클릭률 보다 B가 전반적으로 높다는 것을 통계적으로 알 수 있다.
5. 카이제곱 검정
> chisq.test(ab.test.imp$test_case,ab.test.imp$is.goal)
Pearson's Chi-squared test with Yates' continuity correction
data: ab.test.imp$test_case and ab.test.imp$is.goal
X-squared = 308.38, df = 1, p-value < 2.2e-16
-> p-value가 매주 작으므로 (0.05보다 작음) A와 B의 차이는 우연히 발생한 것이 아님
6. 날짜별,테스트 케이스별로 클릭률 산출하기
> ab.test.imp.summary<- ddply(ab.test.imp,
.(log_date,test_case),
summarize,
imp=length(user_id),
cv=sum(is.goal),
cvr=sum(is.goal)/length(user_id))
> head(ab.test.imp.summary)
log_date test_case imp cv cvr
1 2013-10-01 A 1358 98 0.07216495
2 2013-10-01 B 1391 176 0.12652768
3 2013-10-02 A 1370 88 0.06423358
4 2013-10-02 B 1333 212 0.15903976
5 2013-10-03 A 1213 170 0.14014839
6 2013-10-03 B 1233 185 0.15004055
-> imp = 배너 광고가 얼마나 표시되었는지 확인
cv = 클릭한 사람의 합계
cvr = 클릭률
7. 테스트 케이스별로 클릭률 산출하기
> ab.test.imp.summary<- ddply(ab.test.imp.summary,
.(test_case),
transform,
cvr.avg=sum(cv/sum(imp)))
> head(ab.test.imp.summary)
log_date test_case imp cv cvr cvr.avg
1 2013-10-01 A 1358 98 0.07216495 0.08025559
2 2013-10-02 A 1370 88 0.06423358 0.08025559
3 2013-10-03 A 1213 170 0.14014839 0.08025559
4 2013-10-04 A 1521 89 0.05851414 0.08025559
5 2013-10-05 A 1587 56 0.03528670 0.08025559
6 2013-10-06 A 1219 120 0.09844135 0.08025559
-> transform: 기존 집계툴에 데이터 추가
cvr.avg: test_case 별 추가
8. 테스트 케이스별 클릭률의 시계열 추이 그래프
> str(ab.test.imp.summary)
'data.frame': 62 obs. of 6 variables:
$ log_date : chr "2013-10-01" "2013-10-02" "2013-10-03" "2013-10-04" ...
$ test_case: chr "A" "A" "A" "A" ...
$ imp : int 1358 1370 1213 1521 1587 1219 1595 1401 1648 1364 ...
$ cv : num 98 88 170 89 56 120 194 99 199 114 ...
$ cvr : num 0.0722 0.0642 0.1401 0.0585 0.0353 ...
$ cvr.avg : num 0.0803 0.0803 0.0803 0.0803 0.0803 ...
> ab.test.imp.summary$log_date <- as.Date(ab.test.imp.summary$log_date)
> library(ggplot2)
> library(scales)
> limits<-c(0,max(ab.test.imp.summary$cvr))
> ggplot(ab.test.imp.summary,aes(x=log_date,y=cvr,
col=test_case,lty=test_case,shape=test_case))+
geom_line(lwd=1)+geom_point(size=4)+geom_line(aes(y=cvr.avg,col=test_case))+
scale_y_continuous(label=percent,limits=limits)
-> 배너광고 A의 클릭률 보다 B가 전반적으로 높다는 것을 통계적으로 알 수 있다
##ggplot 그래프 이해하기
> library(ggplot2)
> library(scales)
> ggplot(ab.test.imp.summary,aes(x=log_date,y=cvr,col=test_case,lty=test_case,shape=test_case))
> ggplot(ab.test.imp.summary,aes(x=log_date,y=cvr,col=test_case,lty=test_case,shape=test_case))+geom_line(lwd=1)
> ggplot(ab.test.imp.summary,aes(x=log_date,y=cvr,col=test_case,lty=test_case,shape=test_case))+geom_line(lwd=1)+geom_point(size=4)
> ggplot(ab.test.imp.summary,aes(x=log_date,y=cvr,col=test_case,lty=test_case,shape=test_case))+geom_line(lwd=1)+geom_point(size=4)+geom_line(aes(y=cvr.avg,col=test_case))
> limits<-c(0,max(ab.test.imp.summary$cvr))
> max(ab.test.imp.summary$cvr)
[1] 0.1712159
> ggplot(ab.test.imp.summary,aes(x=log_date,y=cvr,col=test_case,lty=test_case,shape=test_case))+geom_line(lwd=1)+geom_point(size=4)+geom_line(aes(y=cvr.avg,col=test_case))+ scale_y_continuous(label=percent,limits=limits)
출처: 비지니스 활용 사레로 배우는 데이터 분석: R (사카마키 류지, 사토 요헤이 지음)
'Python, R 분석과 프로그래밍 > 비지니스 활용 사례로 배우는 데이터 분석 : R' 카테고리의 다른 글
6장 - 중회귀분석 : 집객효과가 가장 큰 광고의 조합은 무엇인가? (2) | 2017.02.15 |
---|---|
4장 - 크로스 분석: 어떤 속성들의 고객들이 떠날까? (0) | 2017.02.10 |