将理论分布拟合到具有 scipy 统计数据的抽样经验 CDF

Fitting a theoretical distribution to a sampled empirical CDF with scipy stats

我有一个数据包丢失的 CDF 分布图。因此,我没有原始数据或 CDF 模型本身,而是来自 CDF 曲线的样本。 (数据摘自文献中发表的图表。)

我想找到哪个分布和哪些参数提供最接近 CDF 样本的拟合。

我看到 Scipy 统计分布提供 fit(data) 方法,但所有示例都适用于原始数据点。 PDF/CDF 随后从拟合参数中得出。对我的 CDF 样本使用拟合不会给出合理的结果。

我假设 fit() 不能直接应用于经验 CDF 的数据样本是否正确?

我可以使用哪些替代方法来找到匹配的已知分布?

我不确定你到底想做什么。当您说您有 CDF 时,那是什么意思?你有一些数据点,还是函数本身?如果您能 post 更多信息或一些示例数据,将会很有帮助。

如果您有一些数据点并且知道分布,那么使用 scipy 并不难。如果您不知道分布,您可以遍历所有分布,直到找到一个运行良好的分布。

我们可以定义scipy.optimize.curve_fit所需形式的函数。即第一个参数应该是x,然后其他参数是参数

我使用此函数生成了一些基于正常随机变量的 CDF 的测试数据,其中添加了一些噪声。

n = 100
x = np.linspace(-4,4,n)
f = lambda x,mu,sigma: scipy.stats.norm(mu,sigma).cdf(x)

data = f(x,0.2,1) + 0.05*np.random.randn(n)

现在,使用curve_fit查找参数。

mu,sigma = scipy.optimize.curve_fit(f,x,data)[0]

这给出了输出

>> mu,sigma
0.1828320963531838, 0.9452044983927278

我们可以绘制原始 CDF(橙色)、噪声数据和拟合 CDF(蓝色)并观察其运行良好。

请注意,curve_fit 可以采用一些额外的参数,并且输出会提供有关函数拟合程度的额外信息。

@tch 谢谢你的回答。我阅读了该技术并成功应用了它。我想将拟合应用于 scipy.stats 支持的所有连续分布,所以我最终执行了以下操作:

fitted = []
failed = []

for d in dist_list:

    dist_name = d[0] #fetch the distribution name
    dist_object = getattr(ss, dist_name) #fetch the distribution object
    param_default = d[1] #fetch the default distribution parameters

    # For distributions with only location and scale set those to the default loc=0 and scale=1
    if not param_default:
        param_default = (0,1)

    # Computed parameters of fitted distribution
    try:
        param,cov = curve_fit(dist_object.cdf,data_in,data_out,p0=param_default,method='trf')

        # Only take distributions which do not result in zero covariance as those are not a valid fit
        if np.any(cov):
            fitted.append((dist_name,param),)

    # Capture which distributions are not possible to be fitted (variety of reasons)       
    except (NotImplementedError,RuntimeError) as e:
        failed.append((dist_name,e),)
        pass

在上面,经验 cdf 分布在 data_out 中捕获,其中包含 data_in 数据点范围内的采样 cdf 值。列表 dist_listscipy.stats.rv_continuous 中的每个分布保留分布名称作为第一个元素,默认参数列表作为第二个元素。我从 scipy.stats._distr_params 中提取的默认参数。

某些分布无法拟合并引发错误。我保留那些 failed 列表。

最后,我生成了一个列表 fitted,其中包含每个成功拟合分布的估计参数。