我有一个关于树木的数据集。在这个数据集中,我有地块的唯一编号"Plot"、采集数据时的顺序"Measurement"以及树木高度平均值和年龄平均值。类似这样:
数据头部接下来,我定义了预测使用年龄来预测树木高度的模型:
Height = B0 * ((1 - exp(-B1 *Age))**B2)
我的目标是分别确定B0、B1和B2的值。为此,我使用gekko包来找到模型参数,使用以下代码:
num_p = data_gek.Plot.unique()
nmp = 5
number_p = (data_gek.Plot == num_p[nmp])
m = GEKKO()
xm = np.array(data_gek[number_p]['Age'])
x = m.Param(value=xm)
B0 = m.FV(value=38.2) #value=38.2
B0.STATUS = 1
B1 = m.FV(value=0.1) #value=0.1
B1.STATUS = 1
B2 = m.FV(value=2.08) #value=2.08
B2.STATUS = 1
ym = np.array(data_gek[number_p]['Height'])
z = m.CV(value=ym)
y = m.Var()
m.Equation(y==B0 * ((1 - m.exp(-B1 *x))**B2))
m.Obj(((y-z)/z)**2)
m.options.IMODE = 2
m.options.SOLVER = 1
m.solve(disp=False)
print(B0.value[0],B1.value[0],B2.value[0])
#output
27.787958561 0.0052435491089 0.21178326158
不过,我不确定我是否使用了正确的方法。在没有参数初始值的情况下,是否有可能完成这个过程?因为我从文献中使用了B0、B1和B2的先前值。
如果您想查看我的数据集和处理过程,可以访问Google Colab笔记本。
B0
,B1
和B2
的初始值从1更改为您在文献中找到的初始值。例如:B0 = m.FV(38.2)
等等... - reyPandaB1
。一个很大的负值会导致m.exp()
这一项有一个非常大的值,并使求解器难以收敛。您可以使用B0 = m.FV(lb=0,ub=100)
添加这些限制。@reyPanda也提出了一个很好的建议,即使用更好的初始值。您可以将这些建议与B0 = m.FV(value=38.2,lb=0,ub=100)
相结合。 - John Hedengren