【问题标题】:Gaussian data fit varying depending on position of x data高斯数据拟合根据 x 数据的位置而变化
【发布时间】:2019-08-16 14:42:54
【问题描述】:

如果我将与该数据相对应的 x 值的间隔(xdata1 到 @987654326 @)。高斯写成:

其中 A 只是一个幅度因子。更改数据的一些值,很容易使其适用于两种情况,但也可以很容易地找到它不适用于xdata1 以及未估计参数协方差的情况。 我在 Windows 7 上使用带有 Python 3.7.1 的 Spyder 中的 scipy.optimize.curve_fit

import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

xdata1 = np.linspace(-9,4,20, endpoint=True) # works fine
xdata2 = xdata1+2
ydata = np.array([8,9,15,12,14,20,24,40,54,94,160,290,400,420,300,130,40,10,8,4])

def gaussian(x, amp, mean, sigma):
    return amp*np.exp(-(((x-mean)**2)/(2*sigma**2)))/(sigma*np.sqrt(2*np.pi))

popt1, pcov1 = curve_fit(gaussian, xdata1, ydata)
popt2, pcov2 = curve_fit(gaussian, xdata2, ydata)

fig, ([ax1, ax2]) = plt.subplots(nrows=1, ncols=2,figsize=(9, 4))

ax1.plot(xdata1, ydata, 'b+:', label='xdata1')
ax1.plot(xdata1, gaussian(xdata1, *popt1), 'r-', label='fit')
ax1.legend()
ax2.plot(xdata2, ydata, 'b+:', label='xdata2')
ax2.plot(xdata2, gaussian(xdata2, *popt2), 'r-', label='fit')
ax2.legend()

【问题讨论】:

    标签: python curve-fitting gaussian data-fitting


    【解决方案1】:

    问题是您第二次拟合高斯的尝试在搜索参数空间时陷入局部最小值:curve_fit 是 least_squares 的包装器,它使用梯度下降来最小化成本函数,这很可能会得到 @987654322 @。

    您应该尝试提供合理的起始参数(通过使用curve_fitp0 参数)来避免这种情况:

     #...  your code
    
     y_max = np.max(y_data)
     max_pos = ydata[ydata==y_max][0]
     initial_guess = [y_max, max_pos, 1] # amplitude, mean, std
    
     popt2, pcov2 = curve_fit(gaussian, xdata2, ydata, p0=initial_guess)
    

    如您所见,这提供了合理的拟合:

    您应该编写一个可以提供对起始参数的合理估计的函数。在这里,我刚刚找到了最大 y 值,并用它来确定初始参数。我发现这适用于拟合正态分布,但您可以考虑其他方法。

    编辑:

    你也可以通过缩放幅度来解决这个问题:幅度太大,参数空间被扭曲,梯度下降只是遵循幅度变化最大的方向,有效地忽略了 sigma。考虑以下参数空间中的图(颜色是给定参数的拟合残差平方和,白色十字表示最优解):

    请务必记下 x 轴和 y 轴的不同比例。

    需要在 y(幅度)中进行大量“单位”大小的步长,以从点 x,y = (0,0) 达到最小值,因为您只需要不到一个“单位”步长以达到 x (sigma) 的最小值。该算法只是在幅度上采取步骤,因为这是最陡的梯度。当它达到使成本函数最小化的幅度时,它会简单地停止算法,因为它似乎已经收敛并且对 sigma 参数几乎没有变化。

    解决此问题的一种方法是缩放您的 ydata 以不扭曲参数空间:将您的 ydata 除以 100,您将看到您的适合在不提供任何起始参数的情况下工作!

    【讨论】:

    • 可能更好的方法是在拟合数据之前对其进行归一化,即重新缩放它以使其均值和单位方差为零。事实上,如果您知道您的数据是正态分布的,并且已经提供了您正在寻找的参数。
    • 您可以计算这些起始参数(即计算方差和均值并将它们用作您的p0),我认为这会产生相同的结果吗?有没有理由会表现得更好?我在这里介绍的方法的优点是您不需要转换数据。
    • 好吧,事实上,如果您的数据点是从正态分布中采样的,那么样本均值和方差是潜在分布均值和方差的最大似然估计量,即它们提供了最优这个参数的估计。如果数据不是从正态分布中采样的,这当然是不正确的,所以你对不对称有一个公平的观点。
    • 当然,我同意,但我认为这不是重点。我认为 OP 不一定说那里的数据是从正态分布中采样的。看起来那里的数据可能来自实验。我建议您将这些 cmets 构建为答案,以防有人从正态分布中采样,因为这是一个很好的讨论。我会留下我的答案:它很笼统,您可以测试您的数据是否符合正态分布的假设,如果不容易适合另一个函数。
    • 感谢您提供初步猜测并强调curve_fit 工作原理的建议,@FChm,这确实是解决拟合问题的好方法。还要感谢 cmets,@FChm,@user1587520,数据不是从正态分布中采样的。
    猜你喜欢
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多