如果样本不是正态分布,还能用t-test或者z-test吗?

  统计/机器学习 AB Test 假设检验 概率分布    浏览次数: 302
2

最近面了Quora的DS,这算是一个面经题目吧。

做A/B Test的时候,如果KPI不是正态分布的,那么怎么比较两个均值呢?面试官的意思是说t-test和z-test可能会出问题。

应该用什么方法呢?

 

长路漫漫   2018-10-17 09:13



   4个回答 
11

该用Mann-Whitney_U_test(和Wilcoxon rank sum test还不一样)。是比较两个sample的median/mean是否有区别。

这里有个例子。

我也不懂,学习了下,体会它的思路是:即使原数据(KPI)非正太分布,但是它们的rank $U$大概是正太分布,然后对$U$做normalization后再查表检验是否能否定null假设。

--------------------------------------------------------------

做了个实验,对于非正态分布,t test的independent pair test会有很大偏差,比如期望的p接近0,但是得到的p分布较广;Mann-Whitney_U_test才能得到正确的p值。而对于接近正态的分布,t test 更准确。

结论如果接近正态分布,用t-test更准确,否则用Mann-Whitney_U_test。

实验如下:

产生左图里的两个gaussian mixture的sample x1,x2。

共生成K=1000次,sample的个数比较多,$n1=10000,n2=20000$。可

以看到$mean(x1)\approx mean(x2)$, $median(x1)>median(x2)$。所以如果检测中比较的是x1,x2的mean,p值应该接近0.


分别进行t test和Mann-Whitney_U_test,p值的分布如下。可以看到Mann-Whitney_U_test的p值才接近于期望。因为sample size$n1,n2$足够大,说明此时中心极限定理并不能让t test满足正态分布的前提。


如果x1,x2来源于同一个gaussian,t test 的p值更接近0。

#Compare t_test and Mann-Whitney_U_test(or rank sum test) for Gaussian mixture case
import numpy as np
import matplotlib.pyplot as plt
from numpy import random
import scipy as sp
from scipy.stats import ttest_ind,ranksums,mannwhitneyu
n1=10000 # sample size of group1
n2=2*n1 # sample size of group2
K=1000 # number of Monte Carlo tests
random.seed(0)
x1=np.zeros([K,n1])
x2=np.zeros([K,n2])

# 2 component Gaussian mixture
sigma1=.5
sigma2=.5
mu1=np.array([-2.0,1.]*10)
mu2=np.array([-1.,2.]*10)

pi1b=2./3 # prob(sample x1 from Gaussian1b)
pi2b=1./3 # prob(sample x2 from Gaussian2b)
n1_b=np.int(n1*pi1b)
n1_a=n1-n1_b
n2_b=np.int(n2*pi2b)
n2_a=n2-n2_b


mean1=np.zeros([K,1])
mean2=np.zeros([K,1])
median1=np.zeros([K,1])
median2=np.zeros([K,1])
var1=np.zeros([K,1])
var2=np.zeros([K,1])

t_value=np.zeros([K,1])
p_value=np.zeros([K,1])

ranksum_value=np.zeros([K,1])
p_ranksum_value=np.zeros([K,1])

for k in range(K):
    x1_temp0=random.normal(loc=mu1[0],scale=sigma1,size=[1,n1_a])
    x1_temp1=random.normal(loc=mu1[1],scale=sigma1,size=[1,n1_b])
    x1_temp=np.concatenate([x1_temp0,x1_temp1],axis=-1)
    x1[k,:]=x1_temp
    mean1[k]=x1_temp.mean()
    median1[k]=np.median(x1_temp)
    var1[k]=np.var(x1_temp)
    
    x2_temp0=random.normal(loc=mu2[0],scale=sigma2,size=[1,n2_a])
    x2_temp1=random.normal(loc=mu2[1],scale=sigma2,size=[1,n2_b])
    x2_temp=np.concatenate([x2_temp0,x2_temp1],axis=-1)
    x2[k,:]=x2_temp
    mean2[k]=x2_temp.mean()
    median2[k]=np.median(x2_temp)
    var2[k]=np.var(x2_temp)
    
    result=ttest_ind(x1_temp.flatten(),x2_temp.flatten(),equal_var=False)
    t_value[k]=result[0]
    p_value[k]=1.-result[1]
