我在做什么:我修改了僵尸入侵系统中的代码,以演示应如何编写并尝试使用fmin函数优化最小二乘误差(定义为得分函数)。
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from scipy import integrate
from scipy.optimize import fmin
#=====================================================
#Notice we must import the Model Definition
from zombiewithdata import eq
#=====================================================
#1.Get Data
#====================================================
Td=np.array([0.5,1,1.5,2,2.2,3,3.5,4,4.5,5])#time
Zd=np.array([0,2,2,5,2,10,15,50,250,400])#zombie pop
#====================================================
#2.Set up Info for Model System
#===================================================
# model parameters
#----------------------------------------------------
P = 0 # birth rate
d = 0.0001 # natural death percent (per day)
B = 0.0095 # transmission percent (per day)
G = 0.0001 # resurect percent (per day)
A = 0.0001 # destroy perecent (per day)
rates=(P,d,B,G,A)
# model initial conditions
#---------------------------------------------------
S0 = 500. # initial population
Z0 = 0 # initial zombie population
R0 = 0 # initial death population
y0 = [S0, Z0, R0] # initial condition vector
# model steps
#---------------------------------------------------
start_time=0.0
end_time=5.0
intervals=1000
mt=np.linspace(start_time,end_time,intervals)
# model index to compare to data
#----------------------------------------------------
findindex=lambda x:np.where(mt>=x)[0][0]
mindex=map(findindex,Td)
#=======================================================
#3.Score Fit of System
#=========================================================
def score(parms):
#a.Get Solution to system
F0,F1,F2,T=eq(parms,y0,start_time,end_time,intervals)
#b.Pick of Model Points to Compare
Zm=F1[mindex]
#c.Score Difference between model and data points
ss=lambda data,model:((data-model)**2).sum()
return ss(Zd,Zm)
#========================================================
#4.Optimize Fit
#=======================================================
fit_score=score(rates)
answ=fmin(score,(rates),full_output=1,maxiter=1000000)
bestrates=answ[0]
bestscore=answ[1]
P,d,B,G,A=answ[0]
newrates=(P,d,B,G,A)
#=======================================================
#5.Generate Solution to System
#=======================================================
F0,F1,F2,T=eq(newrates,y0,start_time,end_time,intervals)
Zm=F1[mindex]
Tm=T[mindex]
#======================================================
现在在#optimize fit部分中,当我限制lb <= P,d,B,G,A <= ub等lb的“ rates”值时,有什么方法可以获得最佳的bestrates值。 =下限和ub =上限,并设法在该限制区域中获得最低分?它不一定是最优化的值。 fmin使用Nelder-Mead(简单)算法。
我对此很陌生,所以在正确方向上的任何帮助都会很棒。如有任何疑问,请随时提出疑问,我将尽我所能回答。 。谢谢。
答案 0 :(得分:0)
我不确定Adventures in Python : Fitting a Differential Equation System to Data的原始作者为什么会跳过箍以获取与给定数据点相对应的样本,通过将时间数组传递给ind <- order(df$var2, df$var1, decreasing = T)
df$rank <- seq(nrow(df))[order(ind)]
df
# var1 var2 rank
# 1 234 1456 1
# 2 24 456 3
# 3 34 456 2
# 4 68 343 4
可以大大简化该过程而不是其施工参数
eq
此后可以称为
#=======================================================
def eq(par,initial_cond,t):
#differential-eq-system----------------------
def funct(y,t):
Si, Zi, Ri=y
P,d,B,G,A=par
# the model equations (see Munz et al. 2009)
f0 = P - B*Si*Zi - d*Si
f1 = B*Si*Zi + G*Ri - A*Si*Zi
f2 = d*Si + A*Si*Zi - G*Ri
return [f0, f1, f2]
#integrate------------------------------------
ds = odeint(funct,initial_cond,t)
return ds.T
#=======================================================
但也仅产生T = np.linspace(0, 5.0, 1000+1)
S,Z,R=eq(rates,y0,T)
函数所需的值
score
然后将分数函数简化为
Tm=np.append([0],Td)
Sm,Zm,Rm=eq(rates,y0,Tm)
现在,例如,如果您要强烈拒绝否定参数,则可以将返回值更改为
def score(parms):
#a.Get Solution to system
Sm,Zm,Rm=eq(parms,y0,Tm)
#c.Score Difference between model and data points
ss=lambda data,model:((data-model)**2).sum()
return ss(Zd,Zm[1:])
的确使所有参数为正(以前在我的笔记本中第一个参数为负)。