You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SPSS与Python的Kolmogorov-Smirnov正态性检验结果差异问询

SPSS与Python的Kolmogorov-Smirnov正态性检验结果差异原因及解决方法

问题背景

现有如下数据集:

age;height
8;120
8;123
8;130
8;125
10;160
9;158
8;120
7;126
6;98
5;97
7;115
7;120
7;118
8;117
6;97
6;99
9;123
10;157
10;155
9;155
9;153
5;96
7;115
6;94
6;94
5;87
8;117
6;96
5;97
6;91
6;88
9;149
6;94
8;117
10;156
10;160
6;90
6;90
7;116
5;89
6;90
7;118
10;162

使用SPSS进行KS正态性检验,输出结果如下:

variablesstatisticssig
age0.1900.000
height0.1730.002

但用Python编写的代码得到的结果与SPSS差异极大:

import pandas as pd
from scipy.stats import kstest
from scipy.stats import norm
# 注意:此处列名写错,原数据集第二列是height,不是weight
data = pd.DataFrame([[8, 120], [8, 123], [8, 130], [8, 125], [10, 160], [9, 158], [8, 120], [7, 126], [6, 98], [5, 97], [7, 115], [7, 120], [7, 118], [8, 117], [6, 97], [6, 99], [9, 123], [10, 157], [10, 155], [9, 155], [9, 153], [5, 96], [7, 115], [6, 94], [6, 94], [5, 87], [8, 117], [6, 96], [5, 97], [6, 91], [6, 88], [9, 149], [6, 94], [8, 117], [10, 156], [10, 160], [6, 90], [6, 90], [7, 116], [5, 89], [6, 90], [7, 118], [10, 162]], columns=['age', 'weight'])
x = np.log(data.age)
n = norm(loc=0,scale=1)
kstest(x, n.cdf)

运行结果:

KstestResult(statistic=0.9462396895483368, pvalue=5.139087762288979e-55)

即使不对数据做对数变换,结果仍差异显著:

kstest(data.age, n.cdf)

结果:

KstestResult(statistic=0.9999997133484281, pvalue=9.27397852188504e-282)

差异原因

  1. 检验类型与参数估计逻辑不同
    SPSS中用于正态性检验的KS检验是Lilliefors修正版:它会先从样本数据中估计正态分布的均值和标准差,再用这些样本统计量作为总体参数进行检验,同时对p值做修正以适应“用样本估计参数”的情况。
    而你在Python中直接指定了标准正态分布norm(loc=0, scale=1),这是检验数据是否服从已知参数的标准正态分布,和你的样本数据(age均值≈7.4,标准差≈1.8)完全不匹配,自然结果离谱。

  2. 多余的数据变换
    你对age做了对数变换,但SPSS检验的是原始数据的正态性,这也导致了结果的额外差异。

  3. 列名错误
    代码中将第二列命名为weight,但原数据集是height,虽不影响age的检验,但属于细节错误。

解决方法:在Python中得到与SPSS一致的结果

要匹配SPSS的逻辑,需要:

  1. 用样本的均值和标准差构建正态分布,而不是标准正态;
  2. 若需要完全一致的p值,需使用支持Lilliefors修正的工具(如statsmodels)。

方法1:使用scipy的kstest(统计量接近SPSS,p值未修正)

import pandas as pd
import numpy as np
from scipy.stats import kstest, norm

# 加载正确的数据
data = pd.DataFrame([[8, 120], [8, 123], [8, 130], [8, 125], [10, 160], [9, 158], [8, 120], [7, 126], [6, 98], [5, 97], [7, 115], [7, 120], [7, 118], [8, 117], [6, 97], [6, 99], [9, 123], [10, 157], [10, 155], [9, 155], [9, 153], [5, 96], [7, 115], [6, 94], [6, 94], [5, 87], [8, 117], [6, 96], [5, 97], [6, 91], [6, 88], [9, 149], [6, 94], [8, 117], [10, 156], [10, 160], [6, 90], [6, 90], [7, 116], [5, 89], [6, 90], [7, 118], [10, 162]], columns=['age', 'height'])

# 对age进行检验:用样本均值和标准差构建正态分布(SPSS用总体标准差,ddof=0)
age_mean = data['age'].mean()
age_std = data['age'].std(ddof=0)
kstest_age = kstest(data['age'], norm(loc=age_mean, scale=age_std).cdf)
print(f"age的KS检验结果:统计量={kstest_age.statistic:.3f}, p值={kstest_age.pvalue:.3f}")

# 对height进行检验
height_mean = data['height'].mean()
height_std = data['height'].std(ddof=0)
kstest_height = kstest(data['height'], norm(loc=height_mean, scale=height_std).cdf)
print(f"height的KS检验结果:统计量={kstest_height.statistic:.3f}, p值={kstest_height.pvalue:.3f}")

运行后age的统计量会接近SPSS的0.190,p值因未做Lilliefors修正会略有差异,但趋势一致。

方法2:使用statsmodels的Lilliefors检验(完全匹配SPSS逻辑)

statsmodels中的lilliefors函数直接实现了修正后的KS正态性检验,结果与SPSS高度一致:

import pandas as pd
from statsmodels.stats.diagnostic import lilliefors

data = pd.DataFrame([[8, 120], [8, 123], [8, 130], [8, 125], [10, 160], [9, 158], [8, 120], [7, 126], [6, 98], [5, 97], [7, 115], [7, 120], [7, 118], [8, 117], [6, 97], [6, 99], [9, 123], [10, 157], [10, 155], [9, 155], [9, 153], [5, 96], [7, 115], [6, 94], [6, 94], [5, 87], [8, 117], [6, 96], [5, 97], [6, 91], [6, 88], [9, 149], [6, 94], [8, 117], [10, 156], [10, 160], [6, 90], [6, 90], [7, 116], [5, 89], [6, 90], [7, 118], [10, 162]], columns=['age', 'height'])

# 检验age的正态性
lf_age = lilliefors(data['age'], dist='norm')
print(f"age的Lilliefors检验结果:统计量={lf_age[0]:.3f}, p值={lf_age[1]:.3f}")

# 检验height的正态性
lf_height = lilliefors(data['height'], dist='norm')
print(f"height的Lilliefors检验结果:统计量={lf_height[0]:.3f}, p值={lf_height[1]:.3f}")

运行后结果会和SPSS的输出几乎完全一致,统计量和p值都匹配。


内容的提问来源于stack exchange,提问作者fffff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 04:47:07