假设检验:正态性检验的那些bug——为什么对同一数据,normaltest和ktest会得到完全相反的结果?

总体分布假设检验原理-卡方检验

    对总体分布的假设检验是一种非参数检验,所谓非参数假设检验,即在不确定总体分布的数学形式下,对总体的各种一般性推断。例如,“X服从正态分布”,“X1,X2,…,Xn”同分布等都是非参数假设。对总体分布假设检验的一般形式:设x1,x2,…,xn,来自总体X的样本,据此样本需要检验假设
H0

  • X的分布函数为F(x)
  • X的概率密度函数为f(x)
  • 或P(Xi)=p,i=1,2,…,k

H1X的***不是

例1

掷一颗骰子240次,得点数的频数(观测频数)如下,是否服从均匀分布?

出现点数 1 2 3 4 5 6
观测频数 45 36 31 48 42 38

:设X表示掷这颗骰子一次出现的点数,其有6种可能取值,若X服从均匀分布,则p(x=i)=1/6,i=1,2,…,6。所以原假设可以写作如下形式:
H0 :X服从均匀分布,即
H0 :P(X=i)=p, i=1,2,…,6;p=1/6
计算卡方统计量公式如下,
假设检验:正态性检验的那些bug——为什么对同一数据,normaltest和ktest会得到完全相反的结果?_第1张图片
    分别计算每种取值的观测频数和期望频数(理论频数),得到卡方值,然后查表得到P值,通过P值与置信水平α来判断是否接受原假设,P值越大越容易接受原假设,即认为样本服从均匀分布。

例2

    随机抽取到一部分样本x,x为连续数据,问X是否服从正态分布?

:假设x的概率密度函数为
f ( x ) = 1 2 π σ 2 e − ( x − μ ) 2 2 σ 2 f(x) =\frac{1}{\sqrt{2\pi\sigma^2}}e^{-\frac{(x-\mu)^2}{2\sigma^2}} f(x)=2πσ2 1e2σ2(xμ)2

其中μ和σ未知,可以通过极大似然方法对样本估计得到均值和方差的估计值。

有了概率密度函数,就可以设置原假设为:
H0X服从正态分布,即
H0X具有概率密度函数:
f ( x ) = 1 2 π σ 2 e − ( x − μ ) 2 2 σ 2 f(x) =\frac{1}{\sqrt{2\pi\sigma^2}}e^{-\frac{(x-\mu)^2}{2\sigma^2}} f(x)=2πσ2 1e2σ2(xμ)2

    对于连续数据,计算卡方统计量时,需将原数据分箱处理,即转换为分组数据,然后分别计算每组的观测频数和期望频数(理论频数),得到卡方值,查表得到P值,通过P值与置信水平α来判断是否接受原假设,P值越大越容易接受原假设,即认为样本服从正态分布。

卡方检验原理总结

    卡方检验是非参数假设检验方法,使用的统计量是卡方。例如做正态性假设检验时,需先根据现有样本,使用极大似然的方法估计出概率密度函数的参数:均值和方差,得到正态分布的概率密度函数f(x)的函数形式,从而可以计算概率值,进而可以计算期望频数(np)来计算卡方统计量,以及P值,通过P值和置信水平的大小比较来判断原假设是是否成立。
步骤:

  • 使用极大似然的方法估计概率密度函数的参数值或直接估计概率
  • 设置原假设为
    H0:概率密度函数=f(x)。
    或 P(x)=p
    3.计算卡方值,P值,判断是否接受原假设。

P值越大越容易接受原假设,即样本否从某种分布。

正态性检验工具

  • k2, p = stats.normaltest(x)
    normaltest:非参数假设检验方法,正态性检验时,函数可以自行估计概率密度函数参数值。
  • k2, p =scipy.stats.kstest(rvs=x,cdf=‘norm’,args=(0,1))
    kstest:非参数假设检验方法,正态性检验时,函数默认均值为0,方差为1
  • k2, p =scipy.stats.shapiro(x)
    shapiro:非参数假设检验方法,适用于小样本(样本容量<5000)。正态性检验时,函数可以自行估计概率密度函数参数值。??

normaltest、kstest、shapiro三者的原假设均可以为X服从正态分布,P值越小,越容易拒绝原假设,即认为数据不服从正态分布。

有如下数据,

import scipy
import numpy as np
rng = np.random.default_rng()

a = rng.normal(0, 1, size=3000)
b = rng.normal(10, 20, size=3000)
c = np.concatenate((a, b))
  1. normaltest
k2, p = stats.normaltest(b)

假设检验:正态性检验的那些bug——为什么对同一数据,normaltest和ktest会得到完全相反的结果?_第2张图片
2. kstest
假设检验:正态性检验的那些bug——为什么对同一数据,normaltest和ktest会得到完全相反的结果?_第3张图片

注意:
    scipy.stats.normaltest是非参数假设检验总体分布,使用的统计量是卡方。先根据现有样本,使用极大似然的方法估计出均值和方差,得到正态分布的概率密度函数f(x),原假设为H0:概率密度函数=f(x)。而ktest也是非参数检验方法,但是参数估计值默认是均值=0,方差=1或者需要手动输入均值和方差参数。所以,对于同一数据(非标准正态分布),normaltest(估计样本得到参数)和ktest(使用默认参数)得到的结果自然不一样,甚至相反也很正常。也因此,做正态性假设检验时,最好对原数据z-score处理一下,不容易出错。

  • 手动填入样本均值、标准差

假设检验:正态性检验的那些bug——为什么对同一数据,normaltest和ktest会得到完全相反的结果?_第4张图片

  • 对数据做z-score标准化处理

假设检验:正态性检验的那些bug——为什么对同一数据,normaltest和ktest会得到完全相反的结果?_第5张图片

  1. shapiro
    假设检验:正态性检验的那些bug——为什么对同一数据,normaltest和ktest会得到完全相反的结果?_第6张图片
    注意
    使用shapiro做正态性检验时,有一点要注意,如源代码介绍:假设检验:正态性检验的那些bug——为什么对同一数据,normaltest和ktest会得到完全相反的结果?_第7张图片shapiro适合检验样本容量小于5000的数据,超过5000时,P值将不在准确。
import numpy as np
import pandas as pd
a = rng.normal(0, 1, size=100)
b = rng.normal(10, 6, size=100)
c = np.concatenate((a, b))
d = rng.normal(0, 1, size=6000)
e = rng.normal(10, 5, size=10000)

x=[a,b,c,d,e]

p_list=[]
for da in x:
    _,p1=scipy.stats.shapiro(da)
    _,p2= scipy.stats.kstest(rvs=da,cdf='norm',args=(da.mean(),da.std()))
    _,p3 = stats.normaltest(da)
    p_list.append([p1,p2,p3])
df =pd.DataFrame(p_list,index=['a','b','c','d','e'],columns=['shapiro','kstest','normaltest'])
df>0.05

假设检验:正态性检验的那些bug——为什么对同一数据,normaltest和ktest会得到完全相反的结果?_第8张图片

你可能感兴趣的:(数据分析,python,概率论,数据分析)