31 | 统计意义(下):如何通过显著性检验,判断你的A/B测试结果是不是巧合?
31 | 统计意义(下):如何通过显著性检验,判断你的A/B测试结果是不是巧合?
讲述:黄申
时长11:30大小10.55M
方差分析
使用 Python 代码进行验证
总结
思考题
赞 3
提建议
精选留言(13)
- 强哥2019-03-01我们这面的ab test计算显著性用的是t检验,不知道跟f检验的区别是什么?对于非参数检验的方法可以用bootstraping吧!分析师对这方面比较有研究
作者回复: t检验可以用pairwise的t检验,一般用于两组对比,而f检验可以进行多组(多个水平)的检验
7 - 罗耀龙@坐忘2020-04-23茶艺师学编程 老师,我是这么理解方差分析的: 对于要考察的数据(符合正态分布),要想得出差异具有显著性,那么SSM/分布自由度要比SSE/误差自由度大上不少才行(分子比分母大不少)。 有意义的数据要比噪音要多,不然事情就是随机漫步或者是偶然(没有为什么)发生的。 不知道我这样子理解有没有问题?展开
作者回复: 对,就是这个意思
共 3 条评论5 - 动摇的小指南针2019-05-26方差检验的前提是符合正态分布,那么针对用户转化率算法a和b而言,怎么理解这种分布呢,是指在某种用户特征分类的x坐标上,转化效果y坐标符合正态分布吗?
作者回复: 是的,可以进行采样数据可视化来初版判断
3 - 叮当猫2019-04-15请问F检验临界值表是怎么计算出来的?
作者回复: 这个问题比较复杂,简单的来说,基于一些假设我们可以画出在不同的自由度之下,不同的F值曲线。和正态分布类似,根据这个曲线,我们可以确定某个α的值,让F曲线在α值右侧的面积小于0.05或者0.01等等。
2 - mickey2019-02-26请问,显著性水平α为什么要取0.05?
作者回复: 这是个好问题,0.05是业界的常见标准,约定俗成。也不一定要取0.05,0.1或者是0.02,0.01,只要不是太大都可以。至于多“大”算“大”,看你愿意接受偶然性的程度,没有明显的界定,当然0.3,0.5这种就肯定太大了。
2 - mickey2019-02-26算法a所导致的平均转化率要比算法b的相对高出约2% 是怎么计算出来的?
作者回复: (a均值-b均值) / (b均值),是相对百分比
2 - yaya2019-02-25笔记:两组样本的差异可能是由 1.采样造成的差异 2.数据分布不同造成的差异 如果要判断更多的是由哪种差异造成的,可以计算他们的比值。 采样的差异计算 各个数据到每个分布中心的距离和比如对第j水平来说,就是数据到j水平的距离,所有采样的差异就是所有水平的差异之和 分布造成的差异计算,就是各水平均值到所有均值的差异和 这两个差异我能理解,但是他们对应的量纲应该是不同的,就是他们不是同一基准下的差异但是为什么引入自由度就可以了呢?采样差异的自由度计算为什么要保证各水平均值不变,我没能理解展开
作者回复: 量纲在物理学里用得比较多,我的理解是它代表了不同的含义,比如这里代表转化率的单位。假设转化率的定义是#click/#pageview,那么这里的两个水平的量纲都是这种次数的比例,量纲应该是相同的。 对于自由度的计算,如果平均值发生了变化,那么方差就要重新计算了。
2 - 建强2020-07-26简单写了一个Python程序,实现了SST、SSM、SSE、F值的计算,P值就不知道怎么算了,程序代码如下: # 方差分析 import pandas as pd import numpy as np class VarianceAnaly: def __init__(self,sampledata): self.sampledata = sampledata total_sum = 0 total_count = 0 for col in list(self.sampledata.columns): total_sum += self.sampledata[col].sum() total_count += self.sampledata[col].count() self.total_var = np.round(total_sum / total_count,4) def sst(self): result = pd.DataFrame(index=self.sampledata.index, columns = self.sampledata.columns) total_sum = 0 for col in list(result.columns): result[col] = (self.sampledata[col] - self.total_var) ** 2 total_sum += result[col].sum() return np.round(total_sum,6) def ssm(self): total_sum = 0 for col in list(self.sampledata.columns): total_sum += ((self.sampledata[col].mean() - self.total_var) ** 2) * self.sampledata[col].count() return np.round(total_sum,6) def sse(self): total_sum = 0 for col in list(self.sampledata.columns): total_sum += sum((self.sampledata[col] - self.sampledata[col].mean()) ** 2) return np.round(total_sum,6) # 计算样本的F值 def f_value(self): total_columns = len(self.sampledata.columns) total_sample_nums = sum(self.sampledata.count()) f = self.ssm() * (total_sample_nums - total_columns) / (self.sse() * (total_columns - 1)) return np.round(f,6) def test(): sampledata = pd.DataFrame({'algo_a':[0.29,0.36,0.32,0.29,0.34,0.24,0.27,0.29,0.31,0.27], 'algo_b':[0.29,0.33,0.31,0.30,0.31,0.26,0.25,0.30,0.28,0.29]}) test_var = VarianceAnaly(sampledata) print('sst=',test_var.sst()) print('ssm=',test_var.ssm()) print('sse=',test_var.sse()) print('F=',test_var.f_value()) if __name__ == '__main__': test()展开1
- arcsinx2021-07-26老师,p>0.05 可以接受原假设吗?我记得一般是反证,使p<0.05之后拒绝原假设?
作者回复: 对,如果你设置p的阈值为0.05,那么大于0.05就表示接受原假设,否则拒绝原假设。当然,如果要求没那么严苛,可以适当放大p的阈值
- 撒冷之王2021-07-21你好, 例子中自变量数目 m = s-1 = 1; 不是太明白为什么 m 是根据 s-1 算出来的呢? 如果是文中的例子,自变量数目不就是“不同的算法” 这一个自变量吗(m = 1 就直接得出了)
作者回复: 这里“不同的算法”包括a和b,所以不同算法的数量为2,m=s-1=2-1=1
- Geek33402021-05-181.H0是一定要用均值进行假设,而且一定是假设两组或者多组均值相等,是原假设吗?H1是不相等吗? 2. “虽然算法a所导致的平均转化率要比算法b的相对高出约2%”,如果10天的平均值是0.298对比0.292,哪里来的高出2%呢?3. 如果方差分析,结果表明差异没有显著性,那下一步需要找其他什么分析方法来检验a/b测试哪个好呢? 4. 如何判断两组或多组数据一定是正态分布?如果不是正态分布,那怎么办呢?
作者回复: 1. 对,H0假设是两者没有区别,来自同一个数据分布。H1表示相反意见。 2. 第二个原文没有说清楚是相对提升,也是0.292/0.298 = 1.02 3. 如果没有显著性,可以使用其他例如t检验、CHI方等等。如果多个结果都显示出没有显著的差异,那么a/b测试的结论就是两者没有统计上的差异
- wuqg2020-12-11老师,除了pvalue还有置信区间来分析ab测试,您也给讲讲吧。
作者回复: 这个问题很好,不过留言回复里说不清,极客时间和人民邮电出版社明年初就会联合发行我所著的《程序员的数学基础课-从理论到Python实战》,这本书是以本专栏为基础,新增了部分内容,对置信区间和AB测试有更为详细的解释
- Paul Shan2019-09-17F值反应了不同样本的差异是否由系统因素引起,而非采样的随机性引起的参数。 F值可以由样本的观察值计算得到。