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

如何验证数据概率密度是否符合幂律、指数或拉伸指数分布?

验证数据分布:幂律、指数与拉伸指数分布

我需要验证自己的数据概率密度是否符合幂律(power-law)、指数分布(exponential distribution)或拉伸指数函数(stretched exponential function)。目前已经用scipy的powerlaw.fit和expon.fit实现了幂律与指数分布的拟合及检验,但不清楚如何验证拉伸指数分布,现有代码如下:

pip install powerlaw

import numpy as np
import scipy.stats as stats
from scipy.stats import ks_2samp
from scipy.stats import powerlaw, expon
from scipy.stats import kstest
from scipy.optimize import curve_fit
from powerlaw import Fit

#验证概率密度是否符合幂律或指数分布
data = [120.0, 120.0, 100.0, 25.0, 20.0, 30.0, 28.0, 60.0, 90.0, 30.0, 24.0, 30.0, 30.0]

# 将数据拟合到幂律分布
params_powerlaw = powerlaw.fit(data)

# 将数据拟合到指数分布
params_exponential = expon.fit(data)

# 执行Kolmogorov-Smirnov检验以比较分布
D_powerlaw, p_powerlaw = kstest(data, powerlaw.cdf, args=params_powerlaw)
D_exponential, p_exponential = kstest(data, expon.cdf, args=params_exponential)

# 打印检验统计量和p值
print('Kolmogorov-Smirnov检验统计量:')
print('幂律分布(Power-law):', D_powerlaw)
print('指数分布(Exponential):', D_exponential)
print('\nKolmogorov-Smirnov检验p值:')
print('幂律分布(Power-law):', p_powerlaw)
print('指数分布(Exponential):', p_exponential)


#打印参数
print("\n幂律分布alpha =", params_powerlaw[0])    
print("\n指数分布loc =", params_exponential[0], "scale =", params_exponential[1])

# 比较p值以确定哪个分布拟合效果更好
if p_powerlaw > p_exponential:
    print('\n数据符合幂律分布(Power-law)。')
else:
    print('\n数据符合指数分布(Exponential)。')

拉伸指数分布的拟合与检验实现

拉伸指数分布的累积分布函数(CDF)形式为:

( F(x; \lambda, \beta) = 1 - e{-(x/\lambda)\beta} )
其中(\lambda > 0)是尺度参数,(\beta > 0)是形状参数(当(\beta=1)时退化为指数分布)。

由于scipy没有直接提供拉伸指数分布的拟合函数,我们可以用scipy.optimize.curve_fit自定义拟合逻辑,再用KS检验验证拟合效果。

修改后的完整代码

import numpy as np
import scipy.stats as stats
from scipy.stats import powerlaw, expon, kstest
from scipy.optimize import curve_fit

# 待检验数据
data = [120.0, 120.0, 100.0, 25.0, 20.0, 30.0, 28.0, 60.0, 90.0, 30.0, 24.0, 30.0, 30.0]
# 对数据排序,方便后续拟合计算
sorted_data = np.sort(data)

# ---------------------- 幂律分布拟合与检验 ----------------------
params_powerlaw = powerlaw.fit(data)
D_powerlaw, p_powerlaw = kstest(data, powerlaw.cdf, args=params_powerlaw)

# ---------------------- 指数分布拟合与检验 ----------------------
params_exponential = expon.fit(data)
D_exponential, p_exponential = kstest(data, expon.cdf, args=params_exponential)

# ---------------------- 拉伸指数分布拟合与检验 ----------------------
# 定义拉伸指数的CDF函数
def stretched_exponential_cdf(x, lam, beta):
    return 1 - np.exp(-(x / lam)**beta)

# 初始参数猜测(lam取数据均值,beta初始设为1)
initial_guess = [np.mean(data), 1.0]
# 拟合参数,设置边界确保参数为正
params_stretched, _ = curve_fit(stretched_exponential_cdf, sorted_data, np.linspace(0, 1, len(sorted_data)), 
                                p0=initial_guess, bounds=((0, 0), (np.inf, np.inf)))
lam_fit, beta_fit = params_stretched

# 用KS检验验证拉伸指数拟合效果
D_stretched, p_stretched = kstest(data, stretched_exponential_cdf, args=(lam_fit, beta_fit))

# ---------------------- 结果输出 ----------------------
print('=== Kolmogorov-Smirnov检验统计量 ===')
print(f'幂律分布: {D_powerlaw:.4f}')
print(f'指数分布: {D_exponential:.4f}')
print(f'拉伸指数分布: {D_stretched:.4f}')

print('\n=== Kolmogorov-Smirnov检验p值 ===')
print(f'幂律分布: {p_powerlaw:.4f}')
print(f'指数分布: {p_exponential:.4f}')
print(f'拉伸指数分布: {p_stretched:.4f}')

print('\n=== 拟合参数 ===')
print(f'幂律分布alpha = {params_powerlaw[0]:.4f}')
print(f'指数分布loc = {params_exponential[0]:.4f}, scale = {params_exponential[1]:.4f}')
print(f'拉伸指数分布lambda = {lam_fit:.4f}, beta = {beta_fit:.4f}')

# 比较p值,p值越大说明拟合效果越好
p_values = {'幂律分布': p_powerlaw, '指数分布': p_exponential, '拉伸指数分布': p_stretched}
best_dist = max(p_values, key=p_values.get)
print(f'\n数据拟合效果最好的分布是: {best_dist}')

代码说明

  1. 自定义CDF函数:根据拉伸指数的数学定义实现累积分布函数,用于拟合和检验。
  2. 参数拟合:用curve_fit拟合参数,设置初始猜测和参数边界,避免出现非正的无效参数。
  3. KS检验:和前两个分布逻辑一致,用kstest对比数据的经验分布和拟合后的拉伸指数分布,得到检验统计量和p值。
  4. 结果比较:通过比较三个分布的p值,p值越大表示数据与该分布的拟合程度越高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:02:57