【问题标题】:python - curve_fit is seemingly unable to fit sum of gaussianspython - curve_fit 似乎无法拟合高斯的总和
【发布时间】:2015-09-26 17:40:52
【问题描述】:

这里我定义了一个函数来返回任意数量的高斯分布之和:

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

def GaussSum(x,*p):
    n=len(p)/3
    A=p[:n]
    w=p[n:2*n]
    c=p[2*n:3*n]
    return sum([ A[i]*exp(-(x-c[i])**2./(2.*(w[i])**2.))/(2*pi*w[i]**2)**0.5 for i in range(n)])

然后我继续为给定的一组参数生成 x 和 y 数据,并要求 curve_fit 使用与生成集匹配的初始参数来拟合该数据。我尝试了许多不同的集合,包括单个和多个高斯。

params = [1.,1.,-3.]; #parameters for a single gaussian
#params=[1.,1.,1.,2.,-3.,0.]; #parameters for the sum of two gaussians
xdata=arange(-6,6,0.01)
ydata = array([GaussSum(x,*params) for x in xdata])

popt,pcov = curve_fit(GaussSum,xdata,ydata,p0=params)

print popt
print pcov

每个参数集都给我一个不合适的结果,即使我已经在解决方案中开始了拟合。 (在上面的单高斯):

[    52.18242366   5549.66965192  15678.51803797]
inf

我知道函数本身运行正常,因为我已经用它绘制并验证了它的有效性。

【问题讨论】:

    标签: python scipy curve-fitting gaussian mixture-model


    【解决方案1】:

    这里的问题是,curve_fit 期望您正在优化的函数采用输入向量并返回输出向量。如所写,函数 GaussSum 采用单个输入或输入向量(即 numpy.array),但无论哪种方式,它都会返回单个标量输出。然后,curve_fit 函数无法找到良好的最佳拟合。

    为了弄清楚发生了什么,建议在使用 numpy(或任何外部库)时始终明确地使用命名空间,如下面的工作版本所示:

    import numpy
    import matplotlib.pyplot as plt
    from scipy.optimize import curve_fit
    
    def GaussSum(x,*p):
        n=len(p)/3
        A=p[:n]
        w=p[n:2*n]
        c=p[2*n:3*n]
        y = sum([ A[i]*numpy.exp(-(x-c[i])**2./(2.*(w[i])**2.))/(2*numpy.pi*w[i]**2)**0.5 for i in range(n)])
        return y
    
    params = [1.,1.,-3.]; #parameters for a single gaussian                                                                                                                        
    #params=[1.,1.,1.,2.,-3.,0.]; #parameters for the sum of two gaussians                                                                                                         
    xdata=numpy.arange(-6,6,0.01)
    ydata = numpy.array([GaussSum(x,*params) for x in xdata])
    
    popt,pcov = curve_fit(GaussSum,xdata,ydata,p0=params)
    

    具体来说,您隐式调用 numpy.sum,它将聚合 numpy.array 并返回单个值,而您需要使用内置的 python sum,它将 numpy.array 的本机列表聚合到一个 numpy.array。

    【讨论】:

    • 谢谢。这澄清了问题所在。但是有一项,工作代码需要在函数定义中返回而不是 y =。
    • 是的,对不起,是的,错过了代码中粘贴的一行
    猜你喜欢
    • 2018-03-29
    • 1970-01-01
    • 2015-04-08
    • 2013-10-12
    • 2020-06-08
    • 2019-02-12
    • 1970-01-01
    • 2017-08-30
    • 2016-11-29
    相关资源
    最近更新 更多