Python 最小二乘拟合的传递雅可比矩阵

Python 最小二乘拟合的传递雅可比矩阵,python,mathematical-optimization,lmfit,Python,Mathematical Optimization,Lmfit,我正在使用lmfit python包进行非线性优化(url:)。我想知道,当使用最小二乘拟合方法时,是否可以传递雅可比函数?如果是的话,能不能给我举个简单的例子 谢谢大家!! 卡布拉普 注:代码如下: # f(t,g,p) = dg_dt(t,g,p) = R*(c^h/(c^h+K^h))-l*g # returns rhs of an ODE (dg_dt) def hill_1g1c(t, g_in, p_in): R = p_in['R'].value K = p_in[

我正在使用lmfit python包进行非线性优化(url:)。我想知道,当使用最小二乘拟合方法时,是否可以传递雅可比函数?如果是的话,能不能给我举个简单的例子

谢谢大家!! 卡布拉普

注:代码如下:

# f(t,g,p) = dg_dt(t,g,p) = R*(c^h/(c^h+K^h))-l*g
# returns rhs of an ODE (dg_dt)
def hill_1g1c(t, g_in, p_in):
    R = p_in['R'].value
    K = p_in['K'].value
    h = p_in['h'].value
    l = p_in['l'].value

    dg_dt = R*((c_int(t)**h)/((c_int(t)**h)+(K**h))) - l*g_in
    return dg_dt

# f_deriv(t,g,p)
# is intended to return the derivatives of f with respect to 4 parameter
def hill_1g1c_jac(p_in, y_in, dt, t_max, g_data, g_err):
    t=1
    R = p_in['R'].value
    K = p_in['K'].value
    h = p_in['h'].value
    l = p_in['l'].value
    dg_dR = (c_int(t)**h) / (c_int(t)**h + K**h) - l * 1
    dg_dK = (-1 * R * c_int(t)**h * h * k**(h-1)) / ((c_int(t)**h + K**h)**2) - l * 1
    dg_dh = (-1 * R * c_int(t)**h * k**h * (np.log(k) - np.log(c_int(t)))) / ((c_int(t)**h + K**h)**2) - l * 1
    dg_dl = -y_in - l * 1

    return np.array([dg_dR, dg_dK, dg_dh, dg_dl])

# y = ODE_solve(y0,p,dt, t_max) >>>> wrapper around ode.integrate, returns array of g
def ODE_solve(y0, p_in, dt, t_max):
    t = [0]
    y = [y0]
    r.set_initial_value(y0, t=0.0)
    r.set_f_params(p_in)
    while r.successful() and r.t < t_max:
         r.integrate(r.t+dt)
         t.append(r.t)
         y.append(r.y)
    return np.array(y)

# weighted least squares, objective function to be minimised
def ODE_wres(p_in, y0, dt, t_max, g_data, g_err):
    g_extended = ODE_solve(y0, p_in, dt, t_max)
    g_model = g_extended[-25:]/g_extended[-25]
    weighted_residuals = (g_data - g_model)/(g_err + 0.00000001)
    return weighted_residuals


# specs for inegrate.ode
y0 = 1
t0 = 0
r = integrate.ode(hill_1g1c).set_integrator('vode', with_jacobian=False)
t_stim = 15
t_max = t_stim + 24
t_plus = 5
dt = 1
t_extended = np.linspace(0,t_max+t_plus,t_max+t_plus+1)

# set history of all inputs to 1
c_history = [1 for val in range(t_stim)]

# data (is read in from text file)
g_data = Y_data[:,i]
# error in g
g_err = Y_error[:,i]
# input c
c_data = Y_data[:,k]
# interpolation of c, contains history (=1) and future (=endval)
c_future = [c_data[-1] for val in range(t_plus)]
c_extended = np.hstack((c_history, c_data, c_future))
c_int = interp1d(t_extended, c_extended, kind='linear')

# initial parameter vector
R_ini = random.uniform(0.01, 500.0)
K_ini = random.uniform(0.01, 20.0)
h_ini = random.uniform(-4.0, 4.0)
l_ini = random.uniform(0.07, 7.0)

p_ini = Parameters()
p_ini.add('R', value= R_ini, min=0.01, max=500)
p_ini.add('K', value= K_ini, min=0.01, max=20)
p_ini.add('h', value= h_ini, min=-4, max=4)
p_ini.add('l', value= l_ini, min=0.07, max=7.0)

res_ini = ODE_wres(p_ini, y0, dt, t_max, g_data, g_err)
chisqr_ini = np.sum(res_ini**2)

# optimise
lmsol = Minimizer(ODE_wres, p_ini, fcn_args=(y0, dt, t_max, g_data, g_err))
lmsol.leastsq(Dfun=hill_1g1c_jac, col_deriv=True)
#f(t,g,p)=dg#dt(t,g,p)=R*(c^h/(c^h+K^h))-l*g
#返回ODE的rhs(dg_dt)
def hill_1g1c(t、g_-in、p_-in):
R=p_,单位为['R']。数值
K=p_,单位为['K']。值
h=p_in['h']。值
l=p_,单位为['l']。数值
dg_dt=R*((c_int(t)**h)/((c_int(t)**h)+(K**h))-l*g_in
返回dg_dt
#f_deriv(t,g,p)
#用于返回f相对于4参数的导数
def hill_1g1c_jac(p_in,y_in,dt,t_max,g_data,g_err):
t=1
R=p_,单位为['R']。数值
K=p_,单位为['K']。值
h=p_in['h']。值
l=p_,单位为['l']。数值
dg_dR=(c_int(t)**h)/(c_int(t)**h+K**h)-l*1
dg_dK=(-1*R*c_int(t)**h*h*k**(h-1))/((c_int(t)**h+k**h)**2)-l*1
dg_dh=(-1*R*c_int(t)**h*k**h*(np.log(k)-np.log(c_int(t)**h+k**h)**2)-l*1
dg_dl=-y_in-l*1
返回np.数组([dg_-dR,dg_-dK,dg_-dh,dg_-dl])
#y=ODE_solve(y0,p,dt,t_max)>>>>>围绕ODE.integrate的包装器,返回g的数组
def ODE_solve(y0,p_in,dt,t_max):
t=[0]
y=[y0]
r、 设置初始值(y0,t=0.0)
r、 设置参数(p_in)
当r.successful()和r.t
p.p.S:我在github找到了这个有价值的例子:


注意:在成功地将雅可比函数传递给lmft.leastsq之后,我意识到,在我的测试用例中,lmfit返回的优化解不再收敛于真实解。然而,当使用实际的scipy.optimize.leastq函数(由lmfit调用)时,一切正常,即返回的解也收敛,包括要拟合的雅可比矩阵。我并不是说lmfit.leastsq在提供雅可比函数时不能正常工作,但我建议谨慎处理这种情况。到目前为止,我还没有找到时间深入研究这一问题的原因。

您可以将一个函数作为
Dfun
参数传递给
最小值。leastsq
方法:


默认情况下,传递给
Dfun
的函数应该返回一个数组,该数组的行数与参数的行数相同,并且每一行都是与所拟合的每个参数相关的导数。确保使用对象指定参数,以便以正确的顺序处理参数。我相信这是必要的IIRC,尽管它可能并不重要。

谢谢您的快速回答。我有两个后续问题:1)是否可以将一组不同的参数传递给雅可比函数而不是残差函数?2) 是否可以访问雅可比函数的当前值(如y_dx)并将其传递给雅可比函数?此外,我还得到一个错误“TypeError:leastsq:‘Dfun’参数‘u_jacobian’的输入和输出形状不匹配。”返回的雅可比矩阵的形状与您指定的参数类中的参数数量相符
col_deriv=True
。只有在派生函数是面向列而不是面向行的情况下才应使用此选项。感谢您的评论,我尝试了这两种方法并收到了相同的错误消息我找到了错误消息的原因:我只返回了一个形状数组(m,1),m是参数数。正确的形状当然应该是(m,n),其中n是计算目标函数的数据点的数量。