我有一个时间序列,我想使用Scipy.optimize.leastsq来适应。
fitfunc= lambda a, x: a[0]+a[1]*exp(-x/a[4])+a[2]*exp(-x/a[5])+a[3]*exp(-x /a[6])
errfunc lambda a,x,y: fitfunc(a,x) - y
接下来我会将errfunc传递给leastsq来最小化它。我使用的拟合函数是用不同时间尺度a(4:6)和不同权重(a(0:4))衰减的指数之和。 (作为一个副作用:我可以使用带有多个参数数组的minimalsq吗?我没有这样做....)
问题:如何在输入fit-function的参数上添加额外的条件。我想要例如sum(a(0:4))= 1.0
答案 0 :(得分:3)
只需使用
import numpy as np
def fitfunc(p, x):
a = np.zeros(7)
a[1:7] = p[:6]
a[0] = 1 - a[1:4].sum()
return a[0] + a[1]*exp(-x/a[4]) + a[2]*exp(-x/a[5]) + a[3]*exp(-x/a[6])
def errfunc(p, x, y1, y2):
return np.concatenate((
fitfunc(p[:6], x) - y1,
fitfunc(p[6:12], x) - y2
))
通常,lambda函数被认为是错误的样式(并且它们不会在代码中添加任何内容)。要在最小二乘拟合中使用多个函数,您可以使用np.concatenate附加我指示的函数。但是,如果没有任何参数相关,那就没有多大意义了。它只会减慢算法的收敛速度。您要求的侧面条件是通过根据您给出的约束计算一个权重来实现的(参见1 - a [1:4] .sum())。
答案 1 :(得分:0)
如果你不能为你的约束求解方程式,并且你可以忍受满足一些容差的约束,另一种可能性就是在具有大权重的卡方中添加一个术语,这保证了约束条件是几乎满意。
例如,如果您需要\ sum(sin(p [i])== 1,您可以执行以下操作:
constraint_func = lambda a: sin(a).sum()-1
def fitfunc (a,x):
np.concatenate((a[0]+a[1]*exp(-x/a[4])+a[2]*exp(-x/a[5])+a[3]*exp(-x /a[6]),
[constraint_func(a)]))
def errfunc(a,x,y):
tolerance = 1e-10
return np.concatenate((fitfunc(a,x) - y, [tolerance]))
显然收敛速度较慢,但仍有保证。