简体   繁体   English

指数拟合:optimize.curve_fit 和 stats.expon.fit 产生不同的结果

[英]Exponential Fit: optimize.curve_fit and stats.expon.fit produce different results

I am trying to fit histograms to an exponential distribution using two different methods based on the answers I have read here.我正在尝试根据我在此处阅读的答案使用两种不同的方法将直方图拟合到指数分布。 I am interested in obtaining the inverse of the scale parameter of the distribution.我有兴趣获得分布的尺度参数的倒数。

Following the answer given here ( Histogram fitting with python ), I use the fit method of the scipy.stats.expon distribution.按照此处给出的答案( 与 python 拟合的直方图),我使用scipy.stats.expon分布的fit方法。

import glob
import numpy as np
import scipy.stats as ss
import matplotlib.pyplot as plt
import seaborn as sns

fig, ax = plt.subplots(5, 1, sharex = True)
j = 0

for files in glob.glob("data_*"):

    time = []
    hist = []

    with open(files, 'r') as f:
         for line in f:
             line = line.split(' ')
             time.append(float(line[0]))
             H.append(float(line[1]))

    P  = ss.expon.fit(H, floc = 0)
    T  = np.linspace(0,200, 1000)
    rP = ss.expon.pdf(T, *P)

    ax[j].plot(T, rP, lw = 3.0)
    ax[j].hist(H,bins = 30, alpha = 0.6, label = r"$\lambda = $" + str(1/P[1]), density = True, stacked = True)
    ax[j].set_yticks([])
    ax[j].legend()

    j = j +1 

sns.despine(top = True, left = True, right = True)
plt.xlabel("Time")
plt.show()

By doing so, I obtain the following plot:通过这样做,我获得了以下 plot:

在此处输入图像描述

The fit looks nice, but I would like to know the uncertainty/error lambda value.合身看起来不错,但我想知道不确定性/错误 lambda 值。 There is no information about how to get this in the stats.expon documentation. stats.expon文档中没有关于如何获取此信息的信息。

This question has already been asked here ( Is there a way to get the error in fitting parameters from scipy.stats.norm.fit? ).这个问题已经在这里被问过( Is there a way to get the error infitting parameters from scipy.stats.norm.fit? )。 The accepted answer suggested using curve_fit to fit the histogram instead.接受的答案建议使用 curve_fit 来拟合直方图。 Therefore, following the tutorial here ( https://riptutorial.com/scipy/example/31081/fitting-a-function-to-data-from-a-histogram ), I tried using curve_fit.因此,按照这里的教程( https://riptutorial.com/scipy/example/31081/fitting-a-function-to-data-from-a-histogram ),我尝试使用curve_fit。 Here is the modified code (I have inserted these lines instead of using scipy.stats.expon):这是修改后的代码(我插入了这些行,而不是使用 scipy.stats.expon):


    def func(x, a):
        return a*np.exp(-a*x)

    bins = np.linspace(0, 200, 201)
    data_entries, bins = np.histogram(np.array(H), bins = bins)
    binscenters = np.array([0.5 * (bins[i] + bins[i + 1]) for i in range (len(bins)-1)])
    popt, pcov = curve_fit(func, xdata = binscenters, ydata = data_entries)

    ax[j].plot(T, func(T, *popt))
    ax[j].hist(H, bins = 30, alpha = 0.6, label = r"$\lambda = $" + str(popt[0]), density = True, stacked = True)

This fit produces results that are very different from stats.expon.fit , and that seem to (at least qualitatively) fit the data worse.这种拟合产生的结果与stats.expon.fit非常不同,并且似乎(至少在质量上)更适合数据。

在此处输入图像描述

Am I using curve_fit incorrectly?我是否错误地使用了curve_fit? I believe that in some limit, curve_fit and expon.fit should produce the same results.我相信在某些限制下, curve_fitexpon.fit应该会产生相同的结果。 Is there a way I could get the error in the estimated lambda from expon.fit?有没有办法可以从 expon.fit 得到估计的 lambda 中的错误? I am thinking of computing the relative error between the mean of the data and the lambda estimated from the initial fit, but I don't know if this would be correct.我正在考虑计算数据平均值与从初始拟合估计的 lambda 之间的相对误差,但我不知道这是否正确。 Any hint would be greatly appreciated.任何提示将不胜感激。

I managed to solve my problem.我设法解决了我的问题。 It turns out I am lacking density = True on numpy.histogram .事实证明我在numpy.histogram上缺少density = True

The function function

def func(x, a):
        return a*np.exp(-a*x)

is the exponential PDF.是指数 PDF。 Since my data was not normalized (therefore, not a PDF), the fit using curve_fit was incorrect.由于我的数据未标准化(因此不是 PDF),因此使用curve_fit的拟合不正确。 With this modification, both ss.expon.fit and curve_fit produce the same lambda value.通过此修改, ss.expon.fitcurve_fit都产生相同的 lambda 值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM