SCIPY Kolmogorov-Smirnov检验用目标分布随机数据得极小P值问题
问题根源:
ks_1samp不支持多维数据检验 你用错工具了——scipy.stats.ks_1samp是专门为一维数据设计的单样本KS检验,根本没法直接处理二维数据,这才导致结果完全异常。
具体哪里错了?
- 你的
data是(1000,2)的二维数组,包含1000个二维坐标点;但ks_1samp会默认把输入的多维数组扁平化成一维序列(也就是把1000个点的x、y分量全部拆出来,变成2000个独立的数值)。 - 你传入的
cdfx是二维正态分布的联合CDF,它要求输入的是二维点(比如[0.5, 1.2]),返回的是P(X≤0.5, Y≤1.2)这样的联合概率。但ks_1samp会把扁平化后的每个一维数值(比如0.5)单独传给cdfx,这时候cdfx会自动把这个标量广播成二维点[0.5, 0.5],计算的是两个维度都小于等于该值的联合概率——这和你要检验的“每个维度是否服从一维正态”完全不是一回事。
这种维度不匹配的错误输入,直接导致KS统计量异常大(接近1),p值变成0,完全没有参考意义。
正确的做法
如果要验证你的数据是否符合二维标准正态分布,可以分两种情况处理:
- 分别检验每个维度的正态性:把
data拆成x分量和y分量,各自用ks_1samp和一维标准正态CDF对比:
这时候你会得到正常的p值(大概率接近1,因为数据就是按标准正态生成的)。from scipy.stats import norm, ks_1samp import numpy as np from scipy.stats import multivariate_normal data = np.random.multivariate_normal(mean=[0,0], cov=[[1,0],[0,1]], size=1000) # 检验x分量 ks_x = ks_1samp(data[:,0], norm.cdf) # 检验y分量 ks_y = ks_1samp(data[:,1], norm.cdf) print(ks_x, ks_y) - 多维正态性整体检验:如果要严格检验联合分布是否符合二维正态,可以用专门的方法,比如基于马氏距离的卡方检验,或者使用第三方库(比如
pingouin的multivariate_normality函数)。
内容的提问来源于stack exchange,提问作者Imp
相关产品推荐
相关产品推荐

