简体   繁体   English

Python:优化求解程序返回非线性回归问题的初始猜测

[英]Python: optimization solvers return initial guess for a nonlinear regression problem

Below is a code for the least-square fitting of parameters for an ODE. 以下是ODE参数最小二乘拟合的代码。 Python "minimize" as well as "least-square" functions have been used. 使用了Python的“最小化”和“最小二乘”功能。 Different methods and ODE solvers/steps have been tried (scipy ode/odeint). 已经尝试了不同的方法和ODE求解器/步骤(scipy ode / odeint)。 This is a problem that has been solved in MATLAB easily, but Python keeps returning the initial guess. 这个问题已经在MATLAB中轻松解决,但是Python不断返回初始猜测。 I hope you find a coding mistake or I would be disappointed by Python optimization functions. 我希望您发现编码错误,否则我会对Python优化功能感到失望。 Obj shows the objective (residual sum of squares) and ode function (firstorder) shows the equations with unknown parameters. Obj显示目标(残差平方和),而ode函数(一阶)显示参数未知的方程。 Data set is attached. 数据集已附加。

import numpy as np

from scipy.integrate import ode

from scipy.optimize import least_squares

from scipy.optimize import minimize

from scipy.optimize import SR1

import matplotlib.pyplot as plt

import math


Minput=np.loadtxt('C:\\Users\\Ladan\\Documents\\Python Scripts\\Python\\moisturesmoothopt.txt') 


Minput=Minput.flatten()

time=np.linspace(0,1800,901) 

A=np.zeros(3)

XC,RC,alpha=A

#bnds=([0,0,0],[Minput[0],math.inf,math.inf])

bnds=((0,Minput[0]),(0,math.inf),(0,math.inf))

def firstorder(X,time,A):


     if X>=XC:


        dX=-RC


     if X<XC:


        dX=-RC*(X/XC)**alpha

     return dX


def obj(A):


    X0=Minput[0]

   # Xpred=odeint(firstorder,X0,time,args=(A,))

    Xpred=ode(firstorder).set_integrator('vode', method='bdf', 
    order=15).set_initial_value(Minput[0],0).set_f_params(A)

    #Xpred=ode(firstorder).set_integrator('lsoda').set_initial_value(Minput[0],0).set_f_params(A)

    EPR=Xpred

    EPR2=EPR.y.flatten()

    ERRone=np.sum(np.power((EPR2-Minput),2))


    ERR=ERRone/((901-3))    # residual sum of squares deivided by dof


    return ERR


XC=1
RC=0.005
alpha=1.5

A0=[XC,RC,alpha]


Parameters=minimize(obj,A0,method='SLSQP',bounds=bnds,options={'ftol':1e-10, 
'maxiter': 1000}) 


print('parameters',Parameters)   

Data for Minput array is shared online: Minput数组的数据在线共享:

https://1drv.ms/t/s!AoVu1vtlAOiLasJxR7rzubDr8YE https://1drv.ms/t/s!AoVu1vtlAOiLasJxR7rzubDr8YE

Although I have used the newer ode solvers in scipy, I tend to favor the good ol' odeint function which is a bit older, but still pretty solid and in many cases gives better performance for reasons that I don't entirely understand. 尽管我在scipy中使用了较新的ode求解器,但我倾向于偏爱良好的odeint函数,该函数有些陈旧,但仍然相当可靠,并且由于我不完全理解的原因,在许多情况下可以提供更好的性能。 Anyway, I largely restructured your analysis code to use both scipy.optimize.least_squares and scipy.integrate.odeint . 无论如何,我在很大程度上重构了您的分析代码,以同时使用scipy.optimize.least_squaresscipy.integrate.odeint Progress is made but I do get some kind of warning about invalid values in the power. 已经取得了进展,但是我确实收到有关电源中无效值的某种警告。 You will have to investigate further, but this should get you on the right track 您将需要做进一步的调查,但这应该可以使您走上正确的道路

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint
from scipy.optimize import least_squares

Minput=np.loadtxt('Data.txt').T
time=np.linspace(0,1800,901)
bnds=([0,0,0],[Minput[0],np.inf,np.inf])


def firstorder(X,time, XC, RC, alpha):
     if X >= XC:
        dX = -RC
     else:
        dX = -RC * (X/XC)**alpha
     return dX

XC=1
RC=0.005
alpha=1.5
A0=(XC, RC, alpha) 


def residuals(x0):
    Mcalc = odeint(firstorder, y0=Minput[0], t=time, args=tuple(x0))[:,0]
    return Mcalc - Minput

Mcalc = odeint(firstorder, y0=Minput[0], t=time, args=A0)[:,0]
result = least_squares(residuals, x0=A0, bounds=bnds)
print(result)
Mfit = odeint(firstorder, y0=Minput[0], t=time, args=tuple(result.x))[:,0]

plt.plot(time, Minput, label='data')
plt.plot(time, Mcalc, label='initial values')
plt.plot(time, Mfit, label='fit')
plt.legend()

prints out: 打印出:

    /---/python3.6/site-packages/ipykernel_launcher.py:20: RuntimeWarning: invalid value encountered in power

 active_mask: array([0, 0, 0])
        cost: 50.571520689865935
         fun: array([ 0.00000000e+00,  8.14148814e-03,  1.61829763e-02,  2.44244644e-02,
        ...])
        grad: array([-1.18907831,         nan, -7.75389712])
         jac: array([[ 0.        ,  0.        ,  0.        ],
       [ 0.        , -2.        ,  0.        ],
       [ 0.        , -3.99999994,  0.        ],
       ...,
       [ 0.07146036,         nan,  0.1084222 ],
       [ 0.07130456,         nan,  0.10827456],
       [ 0.07114924,         nan,  0.1081272 ]])
     message: '`xtol` termination condition is satisfied.'
        nfev: 30
        njev: 12
  optimality: nan
      status: 3
     success: True
           x: array([1.0000002 , 0.00717926, 1.50000032])

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM