Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 曲线拟合仍有问题_Python_Curve Fitting_Lmfit - Fatal编程技术网

Python 曲线拟合仍有问题

Python 曲线拟合仍有问题,python,curve-fitting,lmfit,Python,Curve Fitting,Lmfit,我已经打开了一个,但我不确定,如果我应该张贴在那里,所以我在这里打开了一个新的问题 我在拟合两个或多个峰值时再次遇到问题。第一个问题发生在计算的示例函数中 xg = np.random.uniform(0,1000,500) mu1 = 200 sigma1 = 20 I1 = -2 mu2 = 800 sigma2 = 20 I2 = -1 yg3 = 0.0001*xg yg1 = (I1 / (sigma1 * np.sqrt(2 * np.pi))) * np.exp( - (xg

我已经打开了一个,但我不确定,如果我应该张贴在那里,所以我在这里打开了一个新的问题

我在拟合两个或多个峰值时再次遇到问题。第一个问题发生在计算的示例函数中

xg = np.random.uniform(0,1000,500)
mu1 = 200
sigma1 = 20
I1 = -2

mu2 = 800
sigma2 = 20
I2 = -1

yg3 = 0.0001*xg
yg1 = (I1 / (sigma1 * np.sqrt(2 * np.pi))) * np.exp( - (xg - mu1)**2 / (2 * sigma1**2) )
yg2 = (I2 / (sigma2 * np.sqrt(2 * np.pi))) * np.exp( - (xg - mu2)**2 / (2 * sigma2**2) )
yg=yg1+yg2+yg3

plt.figure(0, figsize=(8,8))
plt.plot(xg, yg, 'r.')
我在文档中找到了两种不同的方法,如下所示(针对我的数据进行了修改),但这两种方法都给了我错误的拟合数据和混乱的图形(我猜每个拟合步骤一行)

第一次尝试:

import numpy as np
from lmfit.models import PseudoVoigtModel, LinearModel, GaussianModel, LorentzianModel
import sys
import matplotlib.pyplot as plt

gauss1 = PseudoVoigtModel(prefix='g1_')
pars.update(gauss1.make_params())

pars['g1_center'].set(200)
pars['g1_sigma'].set(15, min=3)
pars['g1_amplitude'].set(-0.5)
pars['g1_fwhm'].set(20, vary=True)
#pars['g1_fraction'].set(0, vary=True)

gauss2  = PseudoVoigtModel(prefix='g2_')
pars.update(gauss2.make_params())

pars['g2_center'].set(800)
pars['g2_sigma'].set(15)
pars['g2_amplitude'].set(-0.4)
pars['g2_fwhm'].set(20, vary=True)
#pars['g2_fraction'].set(0, vary=True)

mod = gauss1 + gauss2 + LinearModel()

pars.add('intercept', value=0, vary=True)
pars.add('slope', value=0.0001, vary=True)

init = mod.eval(pars, x=xg)
out = mod.fit(yg, pars, x=xg)

print(out.fit_report(min_correl=0.5))
plt.figure(5, figsize=(8,8))
out.plot_fit()
pars['g1_fraction'].set(0, vary=True)
当我包含“分数”参数时,我经常得到

'NameError: name 'pv1_fraction' is not defined in expr='<_ast.Module object at 0x00000000165E03C8>'.
在这两种情况下,结果都是这样的。它似乎绘制了所有拟合尝试,但从未正确地解决它。最佳拟合参数在我给出的范围内


有人知道这种错误吗?或者有什么解决办法?有人知道如何避免在使用这些方法从
lmfit
调用模型函数时出现
namererror
吗?

我有一个可以容忍的解决方案。因为我不知道你们的数据有多大的变化,我不能说它在一般意义上是有效的,但应该让你们开始。如果您的数据是沿着0-1000的,并且如您所示,沿着一条线有两个峰值或凹陷,那么它应该可以工作

我使用了scipy曲线拟合,并将函数的所有组件放在一个函数中。可以将起始位置传递到曲线拟合函数中。(你可能可以用你正在使用的lib来实现这一点,但我不熟悉它)有一个循环中的循环,我改变mu参数以找到平方误差最小的参数。如果您需要多次或在某些实时场景中调整数据,那么这并不适合您,但如果您只需要调整一些数据,请启动此代码并喝杯咖啡

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

def my_function_big(x, m, n, #lin vars
                       sigma1, mu1, I1,  #gaussian 1
                       sigma2, mu2, I2):  #gaussian 2

  y = m * x + n + (I1 / (sigma1 * np.sqrt(2 * np.pi))) * np.exp( - (x - mu1)**2 / (2 * sigma1**2) ) + (I2 / (sigma2 * np.sqrt(2 * np.pi))) * np.exp( - (x - mu2)**2 / (2 * sigma2**2) )
  return y


#make some data
xs = np.random.uniform(0,1000,500)
mu1 = 200
sigma1 = 20
I1 = -2

mu2 = 800
sigma2 = 20
I2 = -1

yg3 = 0.0001 * xs
yg1 = (I1 / (sigma1 * np.sqrt(2 * np.pi))) * np.exp( - (xs - mu1)**2 / (2 * sigma1**2) )
yg2 = (I2 / (sigma2 * np.sqrt(2 * np.pi))) * np.exp( - (xs - mu2)**2 / (2 * sigma2**2) )
ys = yg1 + yg2 + yg3

xs = np.array(xs)
ys = np.array(ys)

#done making data



#start a double loop...very expensive but this is quick and dirty
#it would seem that the regular optimizer has trouble finding the minima so i 
#found that having the near proper mu values helped it zero in much better

start = time.time()

serr = []
_x = []
_y = []
for x in np.linspace(0, 1000, 61):
  for y in np.linspace(0, 1000, 61):
    cfiti = curve_fit(my_function_big, xs, ys, p0=[0, 0, 1, x, 1, 1, y, 1], maxfev=20000000)
    serr.append(np.sum((my_function_big(xs, *cfiti[0]) - ys) ** 2))
    _x.append(x)
    _y.append(y)

serr = np.array(serr)
_x = np.array(_x)
_y = np.array(_y)

print 'done loop in loop fitting'
print 'time: %0.1f' % (time.time() - start)

gridsize=20
plt.subplot(111)
plt.hexbin(_x, _y, C=serr, gridsize=gridsize, cmap=cm.jet, bins=None)
plt.axis([_x.min(), _x.max(), _y.min(), _y.max()])
cb = plt.colorbar()
cb.set_label('SE')
plt.show()   

ix = np.argmin(serr.ravel())
mustart1 = _x.ravel()[ix]
mustart2 = _y.ravel()[ix]
print mustart1
print mustart2

cfit = curve_fit(my_function_big, xs, ys, p0=[0, 0, 1, mustart1, 1, 1, mustart2, 1], maxfev=2000000000)

xp = np.linspace(0, 1000, 1001)

plt.figure()
plt.scatter(xs, ys) #plot synthetic dat
plt.plot(xp, my_function_big(xp, *cfit[0]), '-', label='fit function')  #plot data evaluated along 0-1000
plt.legend(loc=3, numpoints=1, prop={'size':12})
plt.show()    
pylab.close()

祝你好运

第一次尝试时:

import numpy as np
from lmfit.models import PseudoVoigtModel, LinearModel, GaussianModel, LorentzianModel
import sys
import matplotlib.pyplot as plt

gauss1 = PseudoVoigtModel(prefix='g1_')
pars.update(gauss1.make_params())

pars['g1_center'].set(200)
pars['g1_sigma'].set(15, min=3)
pars['g1_amplitude'].set(-0.5)
pars['g1_fwhm'].set(20, vary=True)
#pars['g1_fraction'].set(0, vary=True)

gauss2  = PseudoVoigtModel(prefix='g2_')
pars.update(gauss2.make_params())

pars['g2_center'].set(800)
pars['g2_sigma'].set(15)
pars['g2_amplitude'].set(-0.4)
pars['g2_fwhm'].set(20, vary=True)
#pars['g2_fraction'].set(0, vary=True)

mod = gauss1 + gauss2 + LinearModel()

pars.add('intercept', value=0, vary=True)
pars.add('slope', value=0.0001, vary=True)

init = mod.eval(pars, x=xg)
out = mod.fit(yg, pars, x=xg)

print(out.fit_report(min_correl=0.5))
plt.figure(5, figsize=(8,8))
out.plot_fit()
pars['g1_fraction'].set(0, vary=True)

分数必须是介于0和1之间的值,但我相信它不能是零。尝试输入0.000001之类的值,它就会起作用。

嘿,你能复制/粘贴你的数据值吗?(逗号分隔)我喜欢这个问题,我可能有个想法想试试。没关系!你创造了数据…明白了!找到这个网站。也许这会有帮助。你确定拟合有问题,而不仅仅是数据的显示有问题吗?不显示参数的拟合结果,只显示数据、初始拟合和最终拟合的曲线图。从图中可以清楚地看出,拟合函数发生了变化。不幸的是,您会在绘图中看到许多伪线,因为您使用点绘制数据,而使用线拟合数据。根据您对
xg=np.random.uniform(01000500)
的定义,
xg
将不会单调增加,这样的绘图瑕疵是不可避免的。不幸的是,我无法显示拟合数据,因为没有。我收到的所有参数都是零。所以我还是觉得合身有问题。我不明白你对示例数据的看法。它们在某种程度上是非常真实的,因为它模拟了一个实验,在这个实验中,每个x数据点测量一个y数据点(它以一定的步长扫描整个范围)。所以在实验中,我会得到一个x的数组,它看起来类似于这个示例数据。