【发布时间】:2015-10-20 17:19:36
【问题描述】:
我正在使用scipy.optimize.curve_fit 用高斯函数来近似我的数据中的峰值。这适用于强峰,但较弱的峰更难。但是,我认为修复一个参数(例如,高斯的宽度)会对此有所帮助。我知道我可以设置初始“估计值”,但有没有一种方法可以轻松定义单个参数而不更改我适合的函数?
【问题讨论】:
标签: python numpy scipy curve-fitting
我正在使用scipy.optimize.curve_fit 用高斯函数来近似我的数据中的峰值。这适用于强峰,但较弱的峰更难。但是,我认为修复一个参数(例如,高斯的宽度)会对此有所帮助。我知道我可以设置初始“估计值”,但有没有一种方法可以轻松定义单个参数而不更改我适合的函数?
【问题讨论】:
标签: python numpy scipy curve-fitting
希望这会有所帮助。不得不使用hax。 Curve_fit 对它的要求非常严格。
import numpy as np
from numpy import random
import scipy as sp
from scipy.optimize import curve_fit
import matplotlib.pyplot as pl
def exp1(t,a1,tau1):
#A1*exp(-t/t1)
val=0.
val=(a1*np.exp(-t/tau1))*np.heaviside(t,0)
return val
def wrapper(t,*args):
global hold
global p0
wrapperName='exp1(t,'
for i in range(0, len(hold)):
if hold[i]:
wrapperName+=str(p0[i])
else:
if i%2==0:
wrapperName+='args['+str(i)+']'
else:
wrapperName+='args'+str(i)+']'
if i<len(hold):
wrapperName+=','
wrapperName+=')'
return eval(wrapperName)
p0=np.array([1.5,500.])
hold=np.array([0,1])
p1=np.delete(p0,1)
timepoints = np.arange(0.,2000.,20.)
y=exp1(timepoints,1,1000)+np.random.normal(0, .1, size=len(timepoints))
popt, pcov = curve_fit(exp1, timepoints, y, p0=p0)
print 'unheld parameters:', popt, pcov
popt, pcov = curve_fit(wrapper, timepoints, y, p0=p1)
for i in range(0, len(hold)):
if hold[i]:
popt=np.insert(popt,i,p0[i])
yfit=exp1(timepoints,popt[0],popt[1])
pl.plot(timepoints,y,timepoints,yfit)
pl.show()
print 'hold parameters:', popt, pcov
【讨论】:
如果你想“修复”你的 fit 函数的一个参数,你可以定义一个新的 fit 函数,它利用原来的 fit 函数,但将一个参数设置为一个固定值:
custom_gaussian = lambda x, mu: gaussian(x, mu, 0.05)
这是将Gaussian function 的sigma 修复为0.05(而不是最佳值0.1)的完整示例。当然,这在这里没有任何意义,因为算法在找到最优值方面没有问题。然而,尽管sigma 是固定的,您仍然可以看到mu 仍然存在。
import matplotlib.pyplot as plt
import numpy as np
import scipy.optimize
def gaussian(x, mu, sigma):
return 1 / sigma / np.sqrt(2 * np.pi) * np.exp(-(x - mu)**2 / 2 / sigma**2)
# Create sample data
x = np.linspace(0, 2, 200)
y = gaussian(x, 1, 0.1) + np.random.rand(*x.shape) - 0.5
plt.plot(x, y, label="sample data")
# Fit with original fit function
popt, _ = scipy.optimize.curve_fit(gaussian, x, y)
plt.plot(x, gaussian(x, *popt), label="gaussian")
# Fit with custom fit function with fixed `sigma`
custom_gaussian = lambda x, mu: gaussian(x, mu, 0.05)
popt, _ = scipy.optimize.curve_fit(custom_gaussian, x, y)
plt.plot(x, custom_gaussian(x, *popt), label="custom_gaussian")
plt.legend()
plt.show()
【讨论】: