170 lines
7.2 KiB
Python
170 lines
7.2 KiB
Python
from dataclasses import dataclass
|
|
from typing import Any
|
|
|
|
|
|
@dataclass
|
|
class TrainModelParams:
|
|
"""
|
|
Parameters for machine learning model training.
|
|
|
|
This class encapsulates all configuration parameters required for the training
|
|
pipeline, including data processing settings, model configuration, and experiment
|
|
tracking information. All parameters are validated upon initialization to ensure
|
|
data integrity and prevent runtime errors.
|
|
|
|
Use the `from_dict()` class method to create instances from dictionaries with
|
|
automatic validation of all fields.
|
|
|
|
Attributes:
|
|
variable_columns (list[str]): List of variable column names to use as features.
|
|
lag_train (int): Number of lags to apply during training phase.
|
|
lag_val (int): Number of lags to apply during validation phase.
|
|
target_variable (str): Name of the target variable to predict.
|
|
rem_static_win (bool): Whether to remove static windows from data.
|
|
low_lim (dict[str, float]): Dictionary of lower limits for each variable.
|
|
upp_lim (dict[str, float]): Dictionary of upper limits for each variable.
|
|
window (int): Window size for rolling operations.
|
|
use_scaler (bool): Whether to use a scaler for data normalization.
|
|
include_ar (bool): Whether to include autoregressive variables.
|
|
bucket_name (str): Name of the MinIO bucket containing training data.
|
|
file_name (str): Name of the file in the MinIO bucket.
|
|
line_separator (str): Line separator used in the CSV file.
|
|
decimal_separator (str): Decimal separator used in the CSV file.
|
|
train_size (int): Percentage of data to use for training (0-100).
|
|
shuffle (bool): Whether to shuffle the data during train/test split.
|
|
experiment_run_id (int): Unique identifier for the experiment run.
|
|
experiment_name (str): Name of the experiment for tracking.
|
|
removed_intervals (list): List of time intervals to remove from the data.
|
|
"""
|
|
|
|
variable_columns: list[str]
|
|
lag_train: int
|
|
lag_val: int
|
|
target_variable: str
|
|
rem_static_win: bool
|
|
low_lim: dict[str, float]
|
|
upp_lim: dict[str, float]
|
|
window: int
|
|
use_scaler: bool
|
|
include_ar: bool
|
|
bucket_name: str
|
|
file_name: str
|
|
line_separator: str
|
|
decimal_separator: str
|
|
train_size: int
|
|
shuffle: bool
|
|
experiment_run_id: int
|
|
experiment_name: str
|
|
removed_intervals: list
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: dict[str, Any]) -> 'TrainModelParams':
|
|
"""
|
|
Create TrainModelParams from dictionary with validation.
|
|
|
|
This factory method creates a TrainModelParams instance from a dictionary,
|
|
applying validation to ensure all required fields are present and have
|
|
the correct types. This is the recommended way to create instances from
|
|
workflow input data.
|
|
|
|
Args:
|
|
data: Dictionary containing training parameters with keys matching
|
|
the attribute names (variable_columns, lag_train, etc.)
|
|
|
|
Returns:
|
|
TrainModelParams: Validated instance with all fields populated
|
|
|
|
Raises:
|
|
ValueError: If any required field is missing or None
|
|
TypeError: If any field has an incorrect type
|
|
KeyError: If any required key is missing from the dictionary
|
|
|
|
Example:
|
|
>>> input_data = {
|
|
... 'variable_columns': ['var1', 'var2'],
|
|
... 'lag_train': 5,
|
|
... # ... other fields
|
|
... }
|
|
>>> params = TrainModelParams.from_dict(input_data)
|
|
"""
|
|
return cls(
|
|
variable_columns=cls._check_none(
|
|
data.get('variable_columns'), list, 'variable_columns'
|
|
),
|
|
lag_train=cls._check_none(data.get('lag_train'), int, 'lag_train'),
|
|
lag_val=cls._check_none(data.get('lag_val'), int, 'lag_val'),
|
|
target_variable=cls._check_none(data.get('target_variable'), str, 'target_variable'),
|
|
rem_static_win=cls._check_none(data.get('rem_static_win'), bool, 'rem_static_win'),
|
|
low_lim=cls._check_none(data.get('low_lim'), dict, 'low_lim'),
|
|
upp_lim=cls._check_none(data.get('upp_lim'), dict, 'upp_lim'),
|
|
window=cls._check_none(data.get('window'), int, 'window'),
|
|
use_scaler=cls._check_none(data.get('use_scaler'), bool, 'use_scaler'),
|
|
include_ar=cls._check_none(data.get('include_ar'), bool, 'include_ar'),
|
|
bucket_name=cls._check_none(data.get('bucket_name'), str, 'bucket_name'),
|
|
file_name=cls._check_none(data.get('file_name'), str, 'file_name'),
|
|
line_separator=cls._check_none(data.get('line_separator'), str, 'line_separator'),
|
|
decimal_separator=cls._check_none(
|
|
data.get('decimal_separator'), str, 'decimal_separator'
|
|
),
|
|
train_size=cls._check_none(data.get('train_size'), int, 'train_size'),
|
|
shuffle=cls._check_none(data.get('shuffle'), bool, 'shuffle'),
|
|
experiment_run_id=cls._check_none(
|
|
data.get('experiment_run_id'), int, 'experiment_run_id'
|
|
),
|
|
experiment_name=cls._check_none(data.get('experiment_name'), str, 'experiment_name'),
|
|
removed_intervals=cls._check_type(
|
|
data.get('removed_intervals'), list, 'removed_intervals'
|
|
),
|
|
)
|
|
|
|
@staticmethod
|
|
def _check_none(value: Any | None, expected_type: type, field_name: str) -> Any:
|
|
"""
|
|
Validate that a value is not None and check its type.
|
|
|
|
This method ensures that required parameters are provided and have the
|
|
correct type, raising descriptive errors if validation fails.
|
|
|
|
Args:
|
|
value (Any | None): The value to validate.
|
|
expected_type (type): The expected type of the value.
|
|
field_name (str): The name of the field being validated (for error messages).
|
|
|
|
Returns:
|
|
Any: The validated value if it is not None and matches the expected type.
|
|
|
|
Raises:
|
|
ValueError: If the value is None.
|
|
TypeError: If the value is not of the expected type.
|
|
"""
|
|
if value is None:
|
|
error = f'{field_name} is required and cannot be None.'
|
|
raise ValueError(error)
|
|
|
|
return TrainModelParams._check_type(value, expected_type, field_name)
|
|
|
|
@staticmethod
|
|
def _check_type(value: Any | None, expected_type: type, field_name: str) -> Any:
|
|
"""
|
|
Validate that a value matches the expected type.
|
|
|
|
This method checks type compatibility and raises a descriptive error
|
|
if the value does not match the expected type.
|
|
|
|
Args:
|
|
value (Any | None): The value to validate.
|
|
expected_type (type): The expected type of the value.
|
|
field_name (str): The name of the field being validated (for error messages).
|
|
|
|
Returns:
|
|
Any: The validated value if it matches the expected type.
|
|
|
|
Raises:
|
|
TypeError: If the value is not of the expected type.
|
|
"""
|
|
if value is not None and not isinstance(value, expected_type):
|
|
error = f'{field_name} must be of type {expected_type.__name__}, but got {type(value).__name__}.'
|
|
raise TypeError(error)
|
|
|
|
return value
|