#     result=ranksums(x1_temp.flatten(),x2_temp.flatten())
    result=mannwhitneyu(x1_temp.flatten(),x2_temp.flatten())
    ranksum_value[k]=result[0]
    p_ranksum_value[k]=result[1]
    
    
bins = np.linspace(-3, 3, 100)

plt.figure(figsize=[15,5])
plt.subplot(131)
plt.hist(x1.flatten(),bins,label='x1',alpha=0.5,normed=True)
plt.hist(x2.flatten(),bins,label='x2',alpha=0.5,normed=True)
plt.title('True pdf of x1 and x2')
plt.legend()

plt.subplot(132)
plt.hist(mean1.flatten(),bins,label='x1',alpha=0.5,normed=True)
plt.hist(mean2.flatten(),bins,label='x2',alpha=0.5,normed=True)
plt.title('hist of mean')
plt.legend()

plt.subplot(133)
plt.hist(median1.flatten(),bins,label='x1',alpha=0.5,normed=True)
plt.hist(median2.flatten(),bins,label='x2',alpha=0.5,normed=True)
plt.title('hist of median')
plt.legend()
plt.show()

bins1 = np.linspace(0, 1, 100)

plt.figure()
plt.hist(p_value.flatten(),bins1,label='t_test',alpha=.5,normed=True,color='red')
plt.hist(p_ranksum_value.flatten(),bins1,label='Mann-Whitney_U_test',alpha=.5,normed=True,color='green')
plt.title('p_value of t_test and Mann-Whitney_U_test')
plt.legend()
plt.show()


SofaSofa数据科学社区 DS面经 问答 实战

Zealing   2018-10-17 12:34

太牛了,非常详细,感谢! - 长路漫漫   2018-10-18 09:04
4

1.中位数

2.数值变换

SofaSofa数据科学社区 DS面经 问答 实战

陈十一   2018-10-17 10:12

谢谢,数值变化是指取对数那种吗? - 长路漫漫   2018-10-17 10:15
2

当数据量很大的时候,t-test或者z-test应该不太需要担心正态性了吧(中心极限定理)

SofaSofa数据科学社区 DS面经 问答 实战

zl_pku   2018-10-17 14:04

0

可以考虑用一些nonparametric bootstrap的方法

SofaSofa数据科学社区 DS面经 问答 实战

Marvin_THU   2018-10-29 21:21



  相关主题

如何从假设检验的角度去理解AB testing   2回答

E-test是什么意思?   3回答

怎么判断一个概率分布是对称的?   3回答

如何检验两个样本是同分布的?   4回答

python中实现柯尔莫可洛夫-斯米洛夫检验(K-S test)   1回答

方差分析的多重比较校正   1回答

python里Z-score和P-value相互转换   1回答

单样本T检验的自由度为什么是n-1?   1回答

线性回归因变量y不满足正态性假设   1回答

python里怎么画QQ图?   1回答

配对T检验和两样本T检验是一回事么?   1回答

z test和t test什么区别?   1回答



回答问题时需要注意什么?

我们谢绝在回答前讲“生动”的故事。

我们谢绝“这么简单,你自己想”、“书上有的,你认真看”这类的回答;如果你认为对方的提问方式或者内容不妥,你可以直接忽略该问题,不用进行任何作答,甚至可以对该问题投反对票。

我们谢绝答非所问。

我们谢绝自己不会、硬要回答。

我们感激每一个用户在编写答案时的努力与付出!