<jupyter_start><jupyter_text>Simulate a Predefined ModelExample created by <NAME><jupyter_code>pip install sysidentpy
import numpy as np
import pandas as pd
from sysidentpy.simulation import SimulateNARMAX
from sysidentpy.metrics import root_relative_squared_error
from sysidentpy.utils.generate_data import get_siso_data
from sysidentpy.basis_function._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, compute_cross_correlation<jupyter_output><empty_output><jupyter_text>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.<jupyter_code>x_train, x_test, y_train, y_test = get_siso_data(
    n=1000,
    colored_noise=False,
    sigma=0.001,
    train_percentage=90
)<jupyter_output><empty_output><jupyter_text>Defining the modelWe 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 Important NoteThe 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.<jupyter_code>s = SimulateNARMAX(basis_function=Polynomial(), calculate_err=True, estimate_parameter=False, extended_least_squares=True)

# 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<jupyter_output><empty_output><jupyter_text>Simulating the modelAfter 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.<jupyter_code>yhat = s.simulate(
    X_test=x_test,
    y_test=y_test,
    model_code=model,
    theta=theta,
)

r = pd.DataFrame(
    results(
        s.final_model, s.theta, s.err,
        s.n_terms, err_precision=8, dtype='sci'
        ),
    columns=['Regressors', 'Parameters', 'ERR'])
print(r)

plot_results(y=y_test, yhat = yhat, n=1000)
ee = compute_residues_autocorrelation(y_test, yhat)
plot_residues_correlation(data=ee, title="Residues", ylabel="$e^2$")
x1e = compute_cross_correlation(y_test, yhat, x_test)
plot_residues_correlation(data=x1e, title="Residues", ylabel="$x_1e$")<jupyter_output>Regressors  Parameters             ERR
0         y(k-1)  2.0000E-01  0.00000000E+00
1        x1(k-2)  9.0000E-01  0.00000000E+00
2  x1(k-1)y(k-1)  1.0000E-01  0.00000000E+00<jupyter_text>OptionsYou can set the `steps_ahead` to run the prediction/simulation:<jupyter_code>yhat = s.simulate(
    X_test=x_test,
    y_test=y_test,
    model_code=model,
    theta=theta,
    steps_ahead=1,
    )
rrse = root_relative_squared_error(y_test, yhat)
print(rrse)
yhat = s.simulate(
    X_test=x_test,
    y_test=y_test,
    model_code=model,
    theta=theta,
    steps_ahead=21,
    )
rrse = root_relative_squared_error(y_test, yhat)
print(rrse)<jupyter_output>0.0018387456847899486<jupyter_text>Estimating the parametersIf you have only the model strucuture, you can create an object with `estimate_parameter=True` andchoose the methed for estimation using `estimator`. In this case, you have to pass the training datafor parameters estimation. When `estimate_parameter=True`, we also computate the ERR considering only the regressors defined by the user.<jupyter_code>s = SimulateNARMAX(basis_function=Polynomial(), estimate_parameter=True, estimator='least_squares', calculate_err=True)

yhat = s.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
)

r = pd.DataFrame(
    results(
        s.final_model, s.theta, s.err,
        s.n_terms, err_precision=8, dtype='sci'
        ),
    columns=['Regressors', 'Parameters', 'ERR'])
print(r)

plot_results(y=y_test, yhat = yhat, n=1000)
ee = compute_residues_autocorrelation(y_test, yhat)
plot_residues_correlation(data=ee, title="Residues", ylabel="$e^2$")
x1e = compute_cross_correlation(y_test, yhat, x_test)
plot_residues_correlation(data=x1e, title="Residues", ylabel="$x_1e$")<jupyter_output>Regressors  Parameters             ERR
0         y(k-1)  2.0006E-01  9.56312958E-01
1        x1(k-2)  8.9993E-01  4.04769137E-02
2  x1(k-1)y(k-1)  9.9979E-02  3.20650789E-03
{'fraction_non_alphanumeric': 0.11842589187201177, 'fraction_numerical': 0.059948510481794774, 'mean_word_length': 4.683385579937304, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 3, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '589420', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 2259, 'n_tokens_neox': 2018, 'n_words': 498, 'path': 'examples/simulating_a_predefined_model.ipynb', 'repo_name': 'samirmartins/sysidentpy', 'size': '5459'}