欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

A/Btest (A/B测试)的营销策略效果分析

程序员文章站 2024-03-21 23:27:58
...


前言

本文分析以支付宝营销活动为例,通过广告点击率指标比较两组营销策略的广告投放效果。


一、数据介绍

来自阿里天池:数据

用到的是:effect_tb.csv: Click/Non-click dataset.

这个csv文件主要用来记录用户是否对广告进行点击。


二、观察数据

1.引入库

# import libraries
import pandas as pd
import numpy as np

pd.set_option('float_format', lambda x: '%.4f' % x)

2.读入数据

# load data
data = pd.read_csv('effect_tb.csv',header = None)
data.columns = ["试验后天数","用户编号","是否点击","试验组别"]


3.观察数据

data.info()

A/Btest (A/B测试)的营销策略效果分析

# table summary
data.describe()

A/Btest (A/B测试)的营销策略效果分析

# distinct count of columns
data.nunique()

A/Btest (A/B测试)的营销策略效果分析

#把重复用户的用户编号变成一个list去观察
dup_userid=data["用户编号"].value_counts()[data["用户编号"].value_counts()>1].index.tolist()

#查看是否都全部字段都重复的记录
data[data.duplicated()]

A/Btest (A/B测试)的营销策略效果分析
虽然有重复的用户id,但是可能在不用的时间(试验后几天)去做这个测试,也可能被放在不同的组别(实验组别)、有不同的结果(是否点击),我们都去验证一下。

print("有重复用户编号的记录条数:",data[data["用户编号"].isin(dup_userid)].shape[0])

print("用户编号和【在第几天试验】重复的记录条数:",data[data["用户编号"].isin(dup_userid)].duplicated(["用户编号","试验后天数"]).sum())

print("用户编号和【是否点击】重复的记录条数:",data[data["用户编号"].isin(dup_userid)].duplicated(["用户编号","是否点击"]).sum())

print("用户编号和【试验组别】重复的记录条数:",data[data["用户编号"].isin(dup_userid)].duplicated(["用户编号","试验组别"]).sum())

print("用户编号和【试验后天数】、【是否点击】重复的记录条数:",data[data["用户编号"].isin(dup_userid)].duplicated(["用户编号","试验后天数","是否点击"]).sum())

print("用户编号和【试验后天数】、【试验组别】重复的记录条数:",data[data["用户编号"].isin(dup_userid)].duplicated(["用户编号","试验后天数","试验组别"]).sum())


A/Btest (A/B测试)的营销策略效果分析
用户ID和【试验后天数】、【试验组别】重复的记录条数: 0

意味着一个用户在不同天用了不同版本,简而言之,没有一个用户在同一天用一个版本。

可以不删除数据,因为如果按照用户编号去重了,会对整个对比有影响。(之后讨论)

data.pivot_table(index = "试验组别", columns = "是否点击", values = "用户编号",aggfunc = "count",margins = True)
                

A/Btest (A/B测试)的营销策略效果分析


三、计算效果

1.简单比对不同策略点击率

#各组的点击率:
print("对照组点击率:",data[data["试验组别"]==1]["是否点击"].mean())

print("一组试验点击率:",data[data["试验组别"]==2]["是否点击"].mean())

print("二组试验点击率:",data[data["试验组别"]==3]["是否点击"].mean())


A/Btest (A/B测试)的营销策略效果分析
策略一组和策略二组都相对于对照组有提升,看起来策略二组提升得更多。

查看策略一组二组相对于参照组来说提升了多少

print("对照组点击率:",data[data['试验组别']==1]['是否点击'].mean())

print("策略一相对对照组提升:",round((data[data['试验组别']==2]['是否点击'].mean()-data[data['试验组别']==1]['是否点击'].mean())*100,3))

print("策略二相对对照组提升:",round((data[data['试验组别']==3]['是否点击'].mean()-data[data['试验组别']==1]['是否点击'].mean())*100,3))


A/Btest (A/B测试)的营销策略效果分析

策略一提升了0.279%,策略二提升了1.364。

假定我们希望新的营销策略能让广告点击率至少提升1个百分点才算提升。那么这里策略一不算是提升。我们研究策略二组的点击率是否在置信区间内有显著提升。

2.观察样本容量

在进行A/B测试前,需检查样本容量是否满足试验所需最小值。
这里借助Evan Miller的样本量计算工具:

Evan Miller链接

已知对照组点击率为1.26%,假定我们希望新的营销策略能让广告点击率至少提升1个百分点才算提升,显著性水平α取5%,则算得所需最小样本量为:2167。

A/Btest (A/B测试)的营销策略效果分析

data["试验组别"].value_counts()

A/Btest (A/B测试)的营销策略效果分析
两组营销活动的样本量都满足最小样本量需求。

3.计算(以策略二组和对照组为例)

3.1 设定假设

接下来需要进行假设检验,这里先查看一组点击率的提升是否显著。

  1. 零假设和备择假设。记对照组点击率为p0,策略二组点击率为p2,则:
    零假设 H0: p0 ≥ p2 (对照组的点击率大于等于策略一组)
    备择假设 H1: p0 < p2 (对照组的点击率小于策略一组)

  2. 分布类型、检验类型和显著性水平样本服从二点分布,独立双样本,样本大小n>30,总体均值和标准差未知,所以采用Z检验。显著性水平α取0.05。显著性水平α取0.05的单尾检测(左侧)对应的z值 = -1.64。

z值可以用python得出或者查看z-score表:

from scipy.stats import norm
z_alpha = norm.ppf(0.05)
# 若为双侧,则norm.ppf(0.05/2)

结果为z_alpha=-1.6448536269514729,统计上一般取-1.645,拒绝域为{z <z_alpha }

3.2 计算方法

独立双样本,样本大小n>30,总体的均值和标准差未知的Z检验的检验统计量公式如下:
A/Btest (A/B测试)的营销策略效果分析

3.2.1 方法一:公式计算

# 用户数
n_old = len(data[data["试验组别"] == 1])  # 对照组
n_two = len(data[data["试验组别"] == 3])  # 策略二组

# 点击数
c_old = len(data[data["试验组别"] == 1][data["是否点击"] == 1])
c_two = len(data[data["试验组别"] == 3][data["是否点击"] == 1])

# 计算点击率
r_old = c_old / n_old
r_two = c_two / n_two


#点击率标准差
std_old=np.std(data[data["试验组别"] == 1]["是否点击"])
std_two=np.std(data[data["试验组别"] == 3]["是否点击"])

# 总和点击率
r = (c_old + c_two) / (n_old + n_two)

print("转化率的联合率::", r)

'''
结果:
转化率的联合率: 0.014429896833357214
'''

按照公式计算:

z_two = (r_old - r_two) / np.sqrt(r * (1 - r)*(1/n_old + 1/n_two))
print("检验统计量z:", z_two)

'''
结果:
检验统计量z: -59.66600946268368
'''

z_one = -59.66600946268368 < -1.64,符合拒绝域为{z<z_alpha}。

所以我们可以得出结论:原假设(对照组的点击率大于策略一组)不成立,策略二点击率的提升在统计上是显著的。

3.2.2 方法二:Python函数计算

直接用python statsmodels包计算z值和p值。

proportions_ztest官方链接

难点:

alternativestr The alternative hypothesis, H1, has to be one of the
following

  • ‘two-sided’: H1: difference in means not equal to value (default)
  • ‘larger’ : H1: difference in means larger than value
  • ‘smaller’ : H1: difference in means smaller than value
import statsmodels.stats.proportion as sp

z_two_score, p = sp.proportions_ztest([ c_two,c_old],[ n_two,n_old], alternative = "la")
print("检验统计量z_two:",z_two_score,",p值:", p)

#alternative 默认 ='two-sided'
#alternative='smaller'代表左尾
#用p值判断与用检验统计量z判断是等效的

'''
结果:
检验统计量z_two: -59.66600946268368 ,p值: 0.0
'''

p值约等于0,p < α,与方法一结论相同,拒绝原假设。

4.扩展

4.1 扩展一:策略一组和对照组对比

策略二组点击率的提升是否显著。

p1为策略一组,p0为对照组

  • 零假设 H0: p1 < p0 (策略二组相比于对照组无提升)
  • 备择假设 H1: p1 ≥ p0 (策略二组相比于对照组有提升)

# 用户数
n_old = len(data[data["试验组别"] == 1])  # 对照组
n_one = len(data[data["试验组别"] == 2])  # 一组

# 点击数
c_old = len(data[data["试验组别"] == 1][data["是否点击"] == 1])
c_one = len(data[data["试验组别"] == 2][data["是否点击"] == 1])

# 计算点击率
r_old = c_old / n_old
r_one = c_one / n_one


# 总和点击率
r = (c_old + c_one) / (n_old + n_one)

print("转化率的联合率:", r)

z_one_score, p = sp.proportions_ztest([c_old, c_one],[n_old, n_one], alternative = "smaller")
print("检验统计量z_one:",z_one_score,",p值:", p)


'''
结果:
转化率的联合率:0.01298700183320143
检验统计量z_one: -14.362726203811503 ,p值: 4.433468512724253e-47

(P值约等于0)
'''


z_one < -1.64,,p < 0.05,拒绝原假设,即策略一组相比于对照组有提升。

4.2 扩展二:策略二组和策略一组对比

那么策略一和策略二相比呢?
p1为策略一组,p2为策略二组

因为从之前的结果看起来策略二组比策略一组提升更多,那么我们先假设是这样。
A/Btest (A/B测试)的营销策略效果分析

  • 零假设 H0: p2 <≥ p1 (策略二组相比于策略一组有提升)
  • 备择假设 H1: p2 ≥ p1 (策略二组相比于策略一组无提升)

看一下样本容量,算出这两组对比所需最小样本量为:2580。

这两组样本的容量符合要求。
A/Btest (A/B测试)的营销策略效果分析

z_one_two_score, p = sp.proportions_ztest([ c_two,c_one],[ n_two,n_one], alternative = "smaller")
print("检验统计量z:",round(z_one_two_score,4),",p值:", round(p,4))

'''
结果:
检验统计量z: 32.818 ,p值: 1.0
'''

p值约等于1,p > α(0.05),符合原假设,即策略二组相比于策略一组有提升。


总结

  • 策略一和策略二都相对于对照组对广告点击率有显著提升效果。
  • 策略二相对于策略一对广告点击率有显著提升效果。