3

我有一个树木数据集。在这个数据集中,我有唯一的绘图编号、获取数据“测量”的顺序以及树木的高度平均值(以米为单位)和年龄平均值(以年为单位)。像这样的东西: 数据负责人

接下来,我定义模型以使用 Age 以这种方式预测高度:

身高 = 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 中访问此笔记本

4

1 回答 1

2

您的脚本只有一个问题。的定义z需要是 aParamMVtype 而不是 a CVasz = m.Param(value=ym)因为它是目标函数的输入。

如果您定义为 a而不是 a ,您也可以使用内置目标。您只需打开反馈状态即可使用目标函数来最小化测量值和模型预测之间的差异。这是您的脚本的修改版本。yCVVar FSTATUS=1

回归拟合

from gekko import GEKKO
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
url = 'http://apmonitor.com/pdc/uploads/Main/data_2nd_order.txt'
data = pd.read_csv(url)
m  = GEKKO()
xm = np.array(data['time'])
x  = m.Param(value=xm)
B0 = m.FV(1); B1 = m.FV(1); B2 = m.FV(1)
B0.STATUS = 1; B1.STATUS = 1; B2.STATUS = 1
ym =  np.array(data['output (y)'])
y  = m.CV(value=ym)
y.FSTATUS = 1
yi = m.Intermediate(B0 * ((1 - m.exp(-B1 *x))**B2))
m.Equation(y==yi)
m.options.IMODE = 2
m.options.SOLVER = 1
m.solve(disp=True)
print(B0.value[0],B1.value[0],B2.value[0])
plt.plot(xm,ym,'ro')
plt.plot(xm,y.value,'b--')
plt.show()
于 2019-11-18T00:04:31.607 回答