Skip to main content

使用 NARMAX 模型进行系统识别的 Python 包

项目描述

DOI PyPI 版本 执照 开放式问题 问题已关闭 下载 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 的一些特定应用程序。试试看!

沟通

引文

DOI

如果您在项目中使用 SysIdentPy,请给我留言。

如果您在科学出版物中使用 SysIdentPy,我们将感谢您引用以下论文:

@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 和许多其他人的启发,因为我们使用(并继续使用)它们来学习。

项目详情