Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 125246c

Browse files
committed
add ridge_regression as parameter estimation method
1 parent bd763cf commit 125246c

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

‎sysidentpy/model_structure_selection/forward_regression_orthogonal_least_squares.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ class FROLS(Estimators, BaseMSS):
9494
Weight factor to control the proportions of the error norms
9595
and offers an extra degree of freedom within the adaptation
9696
of the LMS mixed norm method.
97+
ridge_param : float, default=0.01
98+
Constant parameter used in ridge regression (K = ridge_param*I).
9799
model_type: str, default="NARMAX"
98100
The user can choose "NARMAX", "NAR" and "NFIR" models
99101
@@ -166,6 +168,7 @@ def __init__(
166168
eps: np.float64 = np.finfo(np.float64).eps,
167169
gama: float = 0.2,
168170
weight: float = 0.02,
171+
ridge_param: float = 0.01,
169172
basis_function: Union[Polynomial, Fourier] = Polynomial(),
170173
model_type: str = "NARMAX",
171174
):
@@ -193,6 +196,7 @@ def __init__(
193196
eps=eps,
194197
gama=gama,
195198
weight=weight,
199+
ridge_param=ridge_param,
196200
basis_function=basis_function,
197201
)
198202
self.ensemble = None

‎sysidentpy/parameter_estimation/estimators.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def __init__(
2525
eps=np.finfo(np.float64).eps,
2626
gama=0.2,
2727
weight=0.02,
28+
ridge_param: float=0.01,
2829
basis_function=None,
2930
):
3031
self.eps = eps
@@ -35,6 +36,7 @@ def __init__(
3536
self.delta = delta
3637
self.gama = gama
3738
self.weight = weight # <0 e <1
39+
self.ridge_param = ridge_param
3840
self.xi = None
3941
self.theta_evolution = None
4042
self.basis_function = basis_function
@@ -51,6 +53,7 @@ def _validate_params(self):
5153
"eps": self.eps,
5254
"gama": self.gama,
5355
"weight": self.weight,
56+
"ridge_param": self.ridge_param,
5457
}
5558
for attribute, value in attributes.items():
5659
if not isinstance(value, (np.integer, int, float)):
@@ -890,3 +893,41 @@ def least_mean_squares_mixed_norm(self, psi, y):
890893
theta[:, i] = tmp_list.flatten()
891894

892895
return theta[:, -1].reshape(-1, 1)
896+
897+
def ridge_regression(self, psi, y):
898+
"""Estimate the model parameters using SVD and Ridge Regression method.
899+
900+
Parameters
901+
----------
902+
psi : ndarray of floats
903+
The information matrix of the model.
904+
y : array-like of shape = y_training
905+
The data used to training the model.
906+
907+
Returns
908+
-------
909+
theta : array-like of shape = number_of_model_elements
910+
The estimated parameters of the model.
911+
912+
References
913+
----------
914+
- Manuscript: Hoerl, A. E.; Kennard, R. W. Ridge regression:
915+
applications to nonorthogonal problems. Technometrics,
916+
Taylor & Francis, v. 12, n. 1, p. 69-82, 1970.
917+
918+
- StackExchange: whuber. The proof of shrinking coefficients using ridge
919+
regression through "spectral decomposition".
920+
Cross Validated, accessed 21 September 2023,
921+
https://stats.stackexchange.com/q/220324
922+
"""
923+
self._check_linear_dependence_rows(psi)
924+
925+
y = y[self.max_lag :, 0].reshape(-1, 1)
926+
927+
U, d, Vt = np.linalg.svd(psi, full_matrices=False)
928+
D = np.diag(d)
929+
I = np.identity(len(D))
930+
931+
theta = Vt.T @ np.linalg.inv(D**2 + self.ridge_param*I) @ D @ U.T @ y
932+
933+
return theta

‎sysidentpy/parameter_estimation/tests/test_estimators.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,5 +227,21 @@ def test_least_mean_squares_mixed_norm():
227227
assert_almost_equal(model.theta, theta, decimal=2)
228228

229229

230+
def test_ridge_regression():
231+
x, y, theta = create_test_data()
232+
basis_function = Polynomial(degree=2)
233+
model = FROLS(
234+
n_terms=5,
235+
extended_least_squares=False,
236+
ylag=[1, 2],
237+
xlag=2,
238+
estimator="ridge_regression",
239+
ridge_param=0.01,
240+
basis_function=basis_function,
241+
)
242+
model.fit(X=x, y=y)
243+
assert_almost_equal(model.theta, theta, decimal=2)
244+
245+
230246
def test_model_order_selection():
231247
assert_raises(ValueError, Estimators, max_lag=-1)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /