python - curve_fit似乎无法适应高斯之和

时间:2015-07-08 16:56:30

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

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

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

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

1 个答案:

答案 0 :(得分:2)

这里的问题是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总和,它将numpy.array的本机列表聚合为一个numpy.array。