评估分布拟合的优度

Evaluate the goodness of a distributional fits

我使用以下代码为示例数据拟合了一些分布:

import numpy as np 
import pylab
import matplotlib.pyplot as plt
from scipy.stats import norm

samp = norm.rvs(loc=0,scale=1,size=150) # (example) sample values. 

figprops = dict(figsize=(8., 7. / 1.618), dpi=128)                       
adjustprops = dict(left=0.1, bottom=0.1, right=0.97, top=0.93, wspace=0.2, hspace=0.2)

import pylab
fig = pylab.figure(**figprops)                                            
fig.subplots_adjust(**adjustprops)
ax = fig.add_subplot(1, 1, 1)  
ax.hist(samp,bins=10,density=True,alpha=0.6,color='grey', label='Data')
xmin, xmax = plt.xlim()

# Distributions. 
import scipy.stats
dist_names = ['beta', 'norm','gumbel_l'] 
for dist_name in dist_names:
    dist = getattr(scipy.stats, dist_name)
    param = dist.fit(samp)
    x = np.linspace(xmin, xmax, 100) # 
    ax.plot(x,dist(*param).pdf(x),linewidth=4,label=dist_name)

ax.legend(fontsize=14)
plt.savefig('example.png')

如何自动对图例中的分布名称从最适合(顶部)到最不适合进行排序?我在循环中生成了随机变量,每次迭代的最佳拟合结果可能不同。

嗯,您可以使用 Kolmogorov-Smirnov (K-S) 检验来计算,f.e,p 值并按它排序

修改循环

for dist_name in dist_names:
    dist = getattr(scipy.stats, dist_name)
    param = dist.fit(samp)
    x = np.linspace(xmin, xmax, 100) # 
    ax.plot(x,dist(*param).pdf(x),linewidth=4,label=dist_name)

    ks = scipy.stats.kstest(samp, dist_name, args=param)
    print((dist_name, ks))

你可以得到类似

的输出
('beta', KstestResult(statistic=0.033975289251035434, pvalue=0.9951529119440156))
('norm', KstestResult(statistic=0.03164417055025992, pvalue=0.9982475331007705))
('gumbel_l', KstestResult(statistic=0.113229070386386, pvalue=0.039394595923043355))

这告诉你普通版和测试版都不错,但 gumbel 应该排在最后。基于 P 值或统计数据的排序应该很容易添加

您的结果可能会有所不同,这取决于 RNG 初始状态。

更新

关于 K-S 检验对拟合优度估计的不适用性,我强烈反对。我没有看到不使用它的科学理由,我自己一直在使用它。

通常,您有黑匣子生成随机数据,比方说网络延迟的一些测量值

一般来说,它可以用 Gammas 的混合来描述,你可以使用某种二次效用函数进行拟合并取回参数集

然后您使用 K-S 或任何其他经验与理论分布方法来估计拟合的好坏程度。如果不使用K-S方法拟合,那么使用K-S是非常好的方法。

您基本上有一个黑盒生成数据,另一个黑盒拟合数据,并且想知道拟合数据的拟合程度。然后K-S就可以完成工作了。

并且声明 "it is commonly used as a test for normality to see if your data is normally distributed." 是完全错误的,以我的拙见。 K-S是关于CDF-vs-CDF最大差异的,它不关心正态性,它更通用