Python:最小二乘拟合拟合参数的边条件

时间:2012-03-12 14:44:22

标签: python numpy scipy

我有一个时间序列,我想使用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

2 个答案:

答案 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]))

显然收敛速度较慢,但​​仍有保证。

相关问题