上期回顾:懂得假设检验就可以了吗?实际遇到的需要ABTest的业务和练习时的ABTest项目区别有多大?
本期博客提出疑问:
电商平台的业务场景是怎么的? 中小店铺面临着什么样的问题,其对平台的价值又如何? 如何解决中小店铺流量扶持问题? 怎么利用ABTest方法来寻求电商流量分配的最优解?
1 电商平台的业务场景
上图是电商平台上的业务大致流程。
那么问题来了,电商平台是如何在上述流程中赚取利益的呢?
- 广告费用。如在首页提供广告位出租。
- 分期服务。在付款时提供分期服务,得到部分抽成。
- 商城扣点。如果是在自由商城的认证商家,这个商城是通过平台认证担保的,那么只要有人购买支付,就会有一定的商城扣点。
- 用户消费款项。在确认收货前会产生一定利息。(不多,但积少成多)
- 类似余额宝。用户把钱闲置在平台。
- 商家开店:店铺保证金。退店前都会放在电商平台上,不会产生利息。可以用于投资等。
- 商家贷款。如商家开店资金不足,平台提供商家贷款。
- 平台技术服务费用。
- 增值服务。如数据服务等。
- 直播费用。如果是平台牵头则收取坑位费,平台合作则收取服务费。
2 拆解中小店铺流量扶持问题
2.1 中小店铺面临的流量问题
-
用户在搜索页面更倾向于选择高等级店铺 搜索购买有一个特点:当用户搜索一件商品时,他很容易去对比搜索结果,根据多种情况选择最合适他的。这时,“高等级店铺”、“多付款人数”、“低价格”、“高评价”等等容易成为用户选择的因素。 所以就会有大量流量进入大店铺。(马太效应:大店铺流量越来越多,中小店铺越来越少) -
流量较大的广告位,费用较高 而例如首页这样引流量十分大的页面,其广告费比较贵,中小店铺不太能负担得起这部分开销。所以购买这部分广告位的都是大店铺。
综合以上两个,就形成了大店铺流量越来越多,中小店铺流量越来越少的局面。
2.2 中小店铺对于平台的价值
先来看大店铺:
- 更有优势的价格。在进货来源相同时,大店铺往往更有话语权,能拿到更低的价格。
- 一般来说会有更好的商品质量。进货来源相同时则没有啥区别。
- 能提供更好的服务。能有更多的人力预算,能够与更优质的物流公司合作。
- 大店铺能够有更多的仓储预算,能够售卖更多品类的商品。不过现在这种店铺越来越少。
但需要注意的是,国内常见的电商平台,其丰富的商品都是依靠丰富的垂类店铺实现的,很少有某个大店铺包揽许多类的产品。这种情况也是适合电商平台发展的。
所以,从丰富的商品这个角度来看,中小店铺能够提供个性化商品,如订制品、代购品、农副商品。
从便宜的价格这个角度来看,虽说大店铺能提供更便宜的价格,但小店铺能够做到差异化竞争,即提供质量稍差但价格低很多的商品,如服装类。
从质量保证这个角度来看,如果中小店铺选择正规的进货渠道的话,跟大店铺区别是不大的。
从物流服务这个角度来看,现在基本是选择第三方物流服务。
再来看,如长尾理论(2%的热门商品提供33%的利润,8%的中热门商品提供33%的利润,剩下的33%的利润都是由90%的商品提供)所讲,长尾商品(无限多的中小店铺提供的)能够带来高用户粘性和高消费用户,使得电商平台能够持续获益。
3 设计解决中小店铺流量扶持问题的流程
从2.1和2.2可以知道,我们需要扶持中小店铺,将一些流量向中小商家倾斜。
3.1 业务思路
用户进入商品详情页基本就是来源这4方面,那个所以基于此提出这4个方案。
现在一一来讨论下可行性。
-
增加搜索曝光 1.确实能够给中小店铺带来极大的流量; 2.但是搜索过程是一个用户的主动行为的过程,如果我们过多地干预用户的主动行为,容易引起用户的反感; 3.即使我们干预结果,也可能无法有效地提高中小店铺的商品详情页的点击情况(即使我们给你很多选择,但你不一定点进去,还是会选择你想要的) -
降低中小店铺广告位收费 1.增加中小店铺的广告投放次数; 2.一些竞价类广告,可能不是很有效(就算是中小店铺,也是有些有钱有些很缺钱); 3.高风险行为,需要修改广告规则;影响范围大,成本也会很高。 -
增加中小店铺推荐位 1.整个电商APP有特别特别多的推荐位,所以增加推荐位是一个经济有效的方式; 2.推荐位可以为用户提供精准推荐结果,同时通过减少对比机会,提高商品详情页的点击可能性; 3.可能会影响大店铺的流量。 -
增加中小店铺直播推荐 1.中小店铺人力比较少; 2.直播的规则比较复杂,中小店铺难以与热门主播抗衡。很可能费力不讨好。
综合上述,增加中小店铺推荐位可能是这4种方式中最理想的。
3.2 解决问题流程
明确问题:提高中小店铺流量,从而提高中小店铺的承担量,而不是仅仅提高流量。
所以,找到更多具有消费承担能力的用户,推荐给这些用户,就更有可能直接或间接地提高中小店铺的承担量。
所以我们的方案就是下单成功的推荐页提供更多中小店铺推荐。 以上就是整个问题的解决流程图。
4 利用ABTest寻求电商流量分配的最优解
从这一部分开始,我利用了从培训课堂拿到的数据进行演练。
实验方案:在下单推荐页设置固定中小店铺展示位置,通过对比3个固定展示位、6个、9个的区别,探究最优展示位个数。
4.1 选择实验主要指标
4.1.1 二类指标的确定
目标:提升中小店铺在下单推荐页的下单量30%。
由于总量无法作为假设检验统计量,通过总下单量 = 人数 * 人均下单量,将统计量指标定为人均中小店 铺下单量。此时就能确定二类指标:
二类指标:C类店铺人均下单量上升30%。
4.1.2 一类指标的确定
在下单推荐页将一部分流量固定分配给中小店铺,那大店铺的流量肯定会受到损失。从经验角度来看,近一月的大店铺的流量仅有3%来源与下单推荐页,贡献成单量仅占2%。所以即使页面完全展示中小店铺结果,大店铺的整体流量影响能控制在3%内,大店铺的成单影响能控制在2%内。
一类指标:A类店铺人均下单量下降在两个标准差(15%)以内。
4.2 设计原假设与备择假设
一类指标: H1 : 对照组人均下单量 - 实验组人均下单量 < 2* 实验前人均下单量标准差。 H0 : 对照组人均下单量 - 实验组人均下单量 >= 2* 实验前人均下单量标准差。
二类指标 : H1: 实验组人均下单量 - 对照组人均下单量 > 30%对照组人均下单量。 H0: 实验组人均下单量 - 对照组人均下单量 <= 30%对照组人均下单量。
4.3 计算分组样本量
选择两个总体均值之差计算公式 ,从假设上看一类二类指标都为单侧检验,但由于我们现在还没有做抽样,所以我们不知道实验组的
σ
2
\sigma^2
σ2,我们在这里假定AB组
σ
2
\sigma^2
σ2相等,所以我们选择双侧。
python实现代码如下:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt from scipy import stats
import pymysql
import warnings
warnings.filterwarnings('ignore')
plt.rcParams['font.family']='SimHei'
plt.rcParams['axes.unicode_minus']= False
con=pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='123456',db='ABTest',use_unicode=True, charset="utf8")
data=pd.read_sql("select * from ABTest",con=con)
data.head()
n
A
=
k
n
B
??
a
n
d
??
n
B
=
(
1
+
1
k
)
(
σ
z
1
?
α
/
2
+
z
1
?
β
μ
A
?
μ
B
)
2
n_A=kn_B \; and \; n_B=(1+\frac{1}{k})(\sigma \frac{z_{1-\alpha/2}+z_{1-\beta}}{\mu_A-\mu_B})^2
nA?=knB?andnB?=(1+k1?)(σμA??μB?z1?α/2?+z1?β??)2
alpha = 0.05
beta = 0.2
k =1
求
z
1
?
α
/
2
z_{1-\alpha/2}
z1?α/2?和
z
1
?
β
z_{1-\beta}
z1?β?。
z_alpha = stats.norm.ppf(1-alpha/2)
z_beta = stats.norm.ppf(1-beta)
print(z_alpha,z_beta)
1.959963984540054 0.8416212335729143
求
σ
\sigma
σ。
df_C = data.loc[(data.组=='D') & (data.店铺类型=="C"),["riqi","下单量"]]
sigma = df_C["下单量"].std()
sigma
0.4560376923365469
求二类目标提升值 :
μ
A
?
μ
B
\mu_A-\mu_B
μA??μB?。
mean = df_C.groupby("riqi")["下单量"].mean().mean()*0.3 mean
0.031065555555555555
yangbenliang = (1+1/k)*np.power(sigema*(z_alpha+z_beta)/mean,2)
yangbenliang
3382.835657318574
求
σ
\sigma
σ。
df_A = data.loc[(data.组=='D') & (data.店铺类型=="A"),["riqi","下单量"]]
sigma= df_A["下单量"].std()
sigma
1.90306885529098
求一类目标提升值 :
μ
A
?
μ
B
\mu_A-\mu_B
μA??μB?。
mean = df_A.groupby("riqi")["下单量"].mean().std()*2
mean
0.19578164968724276
yangbenliang = (1+1/k)*np.power(sigema*(z_alpha+z_beta)/mean,2)
yangbenliang
1483.2102112443183
当然,也可以利用工具求解,省事。
4.4 检验策略选择
由于我们明确了一类指标的下降阈值和二类指标的上升目标,所以都使用单侧检验。
4.5 设计分组策略
A组:下单推荐页前12个推荐,9个C类店铺商品 B组:下单推荐页前12个推荐,6个C类店铺商品 C组:下单推荐页前12个推荐,3个C类店铺商品 D组:不干预(对照组)
4.6 实验结论分析
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import pymysql
import warnings
warnings.filterwarnings('ignore')
plt.rcParams['font.family']='SimHei'
plt.rcParams['axes.unicode_minus']= False
con=pymysql.connect(host='127.0.0.1',port=8888,user='root',passwd='123456',db='ABTest',use_unicode=True, charset="utf8")
data=pd.read_sql("select * from ABTest",con=con)
data.head()
一类指标假设检验
df = data.loc[(data.riqi=='2020-05-14') & (data.店铺类型=="A"),["组","下单量"]]
df.head()
df.groupby("组")["下单量"].count()
df = df[df.组 != "C"]
df.组.unique()
df.groupby(["组"])["下单量"].mean()
df_std = data.loc[data.店铺类型=="A",["组","riqi","下单量"]]
std = df_std[df_std.组=="D"].groupby("riqi")["下单量"].mean().std()
std
muzhicha =std *2
muzhicha
求AD组
alpha =0.05
计算统计量
x
ˉ
D
?
x
ˉ
A
\bar x_D - \bar x_A
xˉD??xˉA?
dif_AD = df.下单量[df.组=="D"].mean() - df.下单量[df.组=="A"].mean()
dif_AD
求
s
A
2
n
A
+
s
D
2
n
D
\frac{s_A ^2}{n_A} + \frac{s_D ^2}{n_D}
nA?sA2??+nD?sD2??
varsum_AD = df.下单量[df.组=="A"].var()/df.下单量[df.组=="A"].count() + df.下单量[df.组=="D"].var()/df.下单量[df.组=="D"].count()
varsum_AD
x
ˉ
D
?
x
ˉ
A
\bar x_D - \bar x_A
xˉD??xˉA? ~ N(0.195, varsum_AD)
计算dif_AD 在相应的分布的概率p:
p_A = stats.norm.cdf(dif_AD,loc=muzhicha,scale=np.sqrt(varsum_AD))
p_A
求BD组
dif_BD = df.下单量[df.组=="D"].mean() - df.下单量[df.组=="B"].mean()
varsum_BD = df.下单量[df.组=="D"].var()/df.下单量[df.组=="D"].count() + df.下单量[df.组=="B"].var()/df.下单量[df.组=="B"].count()
p_B = stats.norm.cdf(dif_BD,loc=muzhicha,scale=np.sqrt(varsum_BD))
p_B
if (p_A < alpha) & ( p_B < alpha):
if dif_A <dif_B:
print("A策略对A类店铺影响小")
else:
print("B策略对A类店铺影响小")
elif p_A < alpha:
print("A策略对A类店铺影响小与阈值" + str(muzhicha))
elif p_B < alpha:
print("B策略对A类店铺影响小与阈值" + str(muzhicha))
else:
print("A.B策略对A类店铺影响超过阈值" + str(muzhicha))
二类指标假设检验
df_C = data.loc[(data.riqi=='2020-05-14') & (data.店铺类型=="C"),["组","下单量"]]
df_C.head()
df_C.groupby(["组"])["下单量"].count()
df_C = df_C[df_C.组 != "C"]
df_C.groupby(["组"])["下单量"].mean()
计算提升值
μ
A
?
μ
B
\mu_A - \mu_B
μA??μB?
tisheng = data[(data.组=='D') & (data.店铺类型=="C")].groupby("riqi")["下单量"].mean().mean()*0.3
tisheng
ABTest封装函数
def abtest(df: pd.DataFrame, alpha=0.05, group_col: str = None, value_col: str = None):
'''
:param df: 被分析DateFrame对象
:param alpha: 临界值
:param group_col: 组列的名字,默认为df的第一列
:param value_col: 值列的名字,默认为df的第2列
:return:best_group_name,pdf
best_group_name:最优组
pdf:最优组与其他组的差异性
'''
if not group_col:
group_col = df.columns[0]
if not value_col:
value_col = df.columns[1]
best_group_name = df.groupby(group_col)[value_col].mean().sort_values(ascending=False).index.tolist()[0]
best_group_values = df[df[group_col] == best_group_name][value_col]
group_names = list(set(df[group_col].unique().tolist()) - set(best_group_name))
pdf = pd.DataFrame(columns=[group_col,'mean', 'pvalue', 'ptype'])
for group_name in group_names:
group_values = df[df[group_col] == group_name][value_col]
dif = best_group_values.mean() - group_values.mean()
var = best_group_values.var()/best_group_values.count() + group_values.var()/group_values.count()
pvalue =1-stats.norm.cdf(dif,loc=tisheng,scale=np.sqrt(var))
if pvalue >= alpha:
ptype = "无显著差异"
else:
ptype = "有显著差异"
pdf.loc[pdf.shape[0]] = {group_col: group_name,'mean':group_values.mean(), 'pvalue': pvalue, 'ptype': ptype}
return best_group_name,best_group_values.mean(), pdf
df_C
abtest(df_C)
4.7 实验结论与后续决策
一类指标评估:B策略的一类指标下降幅度在两个标准差内,符合要求;
二类指标评估:B策略的二类指标最优,同时上升幅度显著大于30%,符合要求;
决策:考虑推全B策略。
为了避免我们的取的那天数据是一个异常值,可以多用几天的数据来做检验。
5 总结与拓展
5.1 如何做一个好的ABTest?
- 确定对照组和实验组,最好是做单变量的实验,一次只改变一个变量。
- 分流时尽量排除混杂因素,一般情况下采用随机分流即可。如果随机分流无法保证样本分布于总体分布一致。建议采用手动的分层随机分流。(对比样本与总体的用户的属性分布最常用的属性:地域)
- 检查流量是否达到最小样本量要求,达不到要求则没法进行后续的分析,实验结果不可信。
- 准确收集用户行为数据,这就要求埋点必须正确。
5.2 ABTest的局限
-
细小改变与重大改变的博弈 因为ABTest其实遵循着控制变量法,一次只变化一个自变量。细小改变很可能让你找到“最优解”,但是这“最优解”有可能只是局部最优解,而重大改变有可能让你发现所谓的全局最优解,但也可能让你连局部最优解都找不到。如下图所示,细小改变可能让你找到了B,但很难找到C,而重大改变呢,有可能让你找到C,但有可能得到更差的结果,让企业承担着更大的风险。 -
数据驱动与业务灵感的平衡 正如我在上一篇博客中所讲的:数据分析师主要就是跟数据打交道,但是一个只懂数据的数据分析师不是好的数据分析师,同样的要掌握好业务知识,懂得与产品人员沟通。 掌握数据技能之外,同样也要有良好的业务能力。
一直在学习路上!
了解更多内容,可以关注我的数据分析专栏。
CSDN@报告,今天也有好好学习
|