版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Cocaine_bai/article/details/80524755
《数据分析实战》—用R做A/B测试
本文参考的是《数据分析实战》的第五章。
背景:在某公司中,对与某些产品做促销活动,但是其中有个产品相对于其他产品来说购买率低下,希望通过数据分析找出购买率偏低的原因。
现状:和其他产品相比购买率偏低。
预期:希望能够提升到其他应用相同的购买率
明确问题:经过一系列的沟通,很有可能是由于该应用展示的问题而导致的(不同应用对应不同UI)
不同产品的购买率如下:
应用名称 | 购买率 |
---|---|
app_name1 | 6% |
应用A | 12% |
应用B | 12% |
对app_name1而言做A/B测试,之后通过数据来判断A/B组的测试是否存在差异(使用统计学的“假设检验”来判断)。
我们需要通过假设检验来过滤出显著性差异,
先通过假设检验找出有统计意义的差异,再探讨这个差异在商业活动中是否有意义。
读取数据
- ab_test_imp:关于广告展示次数的数据
具体数据如下:
数据内容 | 数据类型 | R 语言中的标识 |
---|---|---|
广告展示日期 | string(字符串) | log_date |
测试名 | string(字符串) | test_name |
测试用例(A 或B) | string(字符串) | test_case |
用户ID | int(数值) | user_id |
事务ID | int(数值) | transaction_id |
> ab_test_imp <- read.csv('section5-ab_test_imp.csv',header = T,stringsAsFactors = F)
> head(ab_test_imp)
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
3 2013-10-01 game-01 sales_test B 32087 25624
4 2013-10-01 game-01 sales_test B 10160 25625
5 2013-10-01 game-01 sales_test B 46113 25626
6 2013-10-01 game-01 sales_test A 6605 25627
2.ab_test_goal:关于广告点击次数的信息
具体数据如下:
数据内容 | 数据类型 | R 语言中的标识 |
---|---|---|
广告点击日期 | string(字符串) | log_date |
测试名 | string(字符串) | test_name |
测试用例(A 或B) | string(字符串) | test_case |
用户ID | int(数值) | user_id |
事务ID | int(数值) | transaction_id |
> ab_test_goal <- read.csv('section5-ab_test_goal.csv', header = T,stringsAsFactors = F)
> head(ab_test_goal)
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
3 2013-10-01 game-01 sales_test B 8276 25739
4 2013-10-01 game-01 sales_test B 1230 25742
5 2013-10-01 game-01 sales_test B 17471 25743
6 2013-10-01 game-01 sales_test B 48728 25746
其中:事务ID为广告展示时生成的ID号,可以作为key来合并广告展示数据和点击数据。
数据处理
1.将上面的ab_test_imp数据和ab_test_goal数据合并在一起:
> ab_test_all <- merge(ab_test_imp,ab_test_goal,by = 'transaction_id',all.x = T,all.y = T)
> head(ab_test_all)
transaction_id log_date.x app_name.x test_name.x test_case.x user_id.x log_date.y app_name.y test_name.y test_case.y user_id.y
1 1 2013-10-02 game-01 sales_test A 49017 <NA> <NA> <NA> <NA> NA
2 2 2013-10-02 game-01 sales_test B 49018 <NA> <NA> <NA> <NA> NA
3 3 2013-10-02 game-01 sales_test A 44338 <NA> <NA> <NA> <NA> NA
4 4 2013-10-02 game-01 sales_test A 44339 <NA> <NA> <NA> <NA> NA
5 5 2013-10-02 game-01 sales_test A 28598 <NA> <NA> <NA> <NA> NA
6 6 2013-10-02 game-01 sales_test B 30306 <NA> <NA> <NA> <NA> NA
2.对上面的数据增加是否点击一列:
对后者的user_id进行判断,若为空则未点击,计为0;若不为NA则点击,计为1:
> ab_test_all$is_goal <- ifelse(is.na(ab_test_all$user_id.y),0,1)
> head(ab_test_all)
transaction_id log_date.x app_name.x test_name.x test_case.x user_id.x log_date.y app_name.y test_name.y test_case.y user_id.y is_goal
1 1 2013-10-02 game-01 sales_test A 49017 <NA> <NA> <NA> <NA> NA 0
2 2 2013-10-02 game-01 sales_test B 49018 <NA> <NA> <NA> <NA> NA 0
3 3 2013-10-02 game-01 sales_test A 44338 <NA> <NA> <NA> <NA> NA 0
4 4 2013-10-02 game-01 sales_test A 44339 <NA> <NA> <NA> <NA> NA 0
5 5 2013-10-02 game-01 sales_test A 28598 <NA> <NA> <NA> <NA> NA 0
6 6 2013-10-02 game-01 sales_test B 30306 <NA> <NA> <NA> <NA> NA 0
数据分析
3.计算点击率:
library(plyr)
ddply(ab_test_all,
.(test_case.x),
summarise,
cvr = sum(is_goal)/length(is_goal))
输出结果:
test_case.x cvr
1 A 0.08025559
2 B 0.11546015
很明显:
广告A的点击率为8%;广告B的点击率为11.5%
4.进行卡方检验:
> chisq.test(ab_test_all$test_case.x,ab_test_all$is_goal)
Pearson's Chi-squared test with Yates' continuity correction
data: ab_test_all$test_case.x and ab_test_all$is_goal
X-squared = 308.38, df = 1, p-value < 2.2e-16
可以看到,p值小于0.05,存在显著性差异,同时很接近与0,说明差异性很大。
5.计算每个测试的点击率:
#计算每天每个测试用例的点击率
> ab_test_all_summary <- ddply(ab_test_all,
+ .(log_date.x,test_case.x),
+ summarise,
+ imp=length(user_id.x),
+ cv=sum(is_goal),
+ cvr=sum(is_goal)/length(user_id.x))
> head(ab_test_all_summary)
log_date.x test_case.x 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
将整体的点击率添加到上面的数据中:
(将summaries替换成transform)
> ab_test_all_summary <- ddply(ab_test_all_summary,
+ .(test_case.x),
+ transform,
+ cvr.avg=sum(cv)/sum(imp))
> head(ab_test_all_summary)
log_date.x test_case.x 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
数据可视化
使用ggplot2画出时序图:
> library(ggplot2)
> library(scales)
> ggplot(ab_test_all_summary,aes(x=log_date.x,y=cvr,col=test_case.x,
+ lty=test_case.x,shape=test_case.x))+
+ geom_line(lwd=1)+
+ geom_point(size=4)+
+ geom_line(aes(y=cvr.avg,col=test_case.x))+
+ scale_y_continuous(labels = percent,limits = limits)
生成如下图:
所以,结论就是广告B比广告A更加被用户点击,需要投放B广告~
至此数据分析结束~