SIENTIAPDE-1255: Add thread-safety documentation and in-place modification warnings to LinearRegressionModel and DataPreprocessor classes.
This commit is contained in:
@@ -10,6 +10,19 @@ from sklearn.preprocessing import StandardScaler
|
||||
|
||||
|
||||
class LinearRegressionModel(BaseEstimator, TransformerMixin):
|
||||
"""
|
||||
Linear Regression Model for Time Series Analysis.
|
||||
|
||||
Thread-safety: This class is NOT thread-safe during fit() operations.
|
||||
Do not call fit() on the same instance from multiple threads simultaneously.
|
||||
After fitting, predict() is thread-safe for read-only operations.
|
||||
|
||||
For multi-threaded environments:
|
||||
- Fit the model in a single thread
|
||||
- Share the fitted instance across threads for prediction only
|
||||
- Or create separate instances per thread
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
target_variable: str = '',
|
||||
@@ -99,6 +112,21 @@ class LinearRegressionModel(BaseEstimator, TransformerMixin):
|
||||
|
||||
|
||||
class DataPreprocessor(BaseEstimator, TransformerMixin):
|
||||
"""
|
||||
Data Preprocessor for Time Series Analysis.
|
||||
|
||||
Thread-safety: This class is NOT thread-safe during fit() operations.
|
||||
Do not call fit() on the same instance from multiple threads simultaneously.
|
||||
After fitting, transform() is thread-safe for read-only operations IF the
|
||||
input DataFrames are not shared between threads.
|
||||
|
||||
For multi-threaded environments:
|
||||
- Fit the preprocessor in a single thread
|
||||
- Share the fitted instance across threads for transform() only
|
||||
- Ensure each thread passes its own DataFrame copy to transform()
|
||||
- Or create separate instances per thread
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
date_column: str = '',
|
||||
@@ -176,9 +204,11 @@ class DataPreprocessor(BaseEstimator, TransformerMixin):
|
||||
self.static_threshold = static_threshold
|
||||
self.low_lim = low_lim
|
||||
self.upp_lim = upp_lim
|
||||
# self.window = window
|
||||
# self.window = window # Not implemented yet
|
||||
self.scaler_name = scaler_name
|
||||
self.scaler_params = scaler_params
|
||||
self.feature_names_order: list[str] = [] # Initialize to avoid AttributeError
|
||||
|
||||
if self.scaler_name == 'Standard Scaler':
|
||||
self.scaler = StandardScaler()
|
||||
elif self.scaler_name == 'None':
|
||||
@@ -299,11 +329,16 @@ class DataPreprocessor(BaseEstimator, TransformerMixin):
|
||||
|
||||
Returns:
|
||||
pandas.DataFrame: The treated data
|
||||
|
||||
Note:
|
||||
This method modifies input_data in-place. Ensure the caller passes
|
||||
a copy if the original DataFrame needs to be preserved.
|
||||
"""
|
||||
if lag_dict:
|
||||
for var, lag in lag_dict.items():
|
||||
if lag > 0:
|
||||
input_data[var] = input_data[var].shift(lag)
|
||||
# WARNING: Modifies DataFrame in-place
|
||||
input_data.dropna(inplace=True)
|
||||
return input_data
|
||||
|
||||
@@ -366,9 +401,13 @@ class DataPreprocessor(BaseEstimator, TransformerMixin):
|
||||
|
||||
Returns:
|
||||
pandas.DataFrame: The treated data
|
||||
|
||||
Note:
|
||||
This method modifies input_data in-place.
|
||||
"""
|
||||
if self.ar_var:
|
||||
input_data[self.ar_var] = input_data[self.target_variable].shift(1)
|
||||
# WARNING: Modifies DataFrame in-place
|
||||
input_data.dropna(inplace=True)
|
||||
return input_data
|
||||
|
||||
@@ -381,12 +420,16 @@ class DataPreprocessor(BaseEstimator, TransformerMixin):
|
||||
|
||||
Returns:
|
||||
pandas.DataFrame: The treated data
|
||||
|
||||
Note:
|
||||
This method modifies input_data in-place.
|
||||
"""
|
||||
if self.created_lags:
|
||||
for var, lag in self.created_lags.items():
|
||||
if lag > 0 and var in input_data.columns:
|
||||
new_col = f'{var}_lag{lag}'
|
||||
input_data[new_col] = input_data[var].shift(lag)
|
||||
# WARNING: Modifies DataFrame in-place
|
||||
input_data.dropna(inplace=True)
|
||||
return input_data
|
||||
|
||||
|
||||
Reference in New Issue
Block a user