使用 NARMAX 模型进行系统识别的 Python 包
项目描述
什么是 SysIdentPy?
SysIdentPy 是一个用于系统识别的开源 Python 模块,它使用基于numpy构建的NARMAX模型,并在 3-Clause BSD 许可下分发。SysIdentPy 提供了一个易于使用且灵活的框架,用于为时间序列和动态系统构建动态非线性模型。
检查我们的文档!
如何安装 SysIdentPy?
让 SysIdentPy 运行的最简单方法是使用pip
pip install sysidentpy
要求
SysIdentPy 需要:
- Python (>= 3.7)
- 所有数值算法的 NumPy (>= 1.9.2)
- Matplotlib >= 3.3.2 用于静态绘图和可视化
- Pytorch (>=1.7.1) 用于构建前馈神经网络
| 平台 | 地位 |
|---|---|
| Linux | 好的 |
| 视窗 | 好的 |
| 苹果系统 | 好的 |
一些示例需要 pandas >= 0.18.0。但是,不需要使用 SysIdentPy。
SysIdentPy 的主要特点是什么?
| 特征 | 这是什么? |
|---|---|
| NARMAX 理念 | 您可以构建 NARMAX 模型的变体,例如 NARX、NAR、NARMA、NFIR、ARMA、ARX、AR 等。 |
| 模型结构选择 | 易于使用的方法来选择构建模型的最佳项,包括 FROLS 和 MetaMSS 以及与参数估计技术的几种组合来选择模型项。 |
| 基函数 | 您可以使用不同的基函数来构建模型。您可以设置线性和非线性基函数并将它们集成以获得自定义 NARMAX 模型。 |
| 参数估计 | 超过 15 种方法来估计模型参数和测试不同的结构选择场景。 |
| 模型模拟 | 您可以使用 SimulateNARMAX 类轻松地从论文中重现结果。此外,您可以使用不同的参数估计方法测试已发布的模型并比较性能。 |
| 神经 NARX | 您可以将 SysIdentPy 与 Pytorch 一起使用来创建自定义的神经 NARX 模型架构,该架构支持来自 Pytorch 的所有优化器和损失函数。 |
| 一般估计器 | 您可以使用来自 scikit-learn、Catboost 和许多其他兼容接口和组合工具等软件包的估计器来创建 NARMAX 模型。 |
为什么 SysIdentPy 存在?
SysIdentPy 旨在成为一个免费的开源软件包,以帮助社区设计 NARMAX 模型。不仅如此,它是构建 NARMAX 模型的最常用工具之一的免费且强大的替代品,它是 Matlab 的系统识别工具箱。
该项目由 Wilson RL Junior 积极维护并寻找贡献者。
如何使用 sysIdentPy?
SysIdentPy文档包括 20 个示例来帮助您入门:
- 典型的“Hello World”示例,用于主要 SysIdentPy 概念的入门级描述
- 专门介绍 SysIdentPy 功能的部分,例如模型结构选择算法、基函数、参数估计等。
- 一个专门的部分,专注于将 SysIdentPy 与真实世界数据集结合使用的用例。此外,还有一些与 Prophet、Neural Prophet、ARIMA 等其他时间序列工具的简要比较和基准测试。
例子
from torch import nn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sysidentpy.metrics import root_relative_squared_error
from sysidentpy.utils.generate_data import get_siso_data
# Generate a dataset of a simulated dynamical system
x_train, x_valid, y_train, y_valid = get_siso_data(
n=1000,
colored_noise=False,
sigma=0.001,
train_percentage=80
)
使用 FROLS 算法构建多项式 NARX 模型
from sysidentpy.model_structure_selection import FROLS
from sysidentpy.basis_function import Polynomial
from sysidentpy.utils.display_results import results
from sysidentpy.utils.plotting import plot_residues_correlation, plot_results
from sysidentpy.residues.residues_correlation import compute_residues_autocorrelation
from sysidentpy.residues.residues_correlation import compute_cross_correlation
basis_function=Polynomial(degree=2)
model = FROLS(
order_selection=True,
n_info_values=10,
extended_least_squares=False,
ylag=2,
xlag=2,
info_criteria='aic',
estimator='least_squares',
basis_function=basis_function
)
model.fit(X=x_train, y=y_train)
yhat = model.predict(X=x_valid, y=y_valid)
rrse = root_relative_squared_error(y_valid, yhat)
print(rrse)
r = pd.DataFrame(
results(
model.final_model, model.theta, model.err,
model.n_terms, err_precision=8, dtype='sci'
),
columns=['Regressors', 'Parameters', 'ERR'])
print(r)
Regressors Parameters ERR
0 x1(k-2) 0.9000 0.95556574
1 y(k-1) 0.1999 0.04107943
2 x1(k-1)y(k-1) 0.1000 0.00335113
plot_results(y=y_valid, yhat=yhat, n=1000)
ee = compute_residues_autocorrelation(y_valid, yhat)
plot_residues_correlation(data=ee, title="Residues", ylabel="$e^2$")
x1e = compute_cross_correlation(y_valid, yhat, x2_val)
plot_residues_correlation(data=x1e, title="Residues", ylabel="$x_1e$")
NARX 神经网络
from sysidentpy.neural_network import NARXNN
from sysidentpy.basis_function import Polynomial
from sysidentpy.utils.plotting import plot_residues_correlation, plot_results
from sysidentpy.residues.residues_correlation import compute_residues_autocorrelation
from sysidentpy.residues.residues_correlation import compute_cross_correlation
class NARX(nn.Module):
def __init__(self):
super().__init__()
self.lin = nn.Linear(4, 10)
self.lin2 = nn.Linear(10, 10)
self.lin3 = nn.Linear(10, 1)
self.tanh = nn.Tanh()
def forward(self, xb):
z = self.lin(xb)
z = self.tanh(z)
z = self.lin2(z)
z = self.tanh(z)
z = self.lin3(z)
return z
basis_function=Polynomial(degree=1)
narx_net = NARXNN(
net=NARX(),
ylag=2,
xlag=2,
basis_function=basis_function,
model_type="NARMAX",
loss_func='mse_loss',
optimizer='Adam',
epochs=200,
verbose=False,
optim_params={'betas': (0.9, 0.999), 'eps': 1e-05} # optional parameters of the optimizer
)
narx_net.fit(X=x_train, y=y_train)
yhat = narx_net.predict(X=x_valid, y=y_valid)
plot_results(y=y_valid, yhat=yhat, n=1000)
ee = compute_residues_autocorrelation(y_valid, yhat)
plot_residues_correlation(data=ee, title="Residues", ylabel="$e^2$")
x1e = compute_cross_correlation(y_valid, yhat, x_valid)
plot_residues_correlation(data=x1e, title="Residues", ylabel="$x_1e$")
Catboost-narx
from catboost import CatBoostRegressor
from sysidentpy.general_estimators import NARX
from sysidentpy.basis_function import Polynomial
from sysidentpy.utils.plotting import plot_residues_correlation, plot_results
from sysidentpy.residues.residues_correlation import compute_residues_autocorrelation
from sysidentpy.residues.residues_correlation import compute_cross_correlation
basis_function=Polynomial(degree=1)
catboost_narx = NARX(
base_estimator=CatBoostRegressor(
iterations=300,
learning_rate=0.1,
depth=6),
xlag=2,
ylag=2,
basis_function=basis_function,
fit_params={'verbose': False}
)
catboost_narx.fit(X=x_train, y=y_train)
yhat = catboost_narx.predict(X=x_valid, y=y_valid)
plot_results(y=y_valid, yhat=yhat, n=1000)
ee = compute_residues_autocorrelation(y_valid, yhat)
plot_residues_correlation(data=ee, title="Residues", ylabel="$e^2$")
x1e = compute_cross_correlation(y_valid, yhat, x_valid)
plot_residues_correlation(data=x1e, title="Residues", ylabel="$x_1e$")
无 NARX 配置的 Catboost
以下是没有 NARX 配置的 Catboost 性能。
def plot_results_tmp(y_valid, yhat):
_, ax = plt.subplots(figsize=(14, 8))
ax.plot(y_valid[:200], label='Data', marker='o')
ax.plot(yhat[:200], label='Prediction', marker='*')
ax.set_xlabel("$n$", fontsize=18)
ax.set_ylabel("$y[n]$", fontsize=18)
ax.grid()
ax.legend(fontsize=18)
plt.show()
catboost = CatBoostRegressor(
iterations=300,
learning_rate=0.1,
depth=6
)
catboost.fit(x_train, y_train, verbose=False)
plot_results_tmp(y_valid, catboost.predict(x_valid))
示例目录有几个 Jupyter 笔记本,其中包含有关如何使用该软件包的教程以及 sysidentpy 的一些特定应用程序。试试看!
沟通
引文
如果您在项目中使用 SysIdentPy,请给我留言。
如果您在科学出版物中使用 SysIdentPy,我们将感谢您引用以下论文:
- Lacerda 等人,(2020 年)。SysIdentPy:使用 NARMAX 模型进行系统识别的 Python 包。开源软件杂志, 5(54), 2384, https://doi.org/10.21105/joss.02384
@article{Lacerda2020,
doi = {10.21105/joss.02384},
url = {https://doi.org/10.21105/joss.02384},
year = {2020},
publisher = {The Open Journal},
volume = {5},
number = {54},
pages = {2384},
author = {Wilson Rocha Lacerda Junior and Luan Pascoal Costa da Andrade and Samuel Carlos Pessoa Oliveira and Samir Angelo Milani Martins},
title = {SysIdentPy: A Python package for System Identification using NARMAX models},
journal = {Journal of Open Source Software}
}
灵感
文档和结构(甚至本节)公开地受到 sklearn、einsteinpy 和许多其他人的启发,因为我们使用(并继续使用)它们来学习。