使用lmfit最小化和基于似然法的ODE初始条件拟合

我正在使用一阶微分方程对病毒传播进行建模,并正在使用似然方法将ODE拟合到实验数据中。但是,无论何时运行代码,每次运行代码时ODE的拟合初始值都会更改,而模型中的所有其他参数每次都会收敛为相同的值。我的代码如下所示。

import numpy as np
from scipy.integrate import odeint
from lmfit import minimize,Parameters,Parameter,report_fit
import matplotlib.pyplot as plt
#====================================================================
''' Data on which the model will be fitted '''
TROMAS_DATA = [[3,3,1,7219,33],[3,2,7378,102],8978,66],4,8105,116],5,11941,70],[5,12349,214],8958,154,],10661,156],11924,305],9848,417],[7,8854,429],11098,886],12757,470],10233,594],8347,721],[10,8895,586],9554,999],11021,940],9416,917]]
#====================================================================
''' Parameter list '''
likeParams = Parameters()
likeParams.add('I0',value = .00372,min = .0000001,max = 1.0000)
likeParams.add('b',value = .871,min = .0001,max = 1.0000)
likeParams.add('psi3',value = .083,max = 1.0000)
#====================================================================
''' Initial conditions '''
I0 = [likeParams['I0'].value]
#====================================================================
''' Time axis '''
ZERO_DAYS_AXIS = [0,7,10]
DAYS_AXIS = [3,10]
t = np.linspace(0,10,10000)
#====================================================================
''' Define the model '''
def model(M3,t,parameters):

    try: # Get parameters
        b = parameters['b'].value
        psi3 = parameters['psi3'].value
    except KeyError:
        b,psi3 = parameters

    if (M3 < psi3):
        S3 = (1 - (M3 / psi3))
    else:
        S3 = 0

    dM3dt = b * M3 * S3

    return dM3dt
#====================================================================
''' Compute negative log likelihood of Tromas' data given the model '''
def negLogLike(parameters):
    # Solve ODE system to get model values; parameters are not yet fitted
    M3 = odeint(model,I0,ZERO_DAYS_AXIS,args=(parameters,))

    nll = 0
    epsilon = 10**-10
    for t in range(4):          # Iterate through days
        for p in range(5):      # Iterate through replicates
            Vktp = TROMAS_DATA[5 * t + p][4]          # Number of infected cells
            Aktp = TROMAS_DATA[5 * t + p][3] + Vktp   # Total number of cells observed
            Iktp = M3[t + 1]                          # Frequency of cellular infection

            if (Iktp <= 0):
                Iktp = epsilon
            elif (Iktp >= 1):
                Iktp = 1 - epsilon

            nll += Vktp * np.log(Iktp) + (Aktp - Vktp) * np.log(1 - Iktp)

    return -nll
#====================================================================
''' Miminize negative log likelihood with differential evolution algorithm '''
result_likelihood = minimize(negLogLike,likeParams,method = 'differential_evolution')
#====================================================================
''' Compare previous and fitted values '''
print("Original I0 = .00372,My I0   = ",result_likelihood.params['I0'].value)
print("Original beta = .871,My beta = ",result_likelihood.params['b'].value)
print("Original psi3 = .083,My psi3 = ",result_likelihood.params['psi3'].value)

为了帮助说明问题,下面显示了三个代码运行的输出。我也知道I0的“正确”值应大致在0.003左右。

第一次:

Original I0 = .00372,My I0   =  0.9711066426171252
Original beta = .871,My beta =  0.44374676021094367
Original psi3 = .083,My psi3 =  0.11330842894454747

第二次:

Original I0 = .00372,My I0   =  0.09183577426999114
Original beta = .871,My beta =  0.4437477735310379
Original psi3 = .083,My psi3 =  0.11330747932246728

第三次:

Original I0 = .00372,My I0   =  0.47857244584676956
Original beta = .871,My beta =  0.44374801498547956
Original psi3 = .083,My psi3 =  0.11330824660617532

如果您能帮助我学习如何正确地适应初始条件,我将不胜感激。 谢谢!

houxingyu555 回答:使用lmfit最小化和基于似然法的ODE初始条件拟合

您的模型对我来说有点困难。我想知道为什么要定义

I0 = [likeParams['I0'].value]

,然后在您的negLogLike函数中使用该值,并且在拟合模型中实际上不使用I0的变化值。也许应该是

 M3 = odeint(model,parameters['I0'].value,ZERO_DAYS_AXIS,args=(parameters,))

还是其他的变化?这似乎给出了更令人满意的结果。我用method='Nelder'进行了尝试,以获得:

Original I0 = .00372,My I0   =  0.0010018942980410726
Original beta = .871,My beta =  0.7074140684730617
Original psi3 = .083,My psi3 =  0.08807904093119709
本文链接:https://www.f2er.com/3005411.html

大家都在问