Information Criteria - Examples¶
Example created by Wilson Rocha Lacerda Junior
Comparing different information criteria methods¶
Here we import the NARMAX model, the metric for model evaluation and the methods to generate sample data for tests. Also, we import pandas for specific usage.
pip install sysidentpy
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sysidentpy.model_structure_selection import FROLS
from sysidentpy.basis_function._basis_function import Polynomial
from sysidentpy.parameter_estimation import LeastSquares
from sysidentpy.metrics import root_relative_squared_error
from sysidentpy.utils.generate_data import get_siso_data
from sysidentpy.utils.display_results import results
from sysidentpy.utils.plotting import plot_results
Generating 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-1} + 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 3000 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=100, colored_noise=False, sigma=0.1, train_percentage=70
)
The idea is to show the impact of the information criteria to select the number of terms to compose the final model. You will se why it is an auxiliary tool and let the algorithm select the number of terms based on the minimum value is not a good idea when dealing with data highly corrupted by noise (even white noise)
Note: You may find different results when running the examples. This is due the fact we are not setting a fixed random generator for the sample data. However, the main analysis remain.
AIC¶
basis_function = Polynomial(degree=2)
estimator = LeastSquares()
model = FROLS(
order_selection=True,
n_info_values=15,
ylag=2,
xlag=2,
info_criteria="aic",
# estimator=estimator,
basis_function=basis_function,
err_tol=None,
)
model.fit(X=x_train, y=y_train)
yhat = model.predict(X=x_test, y=y_test)
rrse = root_relative_squared_error(y_test, 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)
plot_results(y=y_test, yhat=yhat, n=1000)
xaxis = np.arange(1, model.n_info_values + 1)
plt.plot(xaxis, model.info_values)
plt.xlabel("n_terms")
plt.ylabel("Information Criteria")
0.1681621129389993 Regressors Parameters ERR 0 x1(k-2) 9.2076E-01 9.41001395E-01 1 y(k-1) 1.7063E-01 2.71018399E-02 2 x1(k-1)y(k-1) 1.7342E-01 8.79812755E-03 3 x1(k-1)y(k-2) -9.7902E-02 2.75495842E-03 4 x1(k-2)x1(k-1) 4.9319E-02 1.85339089E-03 5 y(k-2)^2 -5.6743E-02 1.02439383E-03 6 x1(k-1) -2.0179E-02 6.78305323E-04
Text(0, 0.5, 'Information Criteria')
model.info_values
array([-273.81858224, -311.60797635, -331.34011486, -338.49936124, -342.10339048, -342.27073244, -342.82764626, -342.16492383, -341.04704839, -339.58437034, -337.79642875, -336.20531349, -333.72427584, -331.48645717, -329.53042523])
As can be seen above, the minimum value make the algorithm choose a model with 4 terms. However, if you check the plot, 3 terms is the best choice. Increasing the number of terms from 3 upwards do not lead to a better model since the difference is very small.
In this case, you should run the model again with the parameters n_terms=3! The ERR algorithm ordered the terms in a correct way, so you will get the exact model structure again!
AICc¶
basis_function = Polynomial(degree=2)
estimator = LeastSquares()
model = FROLS(
order_selection=True,
n_info_values=15,
ylag=2,
xlag=2,
info_criteria="aicc",
estimator=estimator,
basis_function=basis_function,
)
model.fit(X=x_train, y=y_train)
yhat = model.predict(X=x_test, y=y_test)
rrse = root_relative_squared_error(y_test, 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)
plot_results(y=y_test, yhat=yhat, n=1000)
xaxis = np.arange(1, model.n_info_values + 1)
plt.plot(xaxis, model.info_values)
plt.xlabel("n_terms")
plt.ylabel("Information Criteria")
0.1697650652880654 Regressors Parameters ERR 0 x1(k-2) 9.2659E-01 9.41001395E-01 1 y(k-1) 1.7219E-01 2.71018399E-02 2 x1(k-1)y(k-1) 1.7454E-01 8.79812755E-03 3 x1(k-1)y(k-2) -1.0170E-01 2.75495842E-03 4 x1(k-2)x1(k-1) 5.7955E-02 1.85339089E-03 5 y(k-2)^2 -4.8117E-02 1.02439383E-03 6 x1(k-1) -2.4728E-02 6.78305323E-04