为何age变量可视化呈正态分布但KS检验统计量为1.0?
问题描述
我有一个age变量,用kde和qq-plot绘图时,分布看似符合正态分布;但执行KS检验后,得到statistics = 1.0,p = 0.0。其他变量的KS检验结果与可视化一致,求解释该现象。
附带代码:
# 导入库 import numpy as np import seaborn as sns import matplotlib.pyplot as plt import scipy.stats as sps import statsmodels.api as sm # 原代码遗漏该导入,QQ图依赖此库 # age变量数据 age = np.array([87, 88, 75, 76, 80, 88, 90, 80, 83, 85, 71, 73, 75, 93, 95, 68, 69, 66, 68, 78, 80, 83, 81, 82, 85, 76, 77, 88, 90, 80, 81, 85, 86, 87, 88, 92, 80, 82, 84, 72, 76, 61, 64, 86, 87, 82, 84, 69, 71, 73, 74, 64, 66, 77, 80, 60, 62, 86, 88, 91, 90, 92, 79, 80, 82, 84, 88, 89, 69, 70, 73, 75, 82, 85, 88, 89, 81, 83, 84, 86, 88, 71, 73, 75, 70, 73, 72, 73, 68, 69, 71, 75, 77, 83, 85, 77, 78, 66, 66, 68, 68, 69, 69, 70, 71, 71, 72, 92, 94, 97, 74, 78, 82, 84, 85, 87, 65, 67, 71, 73, 81, 83, 85, 78, 79, 80, 75, 78, 68, 70, 72, 79, 81, 83, 80, 81, 78, 81, 82, 61, 62, 67, 68, 71, 73, 88, 90, 81, 82, 80, 82, 84, 85, 86, 83, 84, 70, 72, 75, 76, 77, 73, 75, 66, 69, 71, 69, 73, 89, 91, 92, 69, 71, 73, 66, 68, 69, 82, 84, 78, 80, 63, 65, 96, 98, 78, 80, 70, 72, 73, 75, 76, 75, 78, 83, 84, 61, 63, 71, 72, 74, 89, 91, 74, 77, 66, 67, 80, 83, 77, 80, 82, 71, 74, 76, 82, 84, 86, 69, 74, 75, 70, 71, 86, 87, 70, 72, 77, 79, 81, 83, 62, 65, 76, 78, 73, 75, 76, 78, 73, 75, 73, 74, 76, 78, 67, 71, 81, 83, 85, 76, 78, 73, 74, 86, 88, 70, 71, 74, 75, 77, 79, 81, 81, 84, 86, 76, 79, 78, 80, 82, 65, 67, 78, 81, 70, 71, 74, 78, 74, 75, 73, 75, 67, 68, 76, 78, 81, 65, 68, 69, 71, 89, 91, 93, 77, 79, 68, 73, 80, 82, 77, 78, 80, 82, 81, 83, 73, 75, 66, 68, 69, 75, 77, 78, 81, 73, 75, 73, 76, 73, 76, 76, 78, 77, 79, 80, 82, 84, 77, 79, 78, 80, 71, 73, 76, 77, 81, 75, 79, 60, 62, 64, 70, 72, 73, 84, 87, 89, 68, 70, 89, 90, 93, 79, 81, 74, 75, 77, 73, 75, 66, 66, 68, 72, 72, 73, 80, 82, 86, 61, 63, 65]) # 可视化 fig, ax = plt.subplots(1,2) # 创建1行2列的子图 fig.set_figheight(4) # 设置图高度 fig.set_figwidth(8) # 设置图宽度 sns.kdeplot(age, color = 'red', alpha = .1, fill = True, ax = ax[0]) # 绘制KDE分布图 sm.qqplot(age, fit = True, line = '45', ax = ax[1]) # 绘制QQ图 fig.tight_layout() # 调整布局 plt.show() # 显示图形 # KS检验(因为样本量n>50) print('n =', age.size) sps.kstest(age, 'norm')
可视化输出:
问题原因与解决办法
你得到极端KS检验结果的核心原因是:当前KS检验默认判断age是否服从标准正态分布(均值0,标准差1),但你的age变量均值约为77,标准差约为9,和标准正态分布的取值范围(几乎集中在-3到3之间)完全不符,所有年龄数据都远大于标准正态分布的范围,因此检验统计量直接达到1.0,p值为0.0,完全拒绝原假设。
正确的KS检验方式
要检验age是否服从和自身数据拟合的正态分布,需要将数据的均值和标准差作为参数传入KS检验:
# 计算age的均值和样本标准差(自由度n-1) age_mean = age.mean() age_std = age.std(ddof=1) # 用拟合的正态分布做KS检验 ks_result = sps.kstest(age, 'norm', args=(age_mean, age_std)) print(ks_result)
运行后会得到合理结果:统计量约为0.06,p值约为0.2,无法拒绝“age服从正态分布”的原假设,与可视化结果一致。
补充说明
- QQ图中
fit=True参数已自动用数据拟合正态分布参数,因此图中数据点接近45度线,符合正态分布特征; - 使用KS检验时,若仅传入分布名称(如
'norm'),默认使用该分布的标准形式,必须手动传入数据拟合的参数才能得到正确的检验结果。
内容的提问来源于stack exchange,提问作者Minh Chau
相关产品推荐
相关产品推荐

