使用 GEKKO sysid 的自适应建模
Adaptive modelling using GEKKO sysid
我有 100 个数据点要在 GEKKO
中使用 sysid
来描述。在某个时间点(在本例中为 t = 50),数据发生显着变化,预测不再准确。我试图包含一个 if 语句来评估实际与预测并生成一个新模型(新 yp
)如果预测比模型大 x 倍。这是我的示例代码。循环在每个时间点继续评估 yp
,但现在应该评估 yp_new
。
from gekko import GEKKO
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# load data and parse into columns
t = np.linspace(0,1,101)
u = np.linspace(0,1,101)
y = np.zeros(len(t))
y[:50] = np.sin(u[:50])
y[50:] = np.exp(u[50:]/500)
# generate time-series model
m = GEKKO(remote=False)
# system identification
na = 2 # output coefficients
nb = 2 # input coefficients
yp,p,K = m.sysid(t,u,y,na,nb,diaglevel=1)
print(yp)
for i in range(len(t)):
difference = np.abs((yp[i]-y[i])/max(0.01,y[i]))
if difference>=0.2: #If the difference is >20%
yp_new,p_new,K = m.sysid(t,u,y,na,nb,diaglevel=0)
print('Recalculating at i = ' + str(i))
print(yp_new)
plt.figure()
plt.subplot(2,1,1)
plt.plot(t,u)
plt.legend([r'$u_0$',r'$u_1$'])
plt.ylabel('MVs')
plt.subplot(2,1,2)
plt.plot(t,y)
plt.plot(t,yp)
plt.plot(t,y)
plt.plot(t,yp_new)
plt.show()
您需要将 yp
更新为新的 yp 值 yp = yp_new
,否则在进行下一次系统识别时只需 return yp
。但是,您用于重做 sysid
计算的数据与您之前使用的数据相同,因此模型预测没有变化。您是否尝试仅使用 yp_new,p_new,K = m.sysid(t[i:],u[i:],y[i:],na,nb)
等最新数据更新时间序列模型?
模型当前更新的周期与原始时间序列模型预测不一致。
Recalculating at i = 10
Recalculating at i = 11
Recalculating at i = 12
Recalculating at i = 13
Recalculating at i = 14
Recalculating at i = 15
Recalculating at i = 16
Recalculating at i = 17
Recalculating at i = 18
Recalculating at i = 19
Recalculating at i = 20
Recalculating at i = 21
Recalculating at i = 22
Recalculating at i = 23
Recalculating at i = 24
Recalculating at i = 25
Recalculating at i = 40
Recalculating at i = 41
Recalculating at i = 42
Recalculating at i = 43
Recalculating at i = 44
Recalculating at i = 45
Recalculating at i = 46
Recalculating at i = 47
Recalculating at i = 48
Recalculating at i = 49
Recalculating at i = 50
Recalculating at i = 51
Recalculating at i = 52
如果您只包含最新数据,那么它只会在第 10、42、46 和 48 个周期重新计算。
from gekko import GEKKO
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# load data and parse into columns
t = np.linspace(0,1,101)
u = np.linspace(0,1,101)
y = np.zeros(len(t))
y[:50] = np.sin(u[:50])
y[50:] = np.exp(u[50:]/500)
# generate time-series model
m = GEKKO(remote=False)
# system identification
na = 2 # output coefficients
nb = 2 # input coefficients
yp,p,K = m.sysid(t,u,y,na,nb)
yp_init = yp.copy()
print(yp)
j = 0
for i in range(len(t)):
difference = np.abs((yp[i-j]-y[i])/max(0.01,y[i]))
if difference>=0.2: #If the difference is >20%
j = i # get cycle where the last update occurred
yp,p,K = m.sysid(t[i:],u[i:],y[i:],na,nb)
print('Recalculating at i = ' + str(i))
plt.figure()
plt.subplot(2,1,1)
plt.plot(t,u)
plt.legend([r'$u_0$',r'$u_1$'])
plt.ylabel('MVs')
plt.subplot(2,1,2)
plt.plot(t,y)
plt.plot(t,yp_init)
plt.plot(t,y)
plt.plot(t[j:],yp)
plt.show()
我有 100 个数据点要在 GEKKO
中使用 sysid
来描述。在某个时间点(在本例中为 t = 50),数据发生显着变化,预测不再准确。我试图包含一个 if 语句来评估实际与预测并生成一个新模型(新 yp
)如果预测比模型大 x 倍。这是我的示例代码。循环在每个时间点继续评估 yp
,但现在应该评估 yp_new
。
from gekko import GEKKO
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# load data and parse into columns
t = np.linspace(0,1,101)
u = np.linspace(0,1,101)
y = np.zeros(len(t))
y[:50] = np.sin(u[:50])
y[50:] = np.exp(u[50:]/500)
# generate time-series model
m = GEKKO(remote=False)
# system identification
na = 2 # output coefficients
nb = 2 # input coefficients
yp,p,K = m.sysid(t,u,y,na,nb,diaglevel=1)
print(yp)
for i in range(len(t)):
difference = np.abs((yp[i]-y[i])/max(0.01,y[i]))
if difference>=0.2: #If the difference is >20%
yp_new,p_new,K = m.sysid(t,u,y,na,nb,diaglevel=0)
print('Recalculating at i = ' + str(i))
print(yp_new)
plt.figure()
plt.subplot(2,1,1)
plt.plot(t,u)
plt.legend([r'$u_0$',r'$u_1$'])
plt.ylabel('MVs')
plt.subplot(2,1,2)
plt.plot(t,y)
plt.plot(t,yp)
plt.plot(t,y)
plt.plot(t,yp_new)
plt.show()
您需要将 yp
更新为新的 yp 值 yp = yp_new
,否则在进行下一次系统识别时只需 return yp
。但是,您用于重做 sysid
计算的数据与您之前使用的数据相同,因此模型预测没有变化。您是否尝试仅使用 yp_new,p_new,K = m.sysid(t[i:],u[i:],y[i:],na,nb)
等最新数据更新时间序列模型?
模型当前更新的周期与原始时间序列模型预测不一致。
Recalculating at i = 10
Recalculating at i = 11
Recalculating at i = 12
Recalculating at i = 13
Recalculating at i = 14
Recalculating at i = 15
Recalculating at i = 16
Recalculating at i = 17
Recalculating at i = 18
Recalculating at i = 19
Recalculating at i = 20
Recalculating at i = 21
Recalculating at i = 22
Recalculating at i = 23
Recalculating at i = 24
Recalculating at i = 25
Recalculating at i = 40
Recalculating at i = 41
Recalculating at i = 42
Recalculating at i = 43
Recalculating at i = 44
Recalculating at i = 45
Recalculating at i = 46
Recalculating at i = 47
Recalculating at i = 48
Recalculating at i = 49
Recalculating at i = 50
Recalculating at i = 51
Recalculating at i = 52
如果您只包含最新数据,那么它只会在第 10、42、46 和 48 个周期重新计算。
from gekko import GEKKO
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# load data and parse into columns
t = np.linspace(0,1,101)
u = np.linspace(0,1,101)
y = np.zeros(len(t))
y[:50] = np.sin(u[:50])
y[50:] = np.exp(u[50:]/500)
# generate time-series model
m = GEKKO(remote=False)
# system identification
na = 2 # output coefficients
nb = 2 # input coefficients
yp,p,K = m.sysid(t,u,y,na,nb)
yp_init = yp.copy()
print(yp)
j = 0
for i in range(len(t)):
difference = np.abs((yp[i-j]-y[i])/max(0.01,y[i]))
if difference>=0.2: #If the difference is >20%
j = i # get cycle where the last update occurred
yp,p,K = m.sysid(t[i:],u[i:],y[i:],na,nb)
print('Recalculating at i = ' + str(i))
plt.figure()
plt.subplot(2,1,1)
plt.plot(t,u)
plt.legend([r'$u_0$',r'$u_1$'])
plt.ylabel('MVs')
plt.subplot(2,1,2)
plt.plot(t,y)
plt.plot(t,yp_init)
plt.plot(t,y)
plt.plot(t[j:],yp)
plt.show()