scentree 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
scentree/__init__.py ADDED
File without changes
@@ -0,0 +1 @@
1
+ explained_var = 0.8
File without changes
@@ -0,0 +1,86 @@
1
+ import numpy as np
2
+ from numpy.typing import NDArray
3
+ from pydantic import BaseModel, PrivateAttr
4
+ from sklearn.decomposition import PCA
5
+ from typing import cast, Optional, TypeVar
6
+
7
+ R = TypeVar("R", bound="BasePCA")
8
+
9
+
10
+ class BasePCA(BaseModel):
11
+ """
12
+ PCA wrapper around scikit-learn's PCA implementation.
13
+
14
+ This class encapsulates a scikit-learn PCA reducer and manages
15
+ it as an internal (non-validated, non-serialized) attribute.
16
+ """
17
+
18
+ _reducer: Optional[PCA] = PrivateAttr(default=None)
19
+
20
+ def transform(self, X: NDArray[np.float64]) -> NDArray[np.float64]:
21
+ """
22
+ Apply dimensionality reduction to a given matrix.
23
+
24
+ Args:
25
+ X (NDArray[np.float64]): Data to be reduced.
26
+
27
+ Raises:
28
+ RuntimeError: If the method has not been fitted previously
29
+ (i.e., `self._reducer` is None).
30
+
31
+ Returns:
32
+ NDArray[np.float64]: Data in the low-dimensional space.
33
+ """
34
+ if self._reducer is None:
35
+ raise RuntimeError("Model has not been fitted yet.")
36
+ return cast(NDArray[np.float64], self._reducer.transform(X))
37
+
38
+ def inverse_transform(self, X: NDArray[np.float64]) -> NDArray[np.float64]:
39
+ """
40
+ Apply inverse transformation to obtain data in the high-dimensional space.
41
+
42
+ Args:
43
+ X (NDArray[np.float64]): Data in the low-dimensional space.
44
+
45
+ Raises:
46
+ RuntimeError: If the method has not been fitted previously
47
+ (i.e., `self._reducer` is None).
48
+
49
+ Returns:
50
+ NDArray[np.float64]: Data in the low-dimensional space.
51
+ """
52
+ if self._reducer is None:
53
+ raise RuntimeError("Model has not been fitted yet.")
54
+ X_rec = cast(NDArray[np.float64], self._reducer.inverse_transform(X))
55
+ return X_rec
56
+
57
+ def fit_auto_components(
58
+ self,
59
+ X: NDArray[np.float64],
60
+ threshold: float,
61
+ ) -> NDArray[np.float64]:
62
+ """
63
+ Fit a PCA reducer automatically selecting the number of components
64
+ based on the explained variance threshold and transform the input data.
65
+
66
+ This method first fits a full PCA to compute the cumulative explained
67
+ variance. It then selects the smallest number of components such that
68
+ the cumulative variance exceeds the specified threshold. Finally, it
69
+ fits a PCA reducer with this number of components and transforms the data.
70
+
71
+ Args:
72
+ X (NDArray[np.float64]): Input feature matrix of shape (n_samples, n_features).
73
+ threshold (float): Desired cumulative explained variance ratio (between 0 and 1)
74
+ used to select the number of principal components.
75
+
76
+ Returns:
77
+ NDArray[np.float64]: Transformed input matrix with reduced dimensions based on
78
+ the automatically selected number of components.
79
+ """
80
+ pca_full = PCA()
81
+ pca_full.fit(X)
82
+ cumulative_variance = np.cumsum(pca_full.explained_variance_ratio_)
83
+ n_components_th = np.argmax(cumulative_variance >= threshold) + 1
84
+ self._reducer = PCA(n_components=n_components_th)
85
+ X_reduced = cast(NDArray[np.float64], self._reducer.fit_transform(X))
86
+ return X_reduced
File without changes
@@ -0,0 +1,245 @@
1
+ import numpy as np
2
+ from numpy.typing import NDArray
3
+ from pydantic import BaseModel
4
+ from scentree.estimators.ridge import RidgeEstimator
5
+ from scentree.estimators.var import VarEstimator
6
+ from sklearn.model_selection import BaseCrossValidator
7
+ from tqdm.auto import tqdm
8
+ from typing import Any, cast, ClassVar, List, Optional, Protocol, Self, Type, TypeVar, Union
9
+
10
+ R = TypeVar("R", bound="EstimatorController")
11
+
12
+
13
+ class EstimatorProtocol(Protocol):
14
+ """
15
+ Protocol defining the minimal interface required for an estimator.
16
+
17
+ This protocol standardizes the expected behavior for models that support
18
+ prediction, residual estimation, cross-validation fitting, in-sample and
19
+ out-of-sample estimation, and scoring.
20
+ """
21
+
22
+ def predict(self, X: NDArray[np.float64]) -> NDArray[np.float64]:
23
+ """Generate predictions.
24
+
25
+ Args:
26
+ X (NDArray[np.float64]): Input feature matrix for prediction.
27
+
28
+ Returns:
29
+ NDArray[np.float64]: Predicted target values.
30
+ """
31
+ ...
32
+
33
+ def estimate_residuals(self, X: NDArray[np.float64]) -> NDArray[np.float64]:
34
+ """
35
+ Estimate residuals.
36
+
37
+ Args:
38
+ X (NDArray[np.float64]): Input feature matrix for prediction. This
39
+ matrix is used as the true values.
40
+
41
+ Returns:
42
+ NDArray[np.float64]: Residuals.
43
+ """
44
+ ...
45
+
46
+ def fit_cv(
47
+ self,
48
+ X: NDArray[np.float64],
49
+ y: Optional[NDArray[np.float64]],
50
+ cv: Union[int, BaseCrossValidator],
51
+ ) -> Self:
52
+ """
53
+ Fit an estmator using cross-validation.
54
+
55
+ Args:
56
+ X (NDArray[np.float64]): Input feature matrix.
57
+ y (Optional[NDArray[np.float64]]): Target value.
58
+ cv (Union[int, BaseCrossValidator]): Number of folds (if int) or a
59
+ scikit-learn compatible cross-validator instance defining
60
+ the splitting strategy.
61
+
62
+ Returns:
63
+ Self: The fitted estimator instance.
64
+ """
65
+ ...
66
+
67
+ def in_sample_estimation(self, steps: int) -> NDArray[np.float64]:
68
+ """
69
+ Generate in sample estimations.
70
+
71
+ Args:
72
+ steps (int): Number of estimated values to provide.
73
+
74
+ Returns:
75
+ NDArray[np.float64]: Matrix containing the estimated values.
76
+ """
77
+ ...
78
+
79
+ def out_sample_estimation(self, steps: int) -> NDArray[np.float64]:
80
+ """
81
+ Generate out sample estimations.
82
+
83
+ Args:
84
+ steps (int): Number of estimated values to provide.
85
+
86
+ Returns:
87
+ NDArray[np.float64]: Matrix containing the estimated values.
88
+ """
89
+ ...
90
+
91
+ def get_score(self, X: NDArray[np.float64]) -> float:
92
+ """
93
+ Compute the score metric using the data provided.
94
+
95
+ Args:
96
+ X (NDArray[np.float64]): Matrix containing the features.
97
+
98
+ Returns:
99
+ float: The scoring measure.
100
+ """
101
+ ...
102
+
103
+
104
+ class EstimatorController(BaseModel):
105
+ """Controller class for managing and selecting estimators.
106
+
107
+ This class provides a mechanism to manage multiple estimator types.
108
+ It trains each estimator using the provided data, evaluates their
109
+ performance based on the scoring measure.
110
+
111
+ Attributes:
112
+ estimator_classes (ClassVar[List[Type]]): A list of estimator classes to be
113
+ evaluated.
114
+ best_estimator (Optional[Any]): The best estimator.
115
+ """
116
+
117
+ estimator_classes: ClassVar[List[Type]] = [RidgeEstimator, VarEstimator]
118
+ best_estimator: Optional[Any] = None
119
+
120
+ def get_score(self, X: NDArray[np.float64], estimator: EstimatorProtocol) -> float:
121
+ """
122
+ Compute the score metric using the data provided.
123
+
124
+ Args:
125
+ X (NDArray[np.float64]): Matrix containing the features.
126
+ estimator (EstimatorProtocol): The estimator to be evaluated.
127
+
128
+ Returns:
129
+ float: The scoring measure.
130
+ """
131
+ score = estimator.get_score(X)
132
+ return score
133
+
134
+ def fit(
135
+ self: R,
136
+ X: NDArray[np.float64],
137
+ cv: Union[int, BaseCrossValidator] = 5,
138
+ ) -> R:
139
+ """Train an estimator.
140
+
141
+ Args:
142
+ X (NDArray[np.float64]): Input feature matrix for prediction.
143
+ cv (Union[int, BaseCrossValidator]): Cross-validation configuration.
144
+ Defaults to 5.
145
+
146
+ Raises:
147
+ ValueError: If no estimator is selected (i.e., `estimator_chosen` is None).
148
+
149
+ Returns:
150
+ EstimatorController: The fitted estimator.
151
+ """
152
+ best_score = None
153
+ estimator_chosen = None
154
+ iterator = tqdm(
155
+ self.estimator_classes,
156
+ desc="Evaluating estimators",
157
+ disable=False,
158
+ )
159
+ for EstimatorClass in iterator:
160
+ iterator.set_postfix(estimator=EstimatorClass.__name__)
161
+ # Instantiate the estimator
162
+ estimator = EstimatorClass()
163
+ estimator.fit_cv(X=X, cv=cv)
164
+ # Compute score
165
+ score = self.get_score(X=X, estimator=estimator)
166
+ if (best_score is None) or (best_score is not None and score < best_score):
167
+ estimator_chosen = estimator
168
+ best_score = score
169
+ # Evaluate the estimator in the test set
170
+ if estimator_chosen is None:
171
+ raise ValueError("`estimator_chosen` is None")
172
+ self.best_estimator = estimator_chosen
173
+ return self
174
+
175
+ def predict(self, X: NDArray[np.float64]) -> NDArray[np.float64]:
176
+ """Generate predictions.
177
+
178
+ Args:
179
+ X (NDArray[np.float64]): Input feature matrix for prediction.
180
+
181
+ Raises:
182
+ ValueError: If the estimator has not been previously fitted
183
+ (i.e., `self.best_estimator` is None).
184
+
185
+ Returns:
186
+ NDArray[np.float64]: Predicted target values.
187
+ """
188
+ if self.best_estimator is None:
189
+ raise ValueError("You must call `fit()` before `predict()`.")
190
+ return cast(NDArray[np.float64], self.best_estimator.predict(X))
191
+
192
+ def estimate_residuals(self, X: NDArray[np.float64]) -> NDArray[np.float64]:
193
+ """
194
+ Estimate residuals.
195
+
196
+ Args:
197
+ X (NDArray[np.float64]): Input feature matrix for prediction. This
198
+ matrix is used as the true values.
199
+
200
+ Raises:
201
+ ValueError: If the estimator has not been previously fitted
202
+ (i.e., `self.best_estimator` is None).
203
+
204
+ Returns:
205
+ NDArray[np.float64]: Residuals.
206
+ """
207
+ if self.best_estimator is None:
208
+ raise ValueError("You must call `fit()` before `estimate_residuals()`.")
209
+ return cast(NDArray[np.float64], self.best_estimator.estimate_residuals(X))
210
+
211
+ def in_sample_estimation(self, steps: int) -> NDArray[np.float64]:
212
+ """
213
+ Generate in sample estimations.
214
+
215
+ Args:
216
+ steps (int): Number of estimated values to provide.
217
+
218
+ Raises:
219
+ ValueError: If the estimator has not been previously fitted
220
+ (i.e., `self.best_estimator` is None).
221
+
222
+ Returns:
223
+ NDArray[np.float64]: Matrix containing the estimated values.
224
+ """
225
+ if self.best_estimator is None:
226
+ raise ValueError("You must call `fit()` before `in_sample_estimation()`.")
227
+ return cast(NDArray[np.float64], self.best_estimator.in_sample_estimation(steps))
228
+
229
+ def out_sample_estimation(self, steps: int) -> NDArray[np.float64]:
230
+ """
231
+ Generate out sample estimations.
232
+
233
+ Args:
234
+ steps (int): Number of estimated values to provide.
235
+
236
+ Raises:
237
+ ValueError: If the estimator has not been previously fitted
238
+ (i.e., `self.best_estimator` is None).
239
+
240
+ Returns:
241
+ NDArray[np.float64]: Matrix containing the estimated values.
242
+ """
243
+ if self.best_estimator is None:
244
+ raise ValueError("You must call `fit()` before `out_sample_estimation()`.")
245
+ return cast(NDArray[np.float64], self.best_estimator.out_sample_estimation(steps))
@@ -0,0 +1,18 @@
1
+ from scentree.estimators.scikit_base import SklearnEstimator
2
+ from sklearn.base import BaseEstimator
3
+ from sklearn.linear_model import Ridge
4
+ from typing import Optional, Type
5
+
6
+
7
+ class RidgeEstimator(SklearnEstimator):
8
+ """Wrapper for the scikit-learn `Ridge` regression estimator.
9
+
10
+ Args:
11
+ estimator_class (Optional[Type[BaseEstimator]]): Estimator class to wrap.
12
+ Defaults to `sklearn.linear_model.Ridge`.
13
+ """
14
+
15
+ def __init__(self, estimator_class: Optional[Type[BaseEstimator]] = None):
16
+ if estimator_class is None:
17
+ estimator_class = Ridge
18
+ super().__init__(estimator_class=estimator_class)
@@ -0,0 +1,255 @@
1
+ import numpy as np
2
+ from numpy.typing import NDArray
3
+ from scentree.estimators.utils import get_default_parameters, get_hyperparameters_space
4
+ from scentree.metrics.rmse import rmse
5
+ from sklearn.base import BaseEstimator
6
+ from sklearn.metrics import make_scorer
7
+ from sklearn.model_selection import GridSearchCV, TimeSeriesSplit
8
+ from sklearn.model_selection._split import _BaseKFold
9
+ from typing import cast, Any, Dict, Optional, Type, TypeVar, Union
10
+
11
+ R = TypeVar("R", bound="SklearnEstimator")
12
+
13
+
14
+ class SklearnEstimator(BaseEstimator):
15
+ """
16
+ Wrapper class for scikit-learn estimators to integrate them into the Scentree framework.
17
+
18
+ This class provides a unified interface for working with scikit-learn estimators.
19
+ It allows dynamic instantiation of the estimator with default or custom hyperparameters,
20
+ and exposes standard scikit-learn methods such as `fit`, `predict`, `get_params`, and
21
+ `set_params`. This makes it easy to use any scikit-learn estimator in a consistent way
22
+ within the framework.
23
+
24
+ Attributes:
25
+ estimator_class (Type[Any]): The scikit-learn estimator class to wrap, e.g.,
26
+ `sklearn.linear_model.Ridge`.
27
+ estimator (Optional[Any]): Instance of the fitted estimator. This is set after
28
+ calling `fit`.
29
+ name (str): Name of the estimator class, derived from `estimator_class.__name__`.
30
+ hyperparameters (Dict[str, Any]): Dictionary of hyperparameter values used to
31
+ instantiate the estimator.
32
+ hyperparameters_space (Dict[str, List[Any]]): Dictionary defining the search
33
+ space for hyperparameters for tuning or optimization.
34
+ X_train_ (Optional[NDArray[np.float64]]): Optional attribute to store training data,
35
+ if needed for reference or internal operations.
36
+ """
37
+
38
+ def __init__(self, estimator_class: Type[Any]):
39
+ """
40
+ Initialize the SklearnEstimator wrapper with a given estimator class.
41
+
42
+ Args:
43
+ estimator_class (Type[Any]): The scikit-learn estimator class to wrap.
44
+ """
45
+ self.estimator = None
46
+ self.estimator_class = estimator_class
47
+ self.name = self.estimator_class.__name__
48
+ self.hyperparameters = get_default_parameters(estimator_class)
49
+ self.hyperparameters_space = get_hyperparameters_space(self.name)
50
+ self.X_train_: Optional[NDArray[np.float64]] = None
51
+
52
+ def fit(self: R, X: NDArray[np.float64], y: NDArray[np.float64]) -> R:
53
+ """Fit the wrapped Scikit-learn estimator to the training data.
54
+
55
+ Args:
56
+ X (NDArray[np.float64]): Input feature matrix for training.
57
+ y (NDArray[np.float64]): Target vector.
58
+
59
+ Returns:
60
+ R: The fitted wrapper instance.
61
+ """
62
+ self.estimator = self.estimator_class(**self.hyperparameters)
63
+ assert self.estimator is not None
64
+ self.estimator.fit(X, y)
65
+ self.X_train_ = X
66
+ return self
67
+
68
+ def predict(self, X: NDArray[np.float64]) -> NDArray[np.float64]:
69
+ """Generate predictions using the fitted Scikit-learn estimator.
70
+
71
+ Args:
72
+ X (NDArray[np.float64]): Input feature matrix for prediction.
73
+
74
+ Raises:
75
+ ValueError: If `fit()` has not been called before prediction.
76
+
77
+ Returns:
78
+ NDArray[np.float64]: Predicted target values.
79
+ """
80
+ if self.estimator is None:
81
+ raise ValueError("You must call `fit()` before `predict()`.")
82
+ return self.estimator.predict(X)
83
+
84
+ def get_params(self, deep: bool = True) -> Dict[str, Any]:
85
+ """Return the hyperparameters of the estimator.
86
+
87
+ Args:
88
+ deep (bool): Ignored parameter for compatibility with Scikit-learn.
89
+ Included for consistency with the BaseEstimator API.
90
+
91
+ Returns:
92
+ Dict[str, Any]: Dictionary of current hyperparameter values.
93
+ """
94
+ return {
95
+ "estimator_class": self.estimator_class,
96
+ "hyperparameters": self.hyperparameters,
97
+ "hyperparameters_space": self.hyperparameters_space,
98
+ }
99
+
100
+ def set_params(self: R, **params: Any) -> R:
101
+ """Set hyperparameter values for the estimator.
102
+
103
+ Args:
104
+ **params: Arbitrary keyword arguments of hyperparameters to update.
105
+
106
+ Returns:
107
+ R: The updated estimator instance (same type as self).
108
+ """
109
+ for key, value in params.items():
110
+ if hasattr(self, key):
111
+ setattr(self, key, value)
112
+ elif key in self.hyperparameters:
113
+ self.hyperparameters[key] = value
114
+ else:
115
+ raise ValueError(
116
+ f"Invalid parameter '{key}' for {self.__class__.__name__}. "
117
+ f"Valid parameters: constructor={list(self.__dict__.keys())}, "
118
+ f"hyperparameters={list(self.hyperparameters.keys())}."
119
+ )
120
+ return self
121
+
122
+ def fit_cv(
123
+ self,
124
+ X: NDArray[np.float64],
125
+ cv: Union[int, _BaseKFold] = 5,
126
+ ) -> BaseEstimator:
127
+ """
128
+ Perform a Grid Search over the estimator's hyperparameters
129
+ and return a trained instance of the best model.
130
+
131
+ Args:
132
+ X (NDArray[np.float64]): Training feature matrix.
133
+ cv (int or BaseCrossValidator): Cross-validation strategy. Default is 5-fold.
134
+
135
+ Returns:
136
+ BaseEstimator: An instance of the estimator with the best
137
+ hyperparameters, already fitted to the training data.
138
+ """
139
+ # First of all, split data into two sets: feature and target.
140
+ # To begin with, only one lag is taken into account.
141
+ steps = X.shape[0]
142
+ feature = X[: (steps - 1), :]
143
+ target = X[1:, :]
144
+
145
+ # Define scoring, compatible with multi-output
146
+ scorer = make_scorer(rmse, greater_is_better=False)
147
+
148
+ if isinstance(cv, int):
149
+ cv_splitter = TimeSeriesSplit(n_splits=cv)
150
+ else:
151
+ cv_splitter = cv
152
+
153
+ # Create GridSearchCV
154
+ grid = GridSearchCV(
155
+ estimator=self.estimator_class(),
156
+ param_grid=self.hyperparameters_space,
157
+ scoring=scorer,
158
+ cv=cv_splitter,
159
+ n_jobs=-1,
160
+ )
161
+
162
+ # Fit the grid search
163
+ grid.fit(feature, target)
164
+
165
+ # Instantiate and fit the best estimator
166
+ self.hyperparameters = grid.best_params_
167
+ self.fit(feature, target)
168
+
169
+ return self
170
+
171
+ def in_sample_estimation(self, steps: int) -> NDArray[np.float64]:
172
+ """
173
+ Generate in sample estimations.
174
+
175
+ Args:
176
+ steps (int): Number of estimated values to provide.
177
+
178
+ Raises:
179
+ ValueError: If `fit()` has not been called before in_sample_estimation.
180
+
181
+ Returns:
182
+ NDArray[np.float64]: Matrix containing the estimated values.
183
+ """
184
+ if self.X_train_ is None:
185
+ raise ValueError("You must call `fit()` before `in_sample_estimation()`.")
186
+ estimated_values = self.predict(self.X_train_[-steps:, :])
187
+ return estimated_values
188
+
189
+ def out_sample_estimation(self, steps: int) -> NDArray[np.float64]:
190
+ """
191
+ Generate out sample estimations.
192
+
193
+ Args:
194
+ steps (int): Number of estimated values to provide.
195
+
196
+ Raises:
197
+ ValueError: If `fit()` has not been called before out_sample_estimation.
198
+
199
+ Returns:
200
+ NDArray[np.float64]: Matrix containing the estimated values.
201
+ """
202
+ if self.X_train_ is None:
203
+ raise ValueError("You must call `fit()` before `in_sample_estimation()`.")
204
+ estimated_values = np.full((steps, self.X_train_.shape[1]), np.nan)
205
+ current_data = np.reshape(self.X_train_[-1, :], shape=(1, -1))
206
+ for i_pred in range(steps):
207
+ current_estimation = np.reshape(self.predict(current_data), shape=(1, -1))
208
+ estimated_values[i_pred, :] = current_estimation
209
+ current_data = current_estimation
210
+ return estimated_values
211
+
212
+ def get_score(self, X: NDArray[np.float64]) -> float:
213
+ """
214
+ Compute the score metric using the data provided.
215
+
216
+ Args:
217
+ X (NDArray[np.float64]): Matrix containing the features.
218
+ estimator (EstimatorProtocol): The estimator to be evaluated.
219
+
220
+ Raises:
221
+ ValueError: If `fit()` has not been called before computing the score.
222
+ ValueError: If `X` does not have the correct shape (at least 2 samples).
223
+
224
+ Returns:
225
+ float: The scoring measure.
226
+ """
227
+ if self.X_train_ is None:
228
+ raise ValueError("You must call `fit()` before `get_score()`.")
229
+ if len(X.shape) != 2 or (len(X.shape) == 2 and X.shape[0] < 2):
230
+ raise ValueError("X must be of appropriate shape")
231
+ estimated_values = self.predict(X)
232
+ X_aligned = X[1:, :]
233
+ estimated_aligned = estimated_values[:-1, :]
234
+ return rmse(X_aligned, estimated_aligned)
235
+
236
+ def estimate_residuals(self, X: NDArray[np.float64]) -> NDArray[np.float64]:
237
+ """
238
+ Estimate residuals.
239
+
240
+ Args:
241
+ X (NDArray[np.float64]): Input feature matrix for prediction. This
242
+ matrix is used as the true values.
243
+
244
+ Raises:
245
+ ValueError: If `fit()` has not been called before computing the residuals.
246
+
247
+ Returns:
248
+ NDArray[np.float64]: Residuals.
249
+ """
250
+ if self.X_train_ is None:
251
+ raise ValueError("You must call `fit()` before `estimate_residuals()`.")
252
+ estimated_values = self.predict(X)
253
+ X_true = X[1:, :]
254
+ X_estimated = estimated_values[:-1, :]
255
+ return cast(NDArray[np.float64], X_true - X_estimated)
@@ -0,0 +1,50 @@
1
+ from inspect import signature
2
+ from typing import Any, Dict, List, Type
3
+
4
+
5
+ HYPERPARAMETERS_SPACE: Dict[str, Dict[str, List[Any]]] = {
6
+ "Ridge": {
7
+ "alpha": [0.05, 0.06, 0.08, 0.1, 0.2, 0.25, 0.5, 0.7, 1, 2],
8
+ "max_iter": [100, 200, 300, 500, 1000],
9
+ },
10
+ "VAR": {"maxlags": [2, 5, 7, 10], "trend": ["n"]},
11
+ }
12
+
13
+
14
+ def get_hyperparameters_space(estimator_name: str) -> Dict[str, List[Any]]:
15
+ """Obtain the hyperparameters space for a given estimator.
16
+
17
+ Args:
18
+ estimator_name (str): Name of the estimator.
19
+
20
+ Returns:
21
+ dict: Dictionary with the range for each hyperparameter.
22
+ """
23
+ return HYPERPARAMETERS_SPACE.get(estimator_name, {})
24
+
25
+
26
+ def get_default_parameters(class_chosen: Type, from_fit: bool = False) -> Dict[str, Any]:
27
+ """
28
+ Retrieve the default hyperparameters for a given estimator class.
29
+
30
+ This function inspects the constructor (`__init__`) or the `fit` method
31
+ of the specified estimator class and returns a dictionary containing
32
+ all parameters that have default values, excluding `self`.
33
+
34
+ Args:
35
+ class_chosen (Type): The estimator class to retrieve default parameters from.
36
+ from_fit (bool, optional): If True, retrieve defaults from the `fit` method
37
+ instead of the constructor. Defaults to False.
38
+
39
+ Returns:
40
+ Dict[str, Any]: A dictionary mapping parameter names to their default values.
41
+ Only parameters with default values are included.
42
+
43
+ """
44
+
45
+ target = class_chosen.fit if from_fit else class_chosen.__init__
46
+ sig = signature(target)
47
+ defaults = {
48
+ k: v.default for k, v in sig.parameters.items() if v.default is not v.empty and k != "self"
49
+ }
50
+ return defaults