V0.1.6 - Simulate a Predefined ModelΒΆ

Example created by Wilson Rocha Lacerda Junior

pip install sysidentpy
Requirement already satisfied: sysidentpy in c:\users\wilso\miniconda3\envs\sysidentpy\lib\site-packages (0.1.6)
Requirement already satisfied: scipy>=1.7.0 in c:\users\wilso\miniconda3\envs\sysidentpy\lib\site-packages (from sysidentpy) (1.7.1)
Requirement already satisfied: matplotlib>=3.3.2 in c:\users\wilso\miniconda3\envs\sysidentpy\lib\site-packages (from sysidentpy) (3.4.3)
Requirement already satisfied: numpy>=1.19.2 in c:\users\wilso\miniconda3\envs\sysidentpy\lib\site-packages (from sysidentpy) (1.20.3)
Requirement already satisfied: kiwisolver>=1.0.1 in c:\users\wilso\miniconda3\envs\sysidentpy\lib\site-packages (from matplotlib>=3.3.2->sysidentpy) (1.3.2)
Requirement already satisfied: pyparsing>=2.2.1 in c:\users\wilso\miniconda3\envs\sysidentpy\lib\site-packages (from matplotlib>=3.3.2->sysidentpy) (2.4.7)
Requirement already satisfied: cycler>=0.10 in c:\users\wilso\miniconda3\envs\sysidentpy\lib\site-packages (from matplotlib>=3.3.2->sysidentpy) (0.10.0)
Requirement already satisfied: python-dateutil>=2.7 in c:\users\wilso\miniconda3\envs\sysidentpy\lib\site-packages (from matplotlib>=3.3.2->sysidentpy) (2.8.2)
Requirement already satisfied: pillow>=6.2.0 in c:\users\wilso\miniconda3\envs\sysidentpy\lib\site-packages (from matplotlib>=3.3.2->sysidentpy) (8.3.2)
Requirement already satisfied: six in c:\users\wilso\miniconda3\envs\sysidentpy\lib\site-packages (from cycler>=0.10->matplotlib>=3.3.2->sysidentpy) (1.16.0)
Note: you may need to restart the kernel to use updated packages.
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_miso_data, get_siso_data
from sysidentpy.polynomial_basis.simulation import SimulatePolynomialNarmax

Generating 1 input 1 output sample dataΒΆ

The data is generated by simulating the following model:ΒΆ

\(y_k = 0.2y_{k-1} + 0.1y_{k-1}x_{k-1} + 0.9x_{k-2} + e_{k}\)

If colored_noise is set to True:

\(e_{k} = 0.8\nu_{k-1} + \nu_{k}\)

where \(x\) is a uniformly distributed random variable and \(\nu\) is a gaussian distributed variable with \(\mu=0\) and \(\sigma=0.1\)

In the next example we will generate a data with 1000 samples with white noise and selecting 90% of the data to train the model.

x_train, x_test, y_train, y_test = get_siso_data(n=1000,
                                                 colored_noise=False,
                                                 sigma=0.001,
                                                 train_percentage=90)

Defining the modelΒΆ

We already know that the generated data is a result of the model \(𝑦_π‘˜=0.2𝑦_{π‘˜βˆ’1}+0.1𝑦_{π‘˜βˆ’1}π‘₯_{π‘˜βˆ’1}+0.9π‘₯_{π‘˜βˆ’2}+𝑒_π‘˜\) . Thus, we can create a model with those regressors follwing a codification pattern:

  • \(0\) is the constant term,

  • \([1001] = y_{k-1}\)

  • \([100n] = y_{k-n}\)

  • \([200n] = x1_{k-n}\)

  • \([300n] = x2_{k-n}\)

  • \([1011, 1001] = y_{k-11} \times y_{k-1}\)

  • \([100n, 100m] = y_{k-n} \times y_{k-m}\)

  • \([12001, 1003, 1001] = x11_{k-1} \times y_{k-3} \times y_{k-1}\)

  • and so on

Importante NoteΒΆ

The order of the arrays matter.

If you use [2001, 1001], it will work, but [1001, 2001] will not (the regressor will be ignored). Always put the highest value first:

  • \([2003, 2001]\) works

  • \([2001, 2003]\) do not work

We will handle this limitation in upcoming update.

s = SimulatePolynomialNarmax()

# the model must be a numpy array
model = np.array(
    [
    [1001,    0], # y(k-1)
    [2001, 1001], # x1(k-1)y(k-1)
    [2002,    0], # x1(k-2)
    ]
                )
# theta must be a numpy array of shape (n, 1) where n is the number of regressors
theta = np.array([[0.2, 0.9, 0.1]]).T

Simulating the modelΒΆ

After defining the model and theta we just need to use the simulate method.

The simulate method returns the predicted values and the results where we can look at regressors, parameters and ERR values.

yhat, results = s.simulate(
    X_test=x_test,
    y_test=y_test,
    model_code=model,
    theta=theta,
    plot=True)
../_images/simulating_a_predefined_model_8_0.png
results = pd.DataFrame(results, columns=['Regressors', 'Parameters', 'ERR'])
results
Regressors Parameters ERR
0 y(k-1) 0.2000 0.00000000
1 x1(k-2) 0.9000 0.00000000
2 x1(k-1)y(k-1) 0.1000 0.00000000

OptionsΒΆ

You can set the steps_ahead to run the prediction/simulation:

yhat, results = s.simulate(
    X_test=x_test,
    y_test=y_test,
    model_code=model,
    theta=theta,
    plot=False,
    steps_ahead=1)
rrse = root_relative_squared_error(y_test, yhat)
rrse
0.0018551703513661596
yhat, results = s.simulate(
    X_test=x_test,
    y_test=y_test,
    model_code=model,
    theta=theta,
    plot=False,
    steps_ahead=21)
rrse = root_relative_squared_error(y_test, yhat)
rrse
0.0018992516182147507

Estimating the parametersΒΆ

If you have only the model strucuture, you can create an object with estimate_parameter=True and choose the methed for estimation using estimator. In this case, you have to pass the training data for parameters estimation.

When estimate_parameter=True, we also computate the ERR considering only the regressors defined by the user.

s2 = SimulatePolynomialNarmax(estimate_parameter=True, estimator='recursive_least_squares')
yhat, results = s2.simulate(
    X_train=x_train,
    y_train=y_train,
    X_test=x_test,
    y_test=y_test,
    model_code=model,
    # theta will be estimated using the defined estimator
    plot=True)

results = pd.DataFrame(results, columns=['Regressors', 'Parameters', 'ERR'])
results
../_images/simulating_a_predefined_model_14_0.png
Regressors Parameters ERR
0 y(k-1) 0.2001 0.00000000
1 x1(k-2) 0.8998 0.00000000
2 x1(k-1)y(k-1) 0.1004 0.00000000
yhat, results = s2.simulate(
    X_train=x_train,
    y_train=y_train,
    X_test=x_test,
    y_test=y_test,
    model_code=model,
    # theta will be estimated using the defined estimator
    plot=True,
    steps_ahead=8)

results = pd.DataFrame(results, columns=['Regressors', 'Parameters', 'ERR'])
results
../_images/simulating_a_predefined_model_15_0.png
Regressors Parameters ERR
0 y(k-1) 0.2001 0.00000000
1 x1(k-2) 0.8998 0.00000000
2 x1(k-1)y(k-1) 0.1004 0.00000000
yhat, results = s2.simulate(
    X_train=x_train,
    y_train=y_train,
    X_test=x_test,
    y_test=y_test,
    model_code=model,
    # theta will be estimated using the defined estimator
    plot=True,
    steps_ahead=8)
../_images/simulating_a_predefined_model_16_0.png