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

如何用R/Python实现Kolmogorov-Smirnov检验功效的蒙特卡洛模拟

KS检验与Lilliefors检验功效蒙特卡洛模拟复现方案

首先明确两个检验的核心差异,避免复现逻辑出错:

  • 普通Kolmogorov-Smirnov(KS)检验:原假设下分布完全已知(本次设定为固定的标准正态$N(0,1)$,无参数估计步骤),临界值直接调用scipy.stats.ksone计算,完全匹配原论文的实现逻辑
  • Lilliefors检验:正态分布拟合优度场景下的KS修正版本,原假设为样本来自某一正态分布(均值、方差由样本估计,不固定为0和1),临界值不能直接套用ksone分布,需使用Lilliefors专属临界值计算结果

模拟参数对齐原论文设定

  • 显著性水平$\alpha=0.05$
  • 固定样本量$n=100$
  • 备择真实分布:$Beta(2,2)$
  • 功效计算逻辑:重复生成指定分布的样本、执行检验,统计拒绝原假设的次数占总重复次数的比例
  • 建议模拟重复次数:至少10000次,结果波动可控制在1%以内

Python实现代码(对齐原论文scipy实现逻辑)

先安装依赖:pip install numpy scipy statsmodels matplotlib

import numpy as np
from scipy import stats
from statsmodels.stats.diagnostic import lilliefors
import matplotlib.pyplot as plt

# 固定随机种子保证结果可复现
np.random.seed(42)

# 初始化模拟参数
alpha = 0.05
n = 100
n_reps = 10000
# 普通KS检验临界值,直接调用原论文提及的scipy.stats.ksone模块计算
ks_critical = stats.ksone.ppf(1 - alpha, n)

# 拒绝次数计数
ks_reject = 0
lillie_reject = 0

for _ in range(n_reps):
    # 生成Beta(2,2)分布样本,值域为[0,1]无需额外转换
    sample = np.random.beta(2, 2, size=n)
    
    # 1. 普通KS检验:原假设为样本来自固定的N(0,1)
    ks_stat, _ = stats.kstest(sample, cdf='norm', args=(0,1))
    if ks_stat > ks_critical:
        ks_reject += 1
    
    # 2. Lilliefors检验:原假设为样本来自某正态分布(参数从样本估计)
    # statsmodels内置临界值与原论文使用的Lilliefors临界值表一致
    lillie_stat, lillie_p = lilliefors(sample, dist='norm')
    if lillie_p < alpha:
        lillie_reject +=1

# 计算检验功效
ks_power = ks_reject / n_reps
lillie_power = lillie_reject / n_reps
print(f"普通KS检验(F0固定为N(0,1))功效:{ks_power:.3f}")
print(f"Lilliefors检验功效:{lillie_power:.3f}")

# 绘制结果对比图
plt.figure(figsize=(6,4))
tests = ['Kolmogorov-Smirnov', 'Lilliefors']
powers = [ks_power, lillie_power]
bars = plt.bar(tests, powers, color=['#1f77b4', '#ff7f0e'])
plt.ylabel('检验功效(α=0.05, n=100, 真实分布Beta(2,2))')
plt.ylim(0, 1)
# 柱子上标注功效数值
for bar in bars:
    height = bar.get_height()
    plt.text(bar.get_x() + bar.get_width()/2., height,
             f'{height:.3f}',
             ha='center', va='bottom')
plt.tight_layout()
plt.show()

结果说明:Beta(2,2)均值为0.5、方差为0.05,和固定的N(0,1)位置、尺度差异极大,因此固定参数的普通KS检验功效会接近1;而Lilliefors检验允许正态分布的均值、方差从样本估计,仅检验分布形态是否符合正态,Beta(2,2)为对称有界分布,和正态的形态差异远小于位置尺度差异,因此功效会显著低于普通KS检验,和原论文结果趋势完全一致。

R可选实现方案

核心逻辑与Python版本一致,代码如下:

set.seed(42)
# 加载Lilliefors检验所需包,首次运行请先执行install.packages("nortest")
library(nortest)
alpha <- 0.05
n <- 100
n_reps <- 10000
ks_reject <- 0
lillie_reject <- 0

for (i in 1:n_reps) {
  sample <- rbeta(n, 2, 2)
  # 普通KS检验,固定原分布为N(0,1)
  ks_res <- ks.test(sample, "pnorm", 0, 1)
  if (ks_res$p.value < alpha) ks_reject <- ks_reject + 1
  # Lilliefors检验
  lillie_res <- lillie.test(sample)
  if (lillie_res$p.value < alpha) lillie_reject <- lillie_reject + 1
}

ks_power <- ks_reject / n_reps
lillie_power <- lillie_reject / n_reps
print(paste0("KS检验功效:", round(ks_power,3)))
print(paste0("Lilliefors检验功效:", round(lillie_power,3)))

# 绘制对比图
barplot(c(ks_power, lillie_power), 
        names.arg = c("Kolmogorov-Smirnov", "Lilliefors"),
        ylab = "检验功效", ylim = c(0,1),
        col = c("#1f77b4", "#ff7f0e"))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 20:27:28