From 91f76cf7efcd5acf044f0abcd177a01ae77c1618 Mon Sep 17 00:00:00 2001 From: victoryst Date: Thu, 14 Aug 2025 21:49:11 +0300 Subject: [PATCH 1/2] Add TS Operators --- .idea/.gitignore | 5 + .idea/BigFeat.iml | 14 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 7 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + bigfeat/bigfeat_base.py | 1057 ++++++++++++-- bigfeat/local_utils.py | 701 ++++++++- ...gfeat-rolling-mean-complete-walkthrough.md | 244 ++++ ...igfeat-time-series-complete-usage-guide.md | 1244 ++++++++++++++++ ...e-series-operators-and-rolling-analysis.md | 390 +++++ ...eat-time-series-testing-script-analysis.md | 505 +++++++ docs/bigfeat_time_series_changes.md | 302 ++++ requirements.txt | 28 + ...ng-term)_feature_info_20250814_194036.json | 63 + ...um-term)_feature_info_20250814_194033.json | 68 + ... (Mixed)_feature_info_20250814_194041.json | 79 + ...rt-term)_feature_info_20250814_194030.json | 70 + ...ng-term)_feature_info_20250814_194055.json | 63 + ...um-term)_feature_info_20250814_194051.json | 72 + ... (Mixed)_feature_info_20250814_194100.json | 77 + ...rt-term)_feature_info_20250814_194046.json | 70 + ...ng-term)_feature_info_20250814_194250.json | 56 + ...um-term)_feature_info_20250814_194241.json | 52 + ... (Mixed)_feature_info_20250814_194301.json | 63 + ...rt-term)_feature_info_20250814_194233.json | 54 + ...ng-term)_feature_info_20250814_194338.json | 56 + ...um-term)_feature_info_20250814_194326.json | 58 + ... (Mixed)_feature_info_20250814_194355.json | 63 + ...rt-term)_feature_info_20250814_194316.json | 56 + ...ng-term)_feature_info_20250814_194119.json | 48 + ...um-term)_feature_info_20250814_194112.json | 50 + ... (Mixed)_feature_info_20250814_194126.json | 56 + ...rt-term)_feature_info_20250814_194106.json | 49 + ...ng-term)_feature_info_20250814_194207.json | 58 + ...um-term)_feature_info_20250814_194154.json | 60 + ... (Mixed)_feature_info_20250814_194222.json | 62 + ...rt-term)_feature_info_20250814_194142.json | 63 + ...ng-term)_feature_info_20250814_194409.json | 36 + ...um-term)_feature_info_20250814_194407.json | 38 + ... (Mixed)_feature_info_20250814_194411.json | 44 + ...rt-term)_feature_info_20250814_194406.json | 39 + ...ng-term)_feature_info_20250814_194401.json | 38 + ...um-term)_feature_info_20250814_194359.json | 40 + ... (Mixed)_feature_info_20250814_194404.json | 44 + ...rt-term)_feature_info_20250814_194358.json | 41 + ...ng-term)_feature_info_20250814_193920.json | 75 + ...um-term)_feature_info_20250814_193914.json | 76 + ... (Mixed)_feature_info_20250814_193927.json | 83 ++ ...rt-term)_feature_info_20250814_193909.json | 72 + ...ng-term)_feature_info_20250814_193958.json | 75 + ...um-term)_feature_info_20250814_193948.json | 76 + ... (Mixed)_feature_info_20250814_194008.json | 81 ++ ...rt-term)_feature_info_20250814_193939.json | 78 + ...ng-term)_feature_info_20250814_194021.json | 69 + ...um-term)_feature_info_20250814_194017.json | 60 + ... (Mixed)_feature_info_20250814_194026.json | 69 + ...rt-term)_feature_info_20250814_194013.json | 62 + testing/results/time_based_analysis.png | Bin 0 -> 620058 bytes ...me_based_test_results_20250814_194412.json | 414 ++++++ testing/time_series_testing.py | 1281 +++++++++++++++++ 61 files changed, 8734 insertions(+), 140 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/BigFeat.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 docs/bigfeat-rolling-mean-complete-walkthrough.md create mode 100644 docs/bigfeat-time-series-complete-usage-guide.md create mode 100644 docs/bigfeat-time-series-operators-and-rolling-analysis.md create mode 100644 docs/bigfeat-time-series-testing-script-analysis.md create mode 100644 docs/bigfeat_time_series_changes.md create mode 100644 testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Long-term)_feature_info_20250814_194036.json create mode 100644 testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Medium-term)_feature_info_20250814_194033.json create mode 100644 testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Mixed)_feature_info_20250814_194041.json create mode 100644 testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Short-term)_feature_info_20250814_194030.json create mode 100644 testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Long-term)_feature_info_20250814_194055.json create mode 100644 testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Medium-term)_feature_info_20250814_194051.json create mode 100644 testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Mixed)_feature_info_20250814_194100.json create mode 100644 testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Short-term)_feature_info_20250814_194046.json create mode 100644 testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Long-term)_feature_info_20250814_194250.json create mode 100644 testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Medium-term)_feature_info_20250814_194241.json create mode 100644 testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Mixed)_feature_info_20250814_194301.json create mode 100644 testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Short-term)_feature_info_20250814_194233.json create mode 100644 testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Long-term)_feature_info_20250814_194338.json create mode 100644 testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Medium-term)_feature_info_20250814_194326.json create mode 100644 testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Mixed)_feature_info_20250814_194355.json create mode 100644 testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Short-term)_feature_info_20250814_194316.json create mode 100644 testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Long-term)_feature_info_20250814_194119.json create mode 100644 testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Medium-term)_feature_info_20250814_194112.json create mode 100644 testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Mixed)_feature_info_20250814_194126.json create mode 100644 testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Short-term)_feature_info_20250814_194106.json create mode 100644 testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Long-term)_feature_info_20250814_194207.json create mode 100644 testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Medium-term)_feature_info_20250814_194154.json create mode 100644 testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Mixed)_feature_info_20250814_194222.json create mode 100644 testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Short-term)_feature_info_20250814_194142.json create mode 100644 testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Long-term)_feature_info_20250814_194409.json create mode 100644 testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Medium-term)_feature_info_20250814_194407.json create mode 100644 testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Mixed)_feature_info_20250814_194411.json create mode 100644 testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Short-term)_feature_info_20250814_194406.json create mode 100644 testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Long-term)_feature_info_20250814_194401.json create mode 100644 testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Medium-term)_feature_info_20250814_194359.json create mode 100644 testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Mixed)_feature_info_20250814_194404.json create mode 100644 testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Short-term)_feature_info_20250814_194358.json create mode 100644 testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Long-term)_feature_info_20250814_193920.json create mode 100644 testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Medium-term)_feature_info_20250814_193914.json create mode 100644 testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Mixed)_feature_info_20250814_193927.json create mode 100644 testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Short-term)_feature_info_20250814_193909.json create mode 100644 testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Long-term)_feature_info_20250814_193958.json create mode 100644 testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Medium-term)_feature_info_20250814_193948.json create mode 100644 testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Mixed)_feature_info_20250814_194008.json create mode 100644 testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Short-term)_feature_info_20250814_193939.json create mode 100644 testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Long-term)_feature_info_20250814_194021.json create mode 100644 testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Medium-term)_feature_info_20250814_194017.json create mode 100644 testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Mixed)_feature_info_20250814_194026.json create mode 100644 testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Short-term)_feature_info_20250814_194013.json create mode 100644 testing/results/time_based_analysis.png create mode 100644 testing/results/time_based_test_results_20250814_194412.json create mode 100644 testing/time_series_testing.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/BigFeat.iml b/.idea/BigFeat.iml new file mode 100644 index 0000000..6609252 --- /dev/null +++ b/.idea/BigFeat.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..26c22e7 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..4d135fc --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/bigfeat/bigfeat_base.py b/bigfeat/bigfeat_base.py index 23cc727..f6e56a3 100644 --- a/bigfeat/bigfeat_base.py +++ b/bigfeat/bigfeat_base.py @@ -14,44 +14,774 @@ from sklearn.model_selection import cross_val_score from sklearn.metrics import f1_score, make_scorer from functools import partial +import warnings +from datetime import timedelta class BigFeat: - """Base BigFeat Class for both classification and regression tasks""" + """Enhanced BigFeat Class with time-based windows for time series support""" - def __init__(self, task_type='classification'): + def __init__(self, task_type='classification', enable_time_series=False, + window_sizes=None, lag_periods=None, verbose=True, + datetime_col=None, groupby_cols=None, time_step='D'): """ Initialize the BigFeat object - + Parameters: ----------- task_type : str, default='classification' The type of machine learning task. Either 'classification' or 'regression'. + enable_time_series : bool, default=False + Whether to enable time series operators + window_sizes : list of str or pd.Timedelta, optional + List of time-based window sizes for rolling operations + Examples: ['7D', '14D', '30D', '3M', '6M', '1Y'] or [pd.Timedelta(days=7), pd.Timedelta(days=30)] + lag_periods : list of str or pd.Timedelta, optional + List of time-based lag periods for time series operations + Examples: ['1D', '7D', '30D'] or [pd.Timedelta(days=1), pd.Timedelta(days=7)] + verbose : bool, default=True + Whether to print progress messages + datetime_col : str, optional + Name of the datetime column to use for time series operations + groupby_cols : list, optional + List of columns to group by when applying time series operations + time_step : str, default='D' + Time step for resampling when using time-based windows + Examples: 'D' (daily), 'H' (hourly), 'W' (weekly), 'M' (monthly) """ + # Original initialization self.n_jobs = -1 self.operators = [np.multiply, np.add, np.subtract, np.abs, np.square] self.binary_operators = [np.multiply, np.add, np.subtract] self.unary_operators = [np.abs, np.square, local_utils.original_feat] self.task_type = task_type - + + # Time series parameters + self.enable_time_series = enable_time_series + self.verbose = verbose + self.time_step = time_step + + # Convert time-based windows to pandas Timedelta objects + if window_sizes is None: + self.window_sizes = [pd.Timedelta(days=7), pd.Timedelta(days=14), pd.Timedelta(days=30), + pd.Timedelta(days=90), pd.Timedelta(days=180), pd.Timedelta(days=365)] + else: + self.window_sizes = self._parse_time_periods(window_sizes) + + if lag_periods is None: + self.lag_periods = [pd.Timedelta(days=1), pd.Timedelta(days=7), pd.Timedelta(days=14), + pd.Timedelta(days=30), pd.Timedelta(days=90)] + else: + self.lag_periods = self._parse_time_periods(lag_periods) + + # Parameters for date/time column specification + self.datetime_col = datetime_col + self.groupby_cols = groupby_cols or [] + self.original_data = None # Store original data with datetime info + self.feature_columns = None # Store feature column names + + # Add time series operators if enabled + if enable_time_series: + self.time_series_operators = [ + self._safe_rolling_mean, + self._safe_rolling_std, + self._safe_rolling_min, + self._safe_rolling_max, + self._safe_rolling_median, + self._safe_rolling_sum, + self._safe_lag_feature, + self._safe_diff_feature, + self._safe_pct_change, + self._safe_ewm, + self._safe_momentum, + self._safe_seasonal_decompose, + self._safe_trend_feature, + self._safe_weekday_mean, + self._safe_month_mean + ] + # Extend the original operators with time series operators + self.operators.extend(self.time_series_operators) + self.unary_operators.extend(self.time_series_operators) + + if self.verbose: + print(f"Time series mode enabled with {len(self.time_series_operators)} additional operators") + print(f"Window sizes: {[str(w) for w in self.window_sizes]}") + print(f"Lag periods: {[str(l) for l in self.lag_periods]}") + if self.datetime_col: + print(f"Date/time column specified: {self.datetime_col}") + if self.groupby_cols: + print(f"Groupby columns specified: {self.groupby_cols}") + print(f"Time step for resampling: {self.time_step}") + # Validate task_type input if task_type not in ['classification', 'regression']: raise ValueError("task_type must be either 'classification' or 'regression'") - def fit(self, X, y, gen_size=5, random_state=0, iterations=5, estimator='avg', + def _parse_time_periods(self, periods): + """ + Parse time periods from string or Timedelta format + + Parameters: + ----------- + periods : list + List of time periods as strings or Timedelta objects + + Returns: + -------- + list of pd.Timedelta + Parsed time periods + """ + parsed_periods = [] + for period in periods: + if isinstance(period, str): + try: + parsed_periods.append(pd.Timedelta(period)) + except ValueError: + # Try parsing common formats + if period.endswith('D'): + days = int(period[:-1]) + parsed_periods.append(pd.Timedelta(days=days)) + elif period.endswith('W'): + weeks = int(period[:-1]) + parsed_periods.append(pd.Timedelta(weeks=weeks)) + elif period.endswith('M'): + months = int(period[:-1]) + parsed_periods.append(pd.Timedelta(days=months * 30)) # Approximate + elif period.endswith('Y'): + years = int(period[:-1]) + parsed_periods.append(pd.Timedelta(days=years * 365)) # Approximate + else: + # Default to days if no unit specified + parsed_periods.append(pd.Timedelta(days=int(period))) + elif isinstance(period, pd.Timedelta): + parsed_periods.append(period) + else: + # Try to convert to timedelta + parsed_periods.append(pd.Timedelta(period)) + + return parsed_periods + + def _prepare_time_series_data(self, X, y=None): + """ + Prepare data for time-based series operations by organizing it with datetime and groupby columns + + Parameters: + ----------- + X : array-like or DataFrame + Input features + y : array-like, optional + Target variable + + Returns: + -------- + X_processed : DataFrame + Processed data ready for time-based series operations + """ + if not self.enable_time_series or self.datetime_col is None: + return X if isinstance(X, pd.DataFrame) else pd.DataFrame(X) + + # Convert to DataFrame if needed + if isinstance(X, pd.DataFrame): + df = X.copy() + else: + # If we have stored feature columns, use them + if self.feature_columns is not None: + df = pd.DataFrame(X, columns=self.feature_columns) + else: + df = pd.DataFrame(X, columns=[f'feature_{i}' for i in range(X.shape[1])]) + + # Add datetime column from stored original data if available + if self.original_data is not None and self.datetime_col in self.original_data.columns: + df[self.datetime_col] = self.original_data[self.datetime_col].values[:len(df)] + + # Add groupby columns if specified + for col in self.groupby_cols: + if col in self.original_data.columns: + df[col] = self.original_data[col].values[:len(df)] + + # Ensure datetime column is datetime type + if self.datetime_col in df.columns: + df[self.datetime_col] = pd.to_datetime(df[self.datetime_col]) + + # Sort by datetime and groupby columns for proper time series order + sort_cols = [self.datetime_col] if self.datetime_col in df.columns else [] + sort_cols.extend([col for col in self.groupby_cols if col in df.columns]) + + if sort_cols: + df = df.sort_values(sort_cols).reset_index(drop=True) + + return df + + def _apply_time_based_operation(self, data, feature_col, operation, window_size=None, lag_period=None): + """ + Apply time-based series operation to a specific feature column with proper grouping + + Parameters: + ----------- + data : DataFrame + Data with datetime and groupby columns + feature_col : str + Name of the feature column to apply operation to + operation : str + Type of operation ('rolling_mean', 'lag', etc.) + window_size : pd.Timedelta, optional + Time-based window size for rolling operations + lag_period : pd.Timedelta, optional + Time-based lag period for lag operations + + Returns: + -------- + result : array + Result of the time-based series operation + """ + try: + if feature_col not in data.columns or self.datetime_col not in data.columns: + return np.zeros(len(data)) + + # Set datetime as index for time-based operations + if self.groupby_cols and any(col in data.columns for col in self.groupby_cols): + # Group data by groupby columns + groupby_cols = [col for col in self.groupby_cols if col in data.columns] + + results = [] + for name, group in data.groupby(groupby_cols): + group_sorted = group.set_index(self.datetime_col).sort_index() + group_result = self._apply_single_group_operation( + group_sorted, feature_col, operation, window_size, lag_period + ) + # Restore original order + group_result = group_result.reindex(group[self.datetime_col]).values + results.extend(group_result) + + return np.array(results) + else: + # Single group operation + data_sorted = data.set_index(self.datetime_col).sort_index() + result = self._apply_single_group_operation( + data_sorted, feature_col, operation, window_size, lag_period + ) + # Restore original order + return result.reindex(data[self.datetime_col]).values + + except Exception as e: + if self.verbose: + print(f"Warning: Time-based operation {operation} failed for {feature_col}: {str(e)}") + return np.zeros(len(data)) + + def _apply_single_group_operation(self, data, feature_col, operation, window_size=None, lag_period=None): + """ + Apply operation to a single group with datetime index + + Parameters: + ----------- + data : DataFrame + Data with datetime index + feature_col : str + Feature column name + operation : str + Operation type + window_size : pd.Timedelta, optional + Window size + lag_period : pd.Timedelta, optional + Lag period + + Returns: + -------- + pd.Series + Result series with datetime index + """ + series = data[feature_col] + + if operation == 'rolling_mean': + window_size = window_size or self.rng.choice(self.window_sizes) + result = series.rolling(window=window_size, min_periods=1).mean() + + elif operation == 'rolling_std': + window_size = window_size or self.rng.choice(self.window_sizes) + result = series.rolling(window=window_size, min_periods=1).std().fillna(0) + + elif operation == 'rolling_min': + window_size = window_size or self.rng.choice(self.window_sizes) + result = series.rolling(window=window_size, min_periods=1).min() + + elif operation == 'rolling_max': + window_size = window_size or self.rng.choice(self.window_sizes) + result = series.rolling(window=window_size, min_periods=1).max() + + elif operation == 'rolling_median': + window_size = window_size or self.rng.choice(self.window_sizes) + result = series.rolling(window=window_size, min_periods=1).median() + + elif operation == 'rolling_sum': + window_size = window_size or self.rng.choice(self.window_sizes) + result = series.rolling(window=window_size, min_periods=1).sum() + + elif operation == 'lag': + lag_period = lag_period or self.rng.choice(self.lag_periods) + # Create a shifted index + shifted_index = series.index - lag_period + result = pd.Series(index=series.index, dtype=float) + for idx in series.index: + shifted_idx = idx - lag_period + # Find the closest timestamp within a reasonable tolerance + tolerance = pd.Timedelta(self.time_step) if isinstance(self.time_step, str) else self.time_step + mask = (series.index >= shifted_idx - tolerance) & (series.index <= shifted_idx + tolerance) + if mask.any(): + result[idx] = series[mask].iloc[0] + else: + result[idx] = np.nan + result = result.fillna(method='ffill').fillna(0) + + elif operation == 'diff': + lag_period = lag_period or self.rng.choice(self.lag_periods) + # Similar to lag but compute difference + shifted_index = series.index - lag_period + result = pd.Series(index=series.index, dtype=float) + for idx in series.index: + shifted_idx = idx - lag_period + tolerance = pd.Timedelta(self.time_step) if isinstance(self.time_step, str) else self.time_step + mask = (series.index >= shifted_idx - tolerance) & (series.index <= shifted_idx + tolerance) + if mask.any(): + result[idx] = series[idx] - series[mask].iloc[0] + else: + result[idx] = 0 + result = result.fillna(0) + + elif operation == 'pct_change': + lag_period = lag_period or self.rng.choice(self.lag_periods) + # Percentage change over time period + shifted_index = series.index - lag_period + result = pd.Series(index=series.index, dtype=float) + for idx in series.index: + shifted_idx = idx - lag_period + tolerance = pd.Timedelta(self.time_step) if isinstance(self.time_step, str) else self.time_step + mask = (series.index >= shifted_idx - tolerance) & (series.index <= shifted_idx + tolerance) + if mask.any(): + old_val = series[mask].iloc[0] + if old_val != 0: + result[idx] = (series[idx] - old_val) / old_val + else: + result[idx] = 0 + else: + result[idx] = 0 + result = result.fillna(0) + + elif operation == 'ewm': + # Use time-based exponential weighting + window_size = window_size or self.rng.choice(self.window_sizes) + halflife = window_size / 2 + result = series.ewm(halflife=halflife).mean() + + elif operation == 'momentum': + lag_period = lag_period or self.rng.choice(self.lag_periods) + # Momentum as difference from lag period + result = self._apply_single_group_operation(data, feature_col, 'diff', None, lag_period) + + elif operation == 'seasonal_decompose': + # Simple seasonal pattern extraction + try: + # Resample to regular frequency for seasonal decomposition + resampled = series.resample(self.time_step).mean().fillna(method='ffill') + if len(resampled) > 2: + # Simple seasonal pattern using day of year + seasonal_pattern = resampled.groupby(resampled.index.dayofyear).transform('mean') + # Map back to original index + result = pd.Series(index=series.index, dtype=float) + for idx in series.index: + day_of_year = idx.dayofyear + matching_seasonal = seasonal_pattern[seasonal_pattern.index.dayofyear == day_of_year] + if len(matching_seasonal) > 0: + result[idx] = matching_seasonal.iloc[0] + else: + result[idx] = series.mean() + else: + result = pd.Series(series.mean(), index=series.index) + except: + result = pd.Series(series.mean(), index=series.index) + + elif operation == 'trend': + window_size = window_size or self.rng.choice(self.window_sizes) + # Simple trend as rolling slope + result = series.rolling(window=window_size, min_periods=2).apply( + lambda x: np.polyfit(range(len(x)), x, 1)[0] if len(x) > 1 else 0, raw=True + ).fillna(0) + + elif operation == 'weekday_mean': + # Mean value by weekday + weekday_means = series.groupby(series.index.dayofweek).mean() + result = pd.Series(index=series.index, dtype=float) + for idx in series.index: + result[idx] = weekday_means.get(idx.dayofweek, series.mean()) + + elif operation == 'month_mean': + # Mean value by month + month_means = series.groupby(series.index.month).mean() + result = pd.Series(index=series.index, dtype=float) + for idx in series.index: + result[idx] = month_means.get(idx.month, series.mean()) + else: + result = pd.Series(0, index=series.index) + + return result + + # Time Series Utility Methods (unchanged) + def _clean_feature(self, feature_data): + """Clean feature data to ensure stability""" + try: + feature_data = np.asarray(feature_data, dtype=float) + # Replace inf with large finite values + feature_data = np.where(np.isinf(feature_data), np.sign(feature_data) * 1e8, feature_data) + # Replace nan with zeros + feature_data = np.where(np.isnan(feature_data), 0, feature_data) + # Clip extreme values + feature_data = np.clip(feature_data, -1e8, 1e8) + return feature_data + except Exception: + return np.zeros_like(feature_data, dtype=float) + + def _validate_feature(self, feature_data): + """Validate features for stability and usefulness""" + try: + if len(feature_data) == 0: + return False + feature_data = np.asarray(feature_data, dtype=float) + if not np.isfinite(feature_data).all(): + return False + if np.std(feature_data) < 1e-10: + return False + if np.max(np.abs(feature_data)) > 1e8: + return False + return True + except Exception: + return False + + # Enhanced Safe Time Series Operations that use time-based operations + def _safe_rolling_mean(self, feature_data): + """Safe rolling mean calculation using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'rolling_mean') + else: + # Fallback to original implementation + try: + window_size = self.rng.choice([3, 5, 7, 10, 14, 21, 30]) + window_size = min(window_size, len(feature_data)) + result = pd.Series(feature_data).rolling(window=window_size, min_periods=1).mean().bfill().values + return self._clean_feature(result) + except Exception: + return feature_data + + def _safe_rolling_std(self, feature_data): + """Safe rolling standard deviation using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'rolling_std') + else: + try: + window_size = self.rng.choice([3, 5, 7, 10, 14, 21, 30]) + window_size = min(window_size, len(feature_data)) + result = pd.Series(feature_data).rolling(window=window_size, min_periods=1).std().fillna(0).values + return self._clean_feature(result) + except Exception: + return np.zeros_like(feature_data) + + def _safe_rolling_min(self, feature_data): + """Safe rolling minimum using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'rolling_min') + else: + try: + window_size = self.rng.choice([3, 5, 7, 10, 14, 21, 30]) + window_size = min(window_size, len(feature_data)) + result = pd.Series(feature_data).rolling(window=window_size, min_periods=1).min().bfill().values + return self._clean_feature(result) + except Exception: + return feature_data + + def _safe_rolling_max(self, feature_data): + """Safe rolling maximum using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'rolling_max') + else: + try: + window_size = self.rng.choice([3, 5, 7, 10, 14, 21, 30]) + window_size = min(window_size, len(feature_data)) + result = pd.Series(feature_data).rolling(window=window_size, min_periods=1).max().bfill().values + return self._clean_feature(result) + except Exception: + return feature_data + + def _safe_rolling_median(self, feature_data): + """Safe rolling median using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'rolling_median') + else: + try: + window_size = self.rng.choice([3, 5, 7, 10, 14, 21, 30]) + window_size = min(window_size, len(feature_data)) + result = pd.Series(feature_data).rolling(window=window_size, min_periods=1).median().bfill().values + return self._clean_feature(result) + except Exception: + return feature_data + + def _safe_rolling_sum(self, feature_data): + """Safe rolling sum using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'rolling_sum') + else: + try: + window_size = self.rng.choice([3, 5, 7, 10, 14, 21, 30]) + window_size = min(window_size, len(feature_data)) + result = pd.Series(feature_data).rolling(window=window_size, min_periods=1).sum().fillna(0).values + return self._clean_feature(result) + except Exception: + return np.zeros_like(feature_data) + + def _safe_lag_feature(self, feature_data): + """Safe lag feature creation using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'lag') + else: + try: + lag_periods = self.rng.choice([1, 2, 3, 5, 7, 10]) + lag_periods = min(lag_periods, len(feature_data) - 1) + result = pd.Series(feature_data).shift(lag_periods).bfill().values + return self._clean_feature(result) + except Exception: + return feature_data + + def _safe_diff_feature(self, feature_data): + """Safe difference calculation using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'diff') + else: + try: + periods = self.rng.choice([1, 2, 3, 5, 7, 10]) + periods = min(periods, len(feature_data) - 1) + result = pd.Series(feature_data).diff(periods).fillna(0).values + return self._clean_feature(result) + except Exception: + return np.zeros_like(feature_data) + + def _safe_pct_change(self, feature_data): + """Safe percentage change using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'pct_change') + else: + try: + periods = self.rng.choice([1, 2, 3, 5, 7, 10]) + periods = min(periods, len(feature_data) - 1) + result = pd.Series(feature_data).pct_change(periods).fillna(0).values + result = np.where(np.isinf(result), 0, result) + return self._clean_feature(result) + except Exception: + return np.zeros_like(feature_data) + + def _safe_ewm(self, feature_data): + """Safe exponential moving average using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'ewm') + else: + try: + alpha = self.rng.choice([0.1, 0.2, 0.3, 0.5]) + result = pd.Series(feature_data).ewm(alpha=alpha, adjust=False).mean().values + return self._clean_feature(result) + except Exception: + return feature_data + + def _safe_momentum(self, feature_data): + """Safe momentum calculation using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'momentum') + else: + try: + periods = self.rng.choice([1, 2, 3, 5, 7, 10]) + periods = min(periods, len(feature_data) - 1) + series = pd.Series(feature_data) + momentum = series - series.shift(periods) + result = momentum.fillna(0).values + return self._clean_feature(result) + except Exception: + return np.zeros_like(feature_data) + + def _safe_seasonal_decompose(self, feature_data): + """Safe seasonal decomposition using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'seasonal_decompose') + else: + try: + # Simple seasonal pattern extraction + series = pd.Series(feature_data) + # Create a simple seasonal pattern based on position in series + season_length = min(365, len(series) // 4) if len(series) > 365 else len(series) // 4 + if season_length < 2: + return feature_data + seasonal = series.rolling(window=season_length, center=True, min_periods=1).mean() + return self._clean_feature(seasonal.fillna(series.mean()).values) + except Exception: + return feature_data + + def _safe_trend_feature(self, feature_data): + """Safe trend feature using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'trend') + else: + try: + window_size = self.rng.choice([7, 14, 30, 60]) + window_size = min(window_size, len(feature_data)) + series = pd.Series(feature_data) + # Simple trend as rolling linear regression slope + result = series.rolling(window=window_size, min_periods=2).apply( + lambda x: np.polyfit(range(len(x)), x, 1)[0] if len(x) > 1 else 0, raw=True + ) + return self._clean_feature(result.fillna(0).values) + except Exception: + return np.zeros_like(feature_data) + + def _safe_weekday_mean(self, feature_data): + """Safe weekday mean using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'weekday_mean') + else: + # Fallback: create simple cyclical feature + try: + result = np.sin(2 * np.pi * np.arange(len(feature_data)) / 7) + return self._clean_feature(result * np.std(feature_data) + np.mean(feature_data)) + except Exception: + return feature_data + + def _safe_month_mean(self, feature_data): + """Safe month mean using time-based operations""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'month_mean') + else: + # Fallback: create simple cyclical feature + try: + result = np.sin(2 * np.pi * np.arange(len(feature_data)) / 30) + return self._clean_feature(result * np.std(feature_data) + np.mean(feature_data)) + except Exception: + return feature_data + + # Updated fit method to handle DataFrame input with datetime column (unchanged from previous version) + def fit(self, X, y, gen_size=5, random_state=0, iterations=5, estimator='avg', feat_imps=True, split_feats=None, check_corr=True, selection='stability', combine_res=True): - """ Generated Features using test set """ + """ Generated Features using test set - Enhanced for datetime-aware time series operations """ + + if self.verbose and self.enable_time_series: + print( + f"Starting BigFeat with time-based series support. Data shape: {X.shape if hasattr(X, 'shape') else len(X)}") + + # Store original data if it's a DataFrame (for datetime column access) + if isinstance(X, pd.DataFrame): + self.original_data = X.copy() + # Identify feature columns by excluding datetime and groupby columns + exclude_cols = [] + if self.datetime_col and self.datetime_col in X.columns: + exclude_cols.append(self.datetime_col) + exclude_cols.extend([col for col in self.groupby_cols if col in X.columns]) + + # Get all potential feature columns + all_feature_cols = [col for col in X.columns if col not in exclude_cols] + + # Filter out any non-numeric columns more carefully + numeric_feature_cols = [] + for col in all_feature_cols: + col_dtype = str(X[col].dtype) + # Skip datetime-like columns and object columns that might contain timestamps + if (col_dtype.startswith('datetime') or + col_dtype.startswith(' 0 else None + if sample_val is not None and hasattr(sample_val, 'year'): + # Likely a datetime object + if self.verbose: + print(f"Warning: Skipping datetime-like column '{col}'") + continue + except: + pass + else: + if self.verbose: + print(f"Warning: Skipping datetime column '{col}' (type: {col_dtype})") + continue + + # Test if the column is actually numeric + try: + # Try to convert a sample to float + test_val = X[col].dropna().iloc[0] if len(X[col].dropna()) > 0 else 0 + float(test_val) + numeric_feature_cols.append(col) + except (ValueError, TypeError): + if self.verbose: + print(f"Warning: Skipping non-numeric column '{col}' (type: {col_dtype})") + continue + + self.feature_columns = numeric_feature_cols + # Extract feature data for processing + if len(self.feature_columns) > 0: + X_features = X[self.feature_columns].values + # Ensure all values are numeric - this should now be safe + X_features = np.array(X_features, dtype=float) + else: + raise ValueError("No numeric feature columns found after filtering!") + else: + X_features = X + # Ensure it's numeric + X_features = np.array(X_features, dtype=float) + if hasattr(X, 'columns'): + self.feature_columns = list(X.columns) + else: + self.feature_columns = [f'feature_{i}' for i in range(X_features.shape[1])] + + # Prepare time series data + if self.enable_time_series: + self._current_data = self._prepare_time_series_data(X) + + # Original initialization - unchanged self.selection = selection self.imp_operators = np.ones(len(self.operators)) self.operator_weights = self.imp_operators / self.imp_operators.sum() self.gen_steps = [] - self.n_feats = X.shape[1] - self.n_rows = X.shape[0] + self.n_feats = X_features.shape[1] + self.n_rows = X_features.shape[0] self.ig_vector = np.ones(self.n_feats) / self.n_feats self.comb_mat = np.ones((self.n_feats, self.n_feats)) self.split_vec = np.ones(self.n_feats) - # Set RNG seed if provided for numpy + + # Set RNG seed if provided for numpy - original self.rng = np.random.RandomState(seed=random_state) + + # Original variable initialization gen_feats = np.zeros((self.n_rows, self.n_feats * gen_size)) iters_comb = np.zeros((self.n_rows, self.n_feats * iterations)) depths_comb = np.zeros(self.n_feats * iterations) @@ -61,37 +791,53 @@ def fit(self, X, y, gen_size=5, random_state=0, iterations=5, estimator='avg', self.depth_range = np.arange(3) + 1 self.depth_weights = 1 / (2 ** self.depth_range) self.depth_weights /= self.depth_weights.sum() + + # Original scaling self.scaler = MinMaxScaler() - self.scaler.fit(X) - X = self.scaler.transform(X) + self.scaler.fit(X_features) + X_scaled = self.scaler.transform(X_features) + + # Original feature importance calculation if feat_imps: - self.ig_vector, estimators = self.get_feature_importances(X, y, estimator, random_state) + self.ig_vector, estimators = self.get_feature_importances(X_scaled, y, estimator, random_state) self.ig_vector /= self.ig_vector.sum() for tree in estimators: - paths = self.get_paths(tree, np.arange(X.shape[1])) + paths = self.get_paths(tree, np.arange(X_scaled.shape[1])) self.get_split_feats(paths, self.split_vec) self.split_vec /= self.split_vec.sum() - # self.split_vec = StandardScaler().fit_transform(self.split_vec.reshape(1, -1), {'var_':5}) + if split_feats == "comb": self.ig_vector = np.multiply(self.ig_vector, self.split_vec) self.ig_vector /= self.ig_vector.sum() elif split_feats == "splits": self.ig_vector = self.split_vec + + # Original iteration loop with enhanced time series support for iteration in range(iterations): + if self.verbose: + print(f"Feature generation iteration {iteration + 1}/{iterations}") + self.tracking_ops = [] self.tracking_ids = [] gen_feats = np.zeros((self.n_rows, self.n_feats * gen_size)) self.feat_depths = np.zeros(gen_feats.shape[1]) + for i in range(gen_feats.shape[1]): dpth = self.rng.choice(self.depth_range, p=self.depth_weights) ops = [] ids = [] - gen_feats[:, i] = self.feat_with_depth(X, dpth, ops, ids) # ops and ids are updated + gen_feats[:, i] = self.feat_with_depth(X_scaled, dpth, ops, ids) # ops and ids are updated + # Clean generated feature if time series is enabled + if self.enable_time_series: + gen_feats[:, i] = self._clean_feature(gen_feats[:, i]) self.feat_depths[i] = dpth self.tracking_ops.append(ops) self.tracking_ids.append(ids) + self.tracking_ids = np.array(self.tracking_ids + [[]], dtype='object')[:-1] self.tracking_ops = np.array(self.tracking_ops + [[]], dtype='object')[:-1] + + # Original feature selection within iteration imps, estimators = self.get_feature_importances(gen_feats, y, estimator, random_state) total_feats = np.argsort(imps) feat_args = total_feats[-self.n_feats:] @@ -99,16 +845,22 @@ def fit(self, X, y, gen_size=5, random_state=0, iterations=5, estimator='avg', self.tracking_ids = self.tracking_ids[feat_args] self.tracking_ops = self.tracking_ops[feat_args] self.feat_depths = self.feat_depths[feat_args] + + # Original combination tracking depths_comb[iteration * self.n_feats:(iteration + 1) * self.n_feats] = self.feat_depths ids_comb[iteration * self.n_feats:(iteration + 1) * self.n_feats] = self.tracking_ids ops_comb[iteration * self.n_feats:(iteration + 1) * self.n_feats] = self.tracking_ops iters_comb[:, iteration * self.n_feats:(iteration + 1) * self.n_feats] = gen_feats + + # Original operator importance update - now includes time series operators for i, op in enumerate(self.operators): for feat in self.tracking_ops: for feat_op in feat: if op == feat_op[0]: self.imp_operators[i] += 1 self.operator_weights = self.imp_operators / self.imp_operators.sum() + + # Original final selection logic if selection == 'stability' and iterations > 1 and combine_res: imps, estimators = self.get_feature_importances(iters_comb, y, estimator, random_state) total_feats = np.argsort(imps) @@ -123,7 +875,9 @@ def fit(self, X, y, gen_size=5, random_state=0, iterations=5, estimator='avg', self.tracking_ids = np.delete(self.tracking_ids, to_drop_cor) self.tracking_ops = np.delete(self.tracking_ops, to_drop_cor) self.feat_depths = np.delete(self.feat_depths, to_drop_cor) - gen_feats = np.hstack((gen_feats, X)) + + # Original final combination + gen_feats = np.hstack((gen_feats, X_scaled)) if selection == 'fAnova': # Use the appropriate feature selection method based on task type @@ -133,225 +887,284 @@ def fit(self, X, y, gen_size=5, random_state=0, iterations=5, estimator='avg', self.fAnova_best = SelectKBest(f_regression, k=self.n_feats) gen_feats = self.fAnova_best.fit_transform(gen_feats, y) + if self.verbose: + print(f"Feature generation completed. Final shape: {gen_feats.shape}") + if self.enable_time_series: + ts_ops_count = sum(1 for ops in self.tracking_ops + for op_info in ops + if len(op_info) > 0 and callable(op_info[0]) and op_info[ + 0] in self.time_series_operators) + print(f"Time series operations used: {ts_ops_count}") + return gen_feats def transform(self, X): - """ Produce features from the fitted BigFeat object """ - X = self.scaler.transform(X) - self.n_rows = X.shape[0] + """ Produce features from the fitted BigFeat object - Enhanced for datetime-aware operations """ + + # Handle DataFrame input with datetime column + if isinstance(X, pd.DataFrame): + if self.feature_columns: + # Use the stored feature columns from fit + available_feature_cols = [col for col in self.feature_columns if col in X.columns] + if len(available_feature_cols) != len(self.feature_columns): + missing_cols = set(self.feature_columns) - set(available_feature_cols) + if self.verbose: + print(f"Warning: Some feature columns missing in transform data: {missing_cols}") + X_features = X[available_feature_cols].values + # Ensure numeric + X_features = np.array(X_features, dtype=float) + else: + # Exclude datetime and groupby columns if they exist + exclude_cols = [] + if self.datetime_col and self.datetime_col in X.columns: + exclude_cols.append(self.datetime_col) + exclude_cols.extend([col for col in self.groupby_cols if col in X.columns]) + + # Get potential feature columns + feature_cols = [col for col in X.columns if col not in exclude_cols] + + # Filter for numeric columns only using the same logic as fit + numeric_feature_cols = [] + for col in feature_cols: + col_dtype = str(X[col].dtype) + # Skip datetime-like columns + if (col_dtype.startswith('datetime') or + col_dtype.startswith(' 0 else None + if sample_val is not None and hasattr(sample_val, 'year'): + continue + except: + pass + else: + continue + + try: + test_val = X[col].dropna().iloc[0] if len(X[col].dropna()) > 0 else 0 + float(test_val) + numeric_feature_cols.append(col) + except (ValueError, TypeError): + continue + + X_features = X[numeric_feature_cols].values + X_features = np.array(X_features, dtype=float) + + # Update current data for time series operations + if self.enable_time_series: + self._current_data = self._prepare_time_series_data(X) + else: + X_features = X + X_features = np.array(X_features, dtype=float) + + X_scaled = self.scaler.transform(X_features) + self.n_rows = X_scaled.shape[0] gen_feats = np.zeros((self.n_rows, len(self.tracking_ids))) + for i in range(gen_feats.shape[1]): dpth = self.feat_depths[i] op_ls = self.tracking_ops[i].copy() id_ls = self.tracking_ids[i].copy() - gen_feats[:, i] = self.feat_with_depth_gen(X, dpth, op_ls, id_ls) - gen_feats = np.hstack((gen_feats, X)) + gen_feats[:, i] = self.feat_with_depth_gen(X_scaled, dpth, op_ls, id_ls) + # Clean generated feature if time series is enabled + if self.enable_time_series: + gen_feats[:, i] = self._clean_feature(gen_feats[:, i]) + + gen_feats = np.hstack((gen_feats, X_scaled)) + if self.selection == 'fAnova': gen_feats = self.fAnova_best.transform(gen_feats) + return gen_feats + # Enhanced feat_with_depth method to support datetime-aware operations + def feat_with_depth(self, X, depth, op_ls, feat_ls): + """ Recursively generate a new features - Enhanced to handle datetime-aware time series operators """ + if depth == 0: + feat_ind = self.rng.choice(np.arange(len(self.ig_vector)), p=self.ig_vector) + feat_ls.append(feat_ind) + # Set current feature index for time series operations + if self.enable_time_series: + self._current_feature_index = feat_ind + return X[:, feat_ind] + + depth -= 1 + op = self.rng.choice(self.operators, p=self.operator_weights) + + if op in self.binary_operators: + feat_1 = self.feat_with_depth(X, depth, op_ls, feat_ls) + feat_2 = self.feat_with_depth(X, depth, op_ls, feat_ls) + op_ls.append((op, depth)) + result = op(feat_1, feat_2) + return self._clean_feature(result) if self.enable_time_series else result + + elif op in self.unary_operators: + feat_1 = self.feat_with_depth(X, depth, op_ls, feat_ls) + op_ls.append((op, depth)) + result = op(feat_1) + return self._clean_feature(result) if self.enable_time_series else result + + def feat_with_depth_gen(self, X, depth, op_ls, feat_ls): + """ Reproduce generated features with new data - Enhanced to handle datetime-aware time series operators """ + if depth == 0: + feat_ind = feat_ls.pop() + # Set current feature index for time series operations + if self.enable_time_series: + self._current_feature_index = feat_ind + return X[:, feat_ind] + + depth -= 1 + op = op_ls.pop()[0] + + if op in self.binary_operators: + feat_1 = self.feat_with_depth_gen(X, depth, op_ls, feat_ls) + feat_2 = self.feat_with_depth_gen(X, depth, op_ls, feat_ls) + result = op(feat_2, feat_1) + return self._clean_feature(result) if self.enable_time_series else result + + elif op in self.unary_operators: + feat_1 = self.feat_with_depth_gen(X, depth, op_ls, feat_ls) + result = op(feat_1) + return self._clean_feature(result) if self.enable_time_series else result + + # Original methods - completely unchanged from previous version def select_estimator(self, X, y, estimators_names=None): """ - Select the best estimator based on cross-validation - - Parameters: - ----------- - X : array-like - Feature matrix - y : array-like - Target vector - estimators_names : list or None - List of estimator names to try. If None, uses appropriate defaults. - - Returns: - -------- - model : estimator - Fitted best estimator + Select the best estimator based on cross-validation - Original method """ - # Use appropriate default estimators based on task type if estimators_names is None: if self.task_type == 'classification': estimators_names = ['dt', 'lr'] else: # regression estimators_names = ['dt_reg', 'lr_reg'] - - # Define available estimators based on task type + estimators_dic = { - # Classification estimators 'dt': DecisionTreeClassifier(), 'lr': LogisticRegression(), 'rf': RandomForestClassifier(n_jobs=self.n_jobs), 'lgb': LGBMClassifier(), - # Regression estimators 'dt_reg': DecisionTreeRegressor(), 'lr_reg': LinearRegression(), 'rf_reg': RandomForestRegressor(n_jobs=self.n_jobs), 'lgb_reg': LGBMRegressor() } - + models_score = {} for estimator in estimators_names: model = estimators_dic[estimator] - - # Use appropriate scoring metric based on task type + if self.task_type == 'classification': scorer = make_scorer(f1_score) else: # regression scorer = make_scorer(r2_score) - + models_score[estimator] = cross_val_score(model, X, y, cv=3, scoring=scorer).mean() - + best_estimator = max(models_score, key=models_score.get) best_model = estimators_dic[best_estimator] best_model.fit(X, y) return best_model def get_feature_importances(self, X, y, estimator, random_state, sample_count=1, sample_size=3, n_jobs=1): - """Return feature importances by specified method""" - + """Return feature importances by specified method - Original method""" importance_sum = np.zeros(X.shape[1]) total_estimators = [] + for sampled in range(sample_count): sampled_ind = np.random.choice(np.arange(self.n_rows), size=self.n_rows // sample_size, replace=False) sampled_X = X[sampled_ind] sampled_y = np.take(y, sampled_ind) - - # Different behavior based on task type - if estimator == "rf": - if self.task_type == 'classification': + + if estimator in ["rf", "rf_reg"]: + if self.task_type == 'classification' or estimator == "rf": estm = RandomForestClassifier(random_state=random_state, n_jobs=n_jobs) - else: # regression + else: estm = RandomForestRegressor(random_state=random_state, n_jobs=n_jobs) - + estm.fit(sampled_X, sampled_y) total_importances = estm.feature_importances_ estimators = estm.estimators_ total_estimators += estimators - + elif estimator == "avg": - # For classification if self.task_type == 'classification': clf = RandomForestClassifier(random_state=random_state, n_jobs=n_jobs) clf.fit(sampled_X, sampled_y) rf_importances = clf.feature_importances_ estimators = clf.estimators_ total_estimators += estimators - - # LightGBM for classification + train_data = lgb.Dataset(sampled_X, label=sampled_y) param = {'num_leaves': 31, 'objective': 'binary', 'verbose': -1} param['metric'] = 'auc' - - # For regression + else: clf = RandomForestRegressor(random_state=random_state, n_jobs=n_jobs) clf.fit(sampled_X, sampled_y) rf_importances = clf.feature_importances_ estimators = clf.estimators_ total_estimators += estimators - - # LightGBM for regression + train_data = lgb.Dataset(sampled_X, label=sampled_y) param = {'num_leaves': 31, 'objective': 'regression', 'verbose': -1} param['metric'] = 'rmse' - - # Common LightGBM code for both tasks + num_round = 2 bst = lgb.train(param, train_data, num_round) lgb_imps = bst.feature_importance(importance_type='gain') lgb_imps /= lgb_imps.sum() total_importances = (rf_importances + lgb_imps) / 2 - + + else: + raise ValueError(f"Unsupported estimator: {estimator}") + importance_sum += total_importances return importance_sum, total_estimators def get_weighted_feature_importances(self, X, y, estimator, random_state): - """Return feature importances weighted by model performance""" + """Return feature importances weighted by model performance - Original method""" X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=random_state) - - # Choose appropriate model based on task type + if self.task_type == 'classification': estm = RandomForestClassifier(random_state=random_state, n_jobs=self.n_jobs) - else: # regression + else: estm = RandomForestRegressor(random_state=random_state, n_jobs=self.n_jobs) - + estm.fit(X_train, y_train) ests = estm.estimators_ model = estm imps = np.zeros((len(model.estimators_), X.shape[1])) scores = np.zeros(len(model.estimators_)) - + for i, each in enumerate(model.estimators_): - # Different scoring metrics based on task type if self.task_type == 'classification': y_probas_train = each.predict_proba(X_test)[:, 1] score = roc_auc_score(y_test, y_probas_train) - else: # regression + else: y_pred_train = each.predict(X_test) score = r2_score(y_test, y_pred_train) - + imps[i] = each.feature_importances_ scores[i] = score - + weights = scores / scores.sum() return np.average(imps, axis=0, weights=weights) - def feat_with_depth(self, X, depth, op_ls, feat_ls): - """ Recursively generate a new features """ - if depth == 0: - feat_ind = self.rng.choice(np.arange(len(self.ig_vector)), p=self.ig_vector) - feat_ls.append(feat_ind) - return X[:, feat_ind] - depth -= 1 - op = self.rng.choice(self.operators, p=self.operator_weights) - if op in self.binary_operators: - feat_1 = self.feat_with_depth(X, depth, op_ls, feat_ls) - feat_2 = self.feat_with_depth(X, depth, op_ls, feat_ls) - op_ls.append((op, depth)) - return op(feat_1, feat_2) - elif op in self.unary_operators: - feat_1 = self.feat_with_depth(X, depth, op_ls, feat_ls) - op_ls.append((op, depth)) - return op(feat_1) - - def feat_with_depth_gen(self, X, depth, op_ls, feat_ls): - """ Reproduce generated features with new data """ - if depth == 0: - feat_ind = feat_ls.pop() - return X[:, feat_ind] - depth -= 1 - op = op_ls.pop()[0] - if op in self.binary_operators: - feat_1 = self.feat_with_depth_gen(X, depth, op_ls, feat_ls) - feat_2 = self.feat_with_depth_gen(X, depth, op_ls, feat_ls) - return op(feat_2, feat_1) - elif op in self.unary_operators: - feat_1 = self.feat_with_depth_gen(X, depth, op_ls, feat_ls) - return op(feat_1) - def check_correlations(self, feats): - """ Check correlations among the selected features """ + """ Check correlations among the selected features - Original method """ cor_thresh = 0.8 corr_matrix = pd.DataFrame(feats).corr().abs() mask = np.tril(np.ones_like(corr_matrix, dtype=bool)) tri_df = corr_matrix.mask(mask) to_drop = [c for c in tri_df.columns if any(tri_df[c] > cor_thresh)] - # remove the feature with lower importance if corr > cor_thresh - # to_drop = [] - # for c in tri_df.columns: - # if any(corr_matrix[c] > cor_thresh): - # for c_, cor_val in enumerate(corr_matrix[c].values): - # if cor_val > cor_thresh and c != c_: - # if self.ig_vector_gen[c_] < self.ig_vector_gen[c] and c_ not in to_drop: - # to_drop.append(c_) - feats = pd.DataFrame(feats).drop(to_drop, axis=1) return feats.values, to_drop def get_paths(self, clf, feature_names): - """ Returns every path in the decision tree""" + """ Returns every path in the decision tree - Original method """ tree_ = clf.tree_ feature_name = [ feature_names[i] if i != _tree.TREE_UNDEFINED else "undefined!" @@ -379,15 +1192,15 @@ def recurse(node, depth, path_list): return new_list def get_combos(self, paths, comb_mat): - """ Fills Combination matrix with values """ + """ Fills Combination matrix with values - Original method """ for i in range(len(comb_mat)): for pt in paths: if i in pt: comb_mat[i][pt] += 1 def get_split_feats(self, paths, split_vec): - """ Fills split vector with values """ + """ Fills split vector with values - Original method """ for i in range(len(split_vec)): for pt in paths: if i in pt: - split_vec[i] += 1 + split_vec[i] += 1 \ No newline at end of file diff --git a/bigfeat/local_utils.py b/bigfeat/local_utils.py index e6aa5cf..d4e717b 100644 --- a/bigfeat/local_utils.py +++ b/bigfeat/local_utils.py @@ -1,41 +1,706 @@ import numpy as np import pandas as pd import scipy.stats +import warnings +# Suppress warnings for cleaner output +warnings.filterwarnings('ignore') + + +# Basic utility functions def unary_cube(arr): - return np.power(arr,3) + """Original cube transformation with overflow protection""" + try: + result = np.power(np.clip(arr, -100, 100), 3) + return np.clip(result, -1e10, 1e10) + except: + return arr + def unary_multinv(arr): - return 1/arr + """Safe multiplicative inverse""" + try: + # Avoid division by zero + arr_safe = np.where(np.abs(arr) < 1e-10, 1e-10, arr) + result = 1 / arr_safe + return np.clip(result, -1e10, 1e10) + except: + return arr + def unary_sqrtabs(arr): - return np.sqrt(np.abs(arr)) * np.sign(arr) + """Square root of absolute value with sign preservation""" + try: + result = np.sqrt(np.abs(arr)) * np.sign(arr) + return np.where(np.isfinite(result), result, 0) + except: + return arr + def unary_logabs(arr): - return np.log(np.abs(arr)) * np.sign(arr) + """Safe logarithm of absolute value with sign preservation""" + try: + abs_arr = np.abs(arr) + # Avoid log(0) by using a small positive number + abs_arr = np.where(abs_arr < 1e-10, 1e-10, abs_arr) + result = np.log(abs_arr) * np.sign(arr) + return np.where(np.isfinite(result), result, 0) + except: + return arr + def convert_with_max(arr): - arr[arr>np.finfo(np.dtype('float32')).max] = np.finfo(np.dtype('float32')).max - arr[arr np.finfo(np.dtype('float32')).max] = np.finfo(np.dtype('float32')).max + arr[arr < np.finfo(np.dtype('float32')).min] = np.finfo(np.dtype('float32')).min + return np.float32(arr) + except: + return np.float32(arr) + def mode(ar1): - return scipy.stats.mode(ar1)[0][0] + """Safe mode calculation""" + try: + if len(ar1) == 0: + return 0 + mode_result = scipy.stats.mode(ar1, keepdims=True) + return float(mode_result.mode[0]) + except: + return np.mean(ar1) if len(ar1) > 0 else 0 + + def ar_range(ar1): - return ar1.max()-ar1.min() + """Safe range calculation""" + try: + if len(ar1) == 0: + return 0 + return float(ar1.max() - ar1.min()) + except: + return 0 + + def percentile_25(ar1): - return np.percentile(ar1, 25) + """Safe 25th percentile""" + try: + if len(ar1) == 0: + return 0 + return float(np.percentile(ar1, 25)) + except: + return np.median(ar1) if len(ar1) > 0 else 0 + + def percentile_75(ar1): - return np.percentile(ar1, 75) + """Safe 75th percentile""" + try: + if len(ar1) == 0: + return 0 + return float(np.percentile(ar1, 75)) + except: + return np.median(ar1) if len(ar1) > 0 else 0 -def group_by(ar1,ar2): - group_by_ops =[np.mean,np.std,np.max,np.min,np.sum,mode,len,ar_range,np.median,percentile_25,percentile_75] - group_by_op = np.random.choice(group_by_ops) - temp_df=pd.DataFrame({'ar1':ar1, 'ar2':ar2}) - group_res = temp_df.groupby(['ar1'])['ar2'].apply(group_by_op).to_dict() - return temp_df['ar1'].map(group_res).values +def group_by(ar1, ar2): + """Enhanced group by operation with error handling""" + try: + group_by_ops = [np.mean, np.std, np.max, np.min, np.sum, mode, len, ar_range, np.median, percentile_25, + percentile_75] + group_by_op = np.random.choice(group_by_ops) + temp_df = pd.DataFrame({'ar1': ar1, 'ar2': ar2}) + group_res = temp_df.groupby(['ar1'])['ar2'].apply(group_by_op).to_dict() + result = temp_df['ar1'].map(group_res).values + return np.where(np.isfinite(result), result, np.mean(ar2)) + except: + return ar2 # Fallback to original array def original_feat(ar1): - return ar1 \ No newline at end of file + """Return original feature""" + return ar1 + + +# Enhanced Time Series Utility Functions +def safe_rolling_operation(arr, window, operation, fill_method='bfill', **kwargs): + """Safe wrapper for rolling operations""" + try: + if len(arr) == 0: + return arr + + series = pd.Series(arr) + window = min(window, len(arr)) # Ensure window doesn't exceed data length + + if operation == 'mean': + result = series.rolling(window=window, min_periods=1).mean() + elif operation == 'std': + result = series.rolling(window=window, min_periods=1).std() + elif operation == 'min': + result = series.rolling(window=window, min_periods=1).min() + elif operation == 'max': + result = series.rolling(window=window, min_periods=1).max() + elif operation == 'median': + result = series.rolling(window=window, min_periods=1).median() + elif operation == 'sum': + result = series.rolling(window=window, min_periods=1).sum() + elif operation == 'skew': + min_periods = min(window, 3) + result = series.rolling(window=window, min_periods=min_periods).skew() + elif operation == 'kurt': + min_periods = min(window, 4) + result = series.rolling(window=window, min_periods=min_periods).kurt() + elif operation == 'quantile': + q = kwargs.get('quantile', 0.5) + result = series.rolling(window=window, min_periods=1).quantile(q) + else: + return arr + + # Handle filling + if fill_method == 'bfill': + result = result.bfill() + elif fill_method == 'ffill': + result = result.ffill() + else: + result = result.fillna(0) + + # Ensure finite values + result = result.replace([np.inf, -np.inf], np.nan).fillna(0) + return result.values + + except Exception as e: + # Return original array on error + return arr + + +def exponential_moving_average(arr, alpha=0.3): + """Enhanced exponential moving average with validation""" + try: + if len(arr) == 0: + return arr + + alpha = np.clip(alpha, 0.01, 0.99) # Ensure valid alpha + series = pd.Series(arr) + result = series.ewm(alpha=alpha, adjust=False).mean() + return result.fillna(method='bfill').values + + except Exception as e: + return arr + + +def bollinger_bands_upper(arr, window=20, num_std=2): + """Enhanced Bollinger Bands upper band with validation""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + rolling_mean = series.rolling(window=window, min_periods=1).mean() + rolling_std = series.rolling(window=window, min_periods=1).std() + rolling_std = rolling_std.fillna(0) + upper_band = rolling_mean + (rolling_std * num_std) + return upper_band.fillna(method='bfill').values + + except Exception as e: + return arr + + +def bollinger_bands_lower(arr, window=20, num_std=2): + """Enhanced Bollinger Bands lower band with validation""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + rolling_mean = series.rolling(window=window, min_periods=1).mean() + rolling_std = series.rolling(window=window, min_periods=1).std() + rolling_std = rolling_std.fillna(0) + lower_band = rolling_mean - (rolling_std * num_std) + return lower_band.fillna(method='bfill').values + + except Exception as e: + return arr + + +def rsi(arr, window=14): + """Enhanced Relative Strength Index with validation""" + try: + if len(arr) <= 1: + return np.full_like(arr, 50.0) + + window = min(window, len(arr)) + series = pd.Series(arr) + delta = series.diff() + gain = (delta.where(delta > 0, 0)).rolling(window=window, min_periods=1).mean() + loss = (-delta.where(delta < 0, 0)).rolling(window=window, min_periods=1).mean() + + # Avoid division by zero + loss = loss.replace(0, 1e-10) + rs = gain / loss + rsi_values = 100 - (100 / (1 + rs)) + + return rsi_values.fillna(50).replace([np.inf, -np.inf], 50).values + + except Exception as e: + return np.full_like(arr, 50.0) + + +def macd(arr, fast=12, slow=26, signal=9): + """Enhanced MACD with validation""" + try: + if len(arr) == 0: + return arr + + series = pd.Series(arr) + ema_fast = series.ewm(span=min(fast, len(arr))).mean() + ema_slow = series.ewm(span=min(slow, len(arr))).mean() + macd_line = ema_fast - ema_slow + return macd_line.fillna(0).replace([np.inf, -np.inf], 0).values + + except Exception as e: + return np.zeros_like(arr) + + +def stochastic_oscillator(arr, window=14): + """Enhanced Stochastic Oscillator with validation""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + rolling_min = series.rolling(window=window, min_periods=1).min() + rolling_max = series.rolling(window=window, min_periods=1).max() + + # Avoid division by zero + denominator = rolling_max - rolling_min + denominator = denominator.replace(0, 1e-10) + + stoch_k = 100 * ((series - rolling_min) / denominator) + return stoch_k.fillna(50).replace([np.inf, -np.inf], 50).values + + except Exception as e: + return np.full_like(arr, 50.0) + + +def williams_r(arr, window=14): + """Enhanced Williams %R with validation""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + rolling_max = series.rolling(window=window, min_periods=1).max() + rolling_min = series.rolling(window=window, min_periods=1).min() + + # Avoid division by zero + denominator = rolling_max - rolling_min + denominator = denominator.replace(0, 1e-10) + + williams = -100 * ((rolling_max - series) / denominator) + return williams.fillna(-50).replace([np.inf, -np.inf], -50).values + + except Exception as e: + return np.full_like(arr, -50.0) + + +def momentum(arr, period=10): + """Enhanced momentum calculation with validation""" + try: + if len(arr) == 0: + return arr + + period = min(period, len(arr)) + series = pd.Series(arr) + momentum_val = series.diff(period) + return momentum_val.fillna(0).replace([np.inf, -np.inf], 0).values + + except Exception as e: + return np.zeros_like(arr) + + +def rate_of_change(arr, period=10): + """Enhanced rate of change with validation""" + try: + if len(arr) == 0: + return arr + + period = min(period, len(arr)) + series = pd.Series(arr) + roc = series.pct_change(period) * 100 + return roc.fillna(0).replace([np.inf, -np.inf], 0).values + + except Exception as e: + return np.zeros_like(arr) + + +def commodity_channel_index(arr, window=20): + """Enhanced Commodity Channel Index with validation""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + typical_price = series + sma = typical_price.rolling(window=window, min_periods=1).mean() + mean_deviation = typical_price.rolling(window=window, min_periods=1).apply( + lambda x: np.mean(np.abs(x - x.mean())) if len(x) > 0 else 1e-10 + ) + + # Avoid division by zero + mean_deviation = mean_deviation.replace(0, 1e-10) + cci = (typical_price - sma) / (0.015 * mean_deviation) + + return cci.fillna(0).replace([np.inf, -np.inf], 0).values + + except Exception as e: + return np.zeros_like(arr) + + +def safe_aroon_calculation(arr, window, direction='up'): + """Safe Aroon calculation helper""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + aroon_vals = np.zeros(len(series)) + + for i in range(len(series)): + if i < window: + period_data = series[:i + 1] + if direction == 'up': + periods_since_extreme = len(period_data) - 1 - period_data.idxmax() + else: + periods_since_extreme = len(period_data) - 1 - period_data.idxmin() + aroon_vals[i] = 100 * (len(period_data) - periods_since_extreme) / len(period_data) + else: + period_data = series[i - window + 1:i + 1] + if direction == 'up': + periods_since_extreme = len(period_data) - 1 - (period_data.idxmax() - (i - window + 1)) + else: + periods_since_extreme = len(period_data) - 1 - (period_data.idxmin() - (i - window + 1)) + aroon_vals[i] = 100 * (window - periods_since_extreme) / window + + return np.clip(aroon_vals, 0, 100) + + except Exception as e: + return np.full_like(arr, 50.0) + + +def aroon_up(arr, window=25): + """Enhanced Aroon Up with validation""" + return safe_aroon_calculation(arr, window, 'up') + + +def aroon_down(arr, window=25): + """Enhanced Aroon Down with validation""" + return safe_aroon_calculation(arr, window, 'down') + + +def average_true_range(arr, window=14): + """Enhanced Average True Range with validation""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + + # Simplified ATR using rolling high-low + high_low = series.rolling(window=2, min_periods=1).max() - series.rolling(window=2, min_periods=1).min() + true_range = high_low.fillna(0) + atr = true_range.rolling(window=window, min_periods=1).mean() + + return atr.fillna(0).replace([np.inf, -np.inf], 0).values + + except Exception as e: + return np.zeros_like(arr) + + +def parabolic_sar(arr, af_step=0.02, af_max=0.2): + """Enhanced Parabolic SAR with validation""" + try: + if len(arr) <= 1: + return arr.copy() + + series = pd.Series(arr) + psar = np.zeros(len(series)) + psar[0] = series.iloc[0] + + trend = 1 # 1 for uptrend, -1 for downtrend + af = af_step + ep = series.iloc[0] # extreme point + + for i in range(1, len(series)): + psar[i] = psar[i - 1] + af * (ep - psar[i - 1]) + + if trend == 1: # uptrend + if series.iloc[i] > ep: + ep = series.iloc[i] + af = min(af + af_step, af_max) + if series.iloc[i] < psar[i]: + trend = -1 + psar[i] = ep + af = af_step + ep = series.iloc[i] + else: # downtrend + if series.iloc[i] < ep: + ep = series.iloc[i] + af = min(af + af_step, af_max) + if series.iloc[i] > psar[i]: + trend = 1 + psar[i] = ep + af = af_step + ep = series.iloc[i] + + return np.where(np.isfinite(psar), psar, series.values) + + except Exception as e: + return arr + + +def safe_fibonacci_retracement(arr, window, level): + """Safe Fibonacci retracement calculation""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + rolling_max = series.rolling(window=window, min_periods=1).max() + rolling_min = series.rolling(window=window, min_periods=1).min() + fib_level = rolling_max - level * (rolling_max - rolling_min) + + return fib_level.fillna(method='bfill').replace([np.inf, -np.inf], series.median()).values + + except Exception as e: + return arr + + +def fibonacci_retracement_236(arr, window=50): + """Enhanced 23.6% Fibonacci retracement with validation""" + return safe_fibonacci_retracement(arr, window, 0.236) + + +def fibonacci_retracement_382(arr, window=50): + """Enhanced 38.2% Fibonacci retracement with validation""" + return safe_fibonacci_retracement(arr, window, 0.382) + + +def fibonacci_retracement_618(arr, window=50): + """Enhanced 61.8% Fibonacci retracement with validation""" + return safe_fibonacci_retracement(arr, window, 0.618) + + +# Additional advanced time series functions +def autocorrelation(arr, lag=1): + """Calculate autocorrelation with specified lag""" + try: + if len(arr) <= lag: + return np.zeros_like(arr) + + series = pd.Series(arr) + autocorr = series.rolling(window=min(20, len(arr)), min_periods=lag + 1).apply( + lambda x: np.corrcoef(x[:-lag], x[lag:])[0, 1] if len(x) > lag else 0 + ) + + return autocorr.fillna(0).replace([np.inf, -np.inf], 0).values + + except Exception as e: + return np.zeros_like(arr) + + +def rolling_entropy(arr, window=10): + """Calculate rolling entropy""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + + def entropy(x): + if len(x) == 0: + return 0 + try: + # Discretize the data + hist, _ = np.histogram(x, bins=min(10, len(x)), density=True) + hist = hist[hist > 0] # Remove zero entries + return -np.sum(hist * np.log(hist)) + except: + return 0 + + rolling_ent = series.rolling(window=window, min_periods=1).apply(entropy) + return rolling_ent.fillna(0).replace([np.inf, -np.inf], 0).values + + except Exception as e: + return np.zeros_like(arr) + + +def rolling_variance_ratio(arr, window=10): + """Calculate rolling variance ratio (variance / mean)""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + rolling_var = series.rolling(window=window, min_periods=1).var() + rolling_mean = series.rolling(window=window, min_periods=1).mean() + + # Avoid division by zero + rolling_mean = rolling_mean.replace(0, 1e-10) + var_ratio = rolling_var / np.abs(rolling_mean) + + return var_ratio.fillna(0).replace([np.inf, -np.inf], 0).values + + except Exception as e: + return np.zeros_like(arr) + + +def rolling_kurtosis_adjusted(arr, window=10): + """Calculate rolling excess kurtosis (kurtosis - 3)""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + min_periods = min(window, 4) + rolling_kurt = series.rolling(window=window, min_periods=min_periods).kurt() + + # Excess kurtosis (subtract 3 for normal distribution) + excess_kurt = rolling_kurt - 3 + return excess_kurt.fillna(0).replace([np.inf, -np.inf], 0).values + + except Exception as e: + return np.zeros_like(arr) + + +def trend_strength(arr, window=10): + """Calculate trend strength using linear regression slope""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + + def calc_slope(x): + if len(x) < 2: + return 0 + try: + y = np.array(x) + x_vals = np.arange(len(y)) + slope = np.polyfit(x_vals, y, 1)[0] + return slope + except: + return 0 + + trend = series.rolling(window=window, min_periods=2).apply(calc_slope) + return trend.fillna(0).replace([np.inf, -np.inf], 0).values + + except Exception as e: + return np.zeros_like(arr) + + +def mean_reversion_indicator(arr, window=20): + """Calculate mean reversion indicator""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + rolling_mean = series.rolling(window=window, min_periods=1).mean() + rolling_std = series.rolling(window=window, min_periods=1).std() + rolling_std = rolling_std.replace(0, 1e-10) + + # Distance from mean in standard deviations + mean_reversion = (series - rolling_mean) / rolling_std + return mean_reversion.fillna(0).replace([np.inf, -np.inf], 0).values + + except Exception as e: + return np.zeros_like(arr) + + +# Seasonal decomposition components +def seasonal_trend(arr, period=12): + """Extract trend component using moving average""" + try: + if len(arr) == 0 or period >= len(arr): + return arr + + series = pd.Series(arr) + # Use centered moving average for trend extraction + trend = series.rolling(window=period, center=True, min_periods=1).mean() + return trend.fillna(method='bfill').fillna(method='ffill').values + + except Exception as e: + return arr + + +def seasonal_residual(arr, period=12): + """Extract residual component after removing trend""" + try: + if len(arr) == 0: + return arr + + trend = seasonal_trend(arr, period) + residual = arr - trend + return residual + + except Exception as e: + return arr + + +# Frequency domain features +def dominant_frequency(arr, sample_rate=1.0): + """Find dominant frequency using FFT""" + try: + if len(arr) < 4: + return np.zeros_like(arr) + + # Apply FFT + fft_vals = np.fft.fft(arr - np.mean(arr)) + freqs = np.fft.fftfreq(len(arr), 1 / sample_rate) + + # Find dominant frequency + magnitude = np.abs(fft_vals) + dominant_freq_idx = np.argmax(magnitude[1:len(magnitude) // 2]) + 1 + dominant_freq = freqs[dominant_freq_idx] + + return np.full_like(arr, dominant_freq) + + except Exception as e: + return np.zeros_like(arr) + + +def spectral_energy(arr, window=10): + """Calculate rolling spectral energy""" + try: + if len(arr) == 0: + return arr + + window = min(window, len(arr)) + series = pd.Series(arr) + + def calc_spectral_energy(x): + if len(x) < 4: + return 0 + try: + fft_vals = np.fft.fft(x - np.mean(x)) + energy = np.sum(np.abs(fft_vals) ** 2) + return energy + except: + return 0 + + spectral_eng = series.rolling(window=window, min_periods=4).apply(calc_spectral_energy) + return spectral_eng.fillna(0).replace([np.inf, -np.inf], 0).values + + except Exception as e: + return np.zeros_like(arr) \ No newline at end of file diff --git a/docs/bigfeat-rolling-mean-complete-walkthrough.md b/docs/bigfeat-rolling-mean-complete-walkthrough.md new file mode 100644 index 0000000..7ef2280 --- /dev/null +++ b/docs/bigfeat-rolling-mean-complete-walkthrough.md @@ -0,0 +1,244 @@ +# BigFeat Rolling Mean: Complete Walkthrough + +## Step-by-Step Example + +Let's trace through exactly how BigFeat's rolling mean works from initialization to feature creation. + +## Sample Dataset + +```python +import pandas as pd +import numpy as np + +# Create sample time series data +df = pd.DataFrame({ + 'timestamp': pd.date_range('2024-01-01', periods=10, freq='D'), + 'store_id': ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'], + 'sales': [100, 120, 110, 130, 125, 80, 85, 90, 88, 92], + 'inventory': [500, 480, 490, 470, 475, 300, 285, 275, 277, 273] +}) + +print("Original Data:") +print(df) +``` + +**Output:** +``` + timestamp store_id sales inventory +0 2024-01-01 A 100 500 +1 2024-01-02 A 120 480 +2 2024-01-03 A 110 490 +3 2024-01-04 A 130 470 +4 2024-01-05 A 125 475 +5 2024-01-06 B 80 300 +6 2024-01-07 B 85 285 +7 2024-01-08 B 90 275 +8 2024-01-09 B 88 277 +9 2024-01-10 B 92 273 +``` + +## BigFeat Initialization + +```python +from enhanced_bigfeat import BigFeat + +bf = BigFeat( + task_type='regression', + enable_time_series=True, + datetime_col='timestamp', + groupby_cols=['store_id'], + window_sizes=['2D', '3D'], # 2-day and 3-day windows + verbose=True +) +``` + +## What Happens During `fit()` + +### **Step 1: Data Preparation** +```python +# BigFeat internally processes the DataFrame +self.original_data = df.copy() +self.feature_columns = ['sales', 'inventory'] # Excludes timestamp, store_id + +# Feature matrix extracted: +X_features = [[100, 500], [120, 480], [110, 490], ...] # Only numeric features +``` + +### **Step 2: Time Series Data Organization** +```python +# _prepare_time_series_data() organizes data by datetime and groups: +sorted_data = df.sort_values(['store_id', 'timestamp']) +``` + +### **Step 3: Feature Generation Loop** +During feature generation, BigFeat randomly selects operators. Let's say it selects `_safe_rolling_mean`: + +```python +# Randomly selected: rolling mean operation on 'sales' feature (index 0) +self._current_feature_index = 0 # 'sales' +self._current_data = prepared_time_series_data + +# Call rolling mean operator +result = self._safe_rolling_mean(X_scaled[:, 0]) # sales column +``` + +## Deep Dive: `_safe_rolling_mean` Execution + +### **Step 1: Time Series Check** +```python +def _safe_rolling_mean(self, feature_data): + if self.enable_time_series and hasattr(self, '_current_data'): + # Use time-aware operations + feature_col = 'sales' # self.feature_columns[0] + return self._apply_time_based_operation( + self._current_data, + feature_col, + 'rolling_mean' + ) +``` + +### **Step 2: Group-Based Processing** +```python +def _apply_time_based_operation(self, data, feature_col, operation): + # Group by store_id + results = [] + for store_id, group in data.groupby(['store_id']): + group_result = self._apply_single_group_operation( + group, feature_col, operation + ) + results.extend(group_result) + return np.array(results) +``` + +### **Step 3: Single Group Rolling Mean** + +**For Store A:** +```python +# Store A data (sorted by timestamp): +store_a_data = { + 'timestamp': ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05'], + 'sales': [100, 120, 110, 130, 125] +} + +# Randomly selected window: '3D' (3-day window) +window_size = pd.Timedelta('3D') + +# Rolling mean calculation with time-based window: +series = pd.Series([100, 120, 110, 130, 125]) +series.index = pd.to_datetime(['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05']) + +rolling_result = series.rolling(window='3D', min_periods=1).mean() +``` + +**Store A Rolling Mean Results:** +``` +2024-01-01: 100.0 # Only 1 day available: (100)/1 = 100.0 +2024-01-02: 110.0 # 2 days available: (100+120)/2 = 110.0 +2024-01-03: 110.0 # 3 days available: (100+120+110)/3 = 110.0 +2024-01-04: 120.0 # 3-day window: (120+110+130)/3 = 120.0 +2024-01-05: 121.67 # 3-day window: (110+130+125)/3 = 121.67 +``` + +**For Store B:** +```python +# Store B data: +store_b_data = { + 'timestamp': ['2024-01-06', '2024-01-07', '2024-01-08', '2024-01-09', '2024-01-10'], + 'sales': [80, 85, 90, 88, 92] +} + +# Same 3D window applied: +series = pd.Series([80, 85, 90, 88, 92]) +series.index = pd.to_datetime(['2024-01-06', '2024-01-07', '2024-01-08', '2024-01-09', '2024-01-10']) + +rolling_result = series.rolling(window='3D', min_periods=1).mean() +``` + +**Store B Rolling Mean Results:** +``` +2024-01-06: 80.0 # Only 1 day: (80)/1 = 80.0 +2024-01-07: 82.5 # 2 days: (80+85)/2 = 82.5 +2024-01-08: 85.0 # 3 days: (80+85+90)/3 = 85.0 +2024-01-09: 87.67 # 3-day window: (85+90+88)/3 = 87.67 +2024-01-10: 90.0 # 3-day window: (90+88+92)/3 = 90.0 +``` + +## Final Feature Combination + +### **Step 4: Combine Group Results** +```python +# Combined rolling mean feature for all rows: +combined_rolling_mean = [ + 100.0, # Store A, Day 1 + 110.0, # Store A, Day 2 + 110.0, # Store A, Day 3 + 120.0, # Store A, Day 4 + 121.67, # Store A, Day 5 + 80.0, # Store B, Day 1 + 82.5, # Store B, Day 2 + 85.0, # Store B, Day 3 + 87.67, # Store B, Day 4 + 90.0 # Store B, Day 5 +] +``` + +### **Step 5: Feature Matrix Assembly** +```python +# This rolling mean becomes one column in the generated feature matrix: +gen_feats = np.array([ + [100.0, other_feature_1, other_feature_2, ...], # Row 0 + [110.0, other_feature_1, other_feature_2, ...], # Row 1 + [110.0, other_feature_1, other_feature_2, ...], # Row 2 + # ... etc +]) +``` + +## Key Points + +### **1. Time-Aware Windows** +- Uses **actual time differences**, not just row positions +- `'3D'` means 3 calendar days, regardless of data frequency +- Handles irregular time series gracefully + +### **2. Group Isolation** +- Store A's rolling mean **never uses Store B's data** +- Each entity maintains its own temporal patterns +- Prevents data leakage between groups + +### **3. Window Boundaries** +```python +# For 3-day window on 2024-01-04: +# Looks back 3 days: 2024-01-01 to 2024-01-04 +# Includes: [2024-01-02, 2024-01-03, 2024-01-04] values +# Rolling mean = (120 + 110 + 130) / 3 = 120.0 +``` + +### **4. Fallback Behavior** +If time series fails or is disabled: +```python +else: + # Fallback to simple pandas rolling + window_size = self.rng.choice([3, 5, 7, 10]) # Row-based window + result = pd.Series(feature_data).rolling(window=window_size).mean() +``` + +## Complete Example Output + +**Original Data:** +``` +sales: [100, 120, 110, 130, 125, 80, 85, 90, 88, 92] +store_id: [ A, A, A, A, A, B, B, B, B, B ] +``` + +**Rolling Mean Feature (3D window):** +``` +rolling_mean: [100, 110, 110, 120, 121.67, 80, 82.5, 85, 87.67, 90] +``` + +**Why This Works:** +- ✅ **Temporal accuracy**: Uses actual dates, not just positions +- ✅ **Group isolation**: Store A and B calculated separately +- ✅ **Pattern preservation**: Each store's trend captured independently +- ✅ **No data leakage**: Future data never influences past calculations + +This is how BigFeat transforms raw time series data into powerful temporal features while respecting entity boundaries and temporal order! \ No newline at end of file diff --git a/docs/bigfeat-time-series-complete-usage-guide.md b/docs/bigfeat-time-series-complete-usage-guide.md new file mode 100644 index 0000000..b5c1b60 --- /dev/null +++ b/docs/bigfeat-time-series-complete-usage-guide.md @@ -0,0 +1,1244 @@ +# BigFeat Time Series Operations: Complete Usage Guide + +## Table of Contents +1. [Quick Start](#quick-start) +2. [Basic Setup](#basic-setup) +3. [Data Preparation](#data-preparation) +4. [Configuration Examples](#configuration-examples) +5. [Single vs Multi-Series Data](#single-vs-multi-series-data) +6. [Advanced Usage Patterns](#advanced-usage-patterns) +7. [Troubleshooting](#troubleshooting) +8. [Real-World Examples](#real-world-examples) +9. [Performance Optimization](#performance-optimization) +10. [Best Practices](#best-practices) + +## Quick Start + +### Minimal Example + +```python +from bigfeat.bigfeat import BigFeat # Updated import +import pandas as pd + +# Your time series data +df = pd.DataFrame({ + 'Date': pd.date_range('2023-01-01', periods=100), + 'value1': np.random.randn(100).cumsum(), + 'value2': np.random.randn(100), + 'target': np.random.randint(0, 2, 100) +}) + +# Initialize BigFeat with time series support +bigfeat = BigFeat( + task_type='classification', + enable_time_series=True, + datetime_col='Date', + time_step='D' +) + +# Generate enhanced features +X_enhanced = bigfeat.fit(df, df['target']) + +# Apply to new data +X_new_enhanced = bigfeat.transform(new_df) +``` + +## Basic Setup + +### 1. Import Required Libraries + +```python +import pandas as pd +import numpy as np +from bigfeat.bigfeat import BigFeat +from sklearn.model_selection import train_test_split +from sklearn.metrics import accuracy_score, r2_score +``` + +### 2. Initialize BigFeat with Time Series + +```python +# Basic time series configuration +bigfeat = BigFeat( + task_type='classification', # or 'regression' + enable_time_series=True, # Enable TS features + datetime_col='Date', # Name of datetime column + window_sizes=['3D', '7D', '14D', '30D'], # Rolling window options + lag_periods=['1D', '3D', '7D', '14D'], # Lag options + time_step='D', # Time step for resampling + verbose=True # Show progress +) +``` + +### 3. Key Parameters Explained + +| Parameter | Purpose | Example Values | +|-----------|---------|----------------| +| `enable_time_series` | Activates time series operators | `True`/`False` | +| `datetime_col` | Name of datetime column | `'Date'`, `'timestamp'`, `'time'` | +| `groupby_cols` | Columns for multi-series grouping | `['Symbol']`, `['store_id', 'product']` | +| `window_sizes` | Time-based rolling window options (str or pd.Timedelta) | `['3D', '7D', '14D', '30D']` | +| `lag_periods` | Time-based lag period options (str or pd.Timedelta) | `['1D', '3D', '7D', '14D']` | +| `time_step` | Time step for resampling | `'D'`, `'H'`, `'W'`, `'M'` | +| `verbose` | Print progress | `True`/`False` | + +## Data Preparation + +### Required Data Format +Your DataFrame must include: + +- **DateTime column**: Properly formatted datetime data +- **Feature columns**: Numeric columns for feature generation +- **Target column**: What you want to predict (separate from DataFrame) + +### Example Data Structures + +#### Stock Market Data + +```python +df = pd.DataFrame({ + 'Date': pd.date_range('2023-01-01', periods=252), + 'Symbol': ['AAPL'] * 252, + 'Open': np.random.uniform(150, 200, 252), + 'High': np.random.uniform(150, 200, 252), + 'Low': np.random.uniform(150, 200, 252), + 'Close': np.random.uniform(150, 200, 252), + 'Volume': np.random.uniform(1e6, 1e8, 252), + 'target': np.random.randint(0, 2, 252) # Price up/down +}) + +# Ensure datetime column is properly formatted +df['Date'] = pd.to_datetime(df['Date']) + +# Sort by time (crucial for time series) +df = df.sort_values(['Symbol', 'Date']).reset_index(drop=True) +``` + +#### Retail Sales Data + +```python +df = pd.DataFrame({ + 'Date': pd.date_range('2023-01-01', periods=365), + 'Store': np.random.choice(['A', 'B', 'C'], 365), + 'Sales': np.random.uniform(1000, 5000, 365), + 'Customers': np.random.uniform(50, 200, 365), + 'Temperature': np.random.uniform(0, 35, 365), + 'IsWeekend': np.random.choice([0, 1], 365), + 'target': np.random.uniform(2000, 6000, 365) # Next day sales +}) + +df['Date'] = pd.to_datetime(df['Date']) +df = df.sort_values(['Store', 'Date']).reset_index(drop=True) +``` + +#### IoT Sensor Data + +```python +df = pd.DataFrame({ + 'timestamp': pd.date_range('2023-01-01', periods=8760, freq='h'), + 'sensor_id': np.random.choice(['S1', 'S2', 'S3'], 8760), + 'temperature': np.random.uniform(20, 80, 8760), + 'humidity': np.random.uniform(30, 90, 8760), + 'pressure': np.random.uniform(980, 1020, 8760), + 'target': np.random.randint(0, 2, 8760) # Anomaly detection +}) + +df['timestamp'] = pd.to_datetime(df['timestamp']) +df = df.sort_values(['sensor_id', 'timestamp']).reset_index(drop=True) +``` + +## Configuration Examples + +### 1. Financial Markets + +```python +# High-frequency trading +bigfeat = BigFeat( + task_type='classification', + enable_time_series=True, + datetime_col='timestamp', + groupby_cols=['symbol'], + window_sizes=['3D', '7D', '14D', '30D'], # 3 days to 1 month + lag_periods=['1D', '3D', '7D', '14D'], # 1 day to 2 weeks + time_step='D', + verbose=True +) + +# Daily stock analysis +bigfeat = BigFeat( + task_type='regression', + enable_time_series=True, + datetime_col='Date', + groupby_cols=['Symbol'], + window_sizes=['7D', '14D', '30D', '90D'], # 1 week to 3 months + lag_periods=['1D', '7D', '14D', '30D'], # 1 day to 1 month + time_step='D', + verbose=True +) +``` + +### 2. Business Analytics + +```python +# Retail sales forecasting +bigfeat = BigFeat( + task_type='regression', + enable_time_series=True, + datetime_col='Date', + groupby_cols=['Store', 'Product'], + window_sizes=['7D', '14D', '30D', '90D'], # 1 week to 3 months + lag_periods=['1D', '7D', '14D', '30D'], # 1 day to 1 month + time_step='D', + verbose=True +) + +# Website analytics +bigfeat = BigFeat( + task_type='classification', + enable_time_series=True, + datetime_col='date', + window_sizes=['7D', '14D', '28D'], # 1-4 weeks + lag_periods=['1D', '7D', '14D'], # Recent history + time_step='D', + verbose=True +) +``` + +### 3. Industrial IoT + +```python +# Manufacturing equipment monitoring +bigfeat = BigFeat( + task_type='classification', + enable_time_series=True, + datetime_col='timestamp', + groupby_cols=['machine_id', 'line'], + window_sizes=['1H', '6H', '12H', '24H'], # 1 hour to 1 day + lag_periods=['1H', '6H', '12H'], # 1 hour to 12 hours + time_step='H', + verbose=True +) + +# Environmental monitoring +bigfeat = BigFeat( + task_type='regression', + enable_time_series=True, + datetime_col='datetime', + groupby_cols=['station_id'], + window_sizes=['24H', '72H', '7D'], # 1 day to 1 week (hourly data) + lag_periods=['1H', '12H', '24H', '72H'], # 1 hour to 3 days + time_step='H', + verbose=True +) +``` + +## Single vs Multi-Series Data + +### Single Time Series (No Grouping) + +```python +# Simple temperature forecasting +df = pd.DataFrame({ + 'Date': pd.date_range('2023-01-01', periods=365), + 'temperature': 20 + 10 * np.sin(np.arange(365) * 2 * np.pi / 365), + 'humidity': np.random.uniform(40, 80, 365), + 'pressure': np.random.uniform(990, 1010, 365) +}) + +# No groupby columns needed +bigfeat = BigFeat( + task_type='regression', + enable_time_series=True, + datetime_col='Date', + # groupby_cols=[] # Empty or omit entirely + window_sizes=['7D', '14D', '30D'], + lag_periods=['1D', '7D', '14D'], + time_step='D' +) + +# Target: predict next day temperature +target = df['temperature'].shift(-1).fillna(method='ffill') +X_enhanced = bigfeat.fit(df, target) +``` + +### Multi-Series Data (With Grouping) + +```python +# Multiple stock symbols +df = pd.DataFrame({ + 'Date': pd.date_range('2023-01-01', periods=500).repeat(3), + 'Symbol': ['AAPL', 'GOOGL', 'MSFT'] * 500, + 'Price': np.random.uniform(100, 300, 1500), + 'Volume': np.random.uniform(1e6, 1e8, 1500) +}) + +# Group by Symbol to prevent cross-contamination +bigfeat = BigFeat( + task_type='classification', + enable_time_series=True, + datetime_col='Date', + groupby_cols=['Symbol'], # Critical for multi-series + window_sizes=['3D', '7D', '14D', '21D'], + lag_periods=['1D', '3D', '7D'], + time_step='D' +) + +target = (df['Price'].shift(-1) > df['Price']).astype(int) +X_enhanced = bigfeat.fit(df, target) +``` + +## Advanced Usage Patterns + +### 1. Custom Window and Lag Configurations + +```python +# Adaptive configuration based on data frequency +def get_adaptive_config(data_freq, data_length): + if data_freq == 'D': # Daily + windows = ['3D', '7D', '14D', '30D'] + lags = ['1D', '3D', '7D', '14D'] + elif data_freq == 'H': # Hourly + windows = ['1H', '3H', '6H', '12H', '1D'] + lags = ['1H', '3H', '6H', '12H'] + elif data_freq == 'W': # Weekly + windows = ['1W', '2W', '4W', '12W'] + lags = ['1W', '2W', '4W'] + + # Adjust for data length + max_window = data_length // 10 + windows = [w for w in windows if w <= max_window] + + return windows, lags + +# Apply adaptive configuration +windows, lags = get_adaptive_config('D', len(df)) +bigfeat = BigFeat( + enable_time_series=True, + datetime_col='Date', + window_sizes=windows, + lag_periods=lags, + time_step='D' +) +``` + +### 2. Feature Generation Control + +```python +# More aggressive feature generation +bigfeat = BigFeat( + task_type='regression', + enable_time_series=True, + datetime_col='Date', + groupby_cols=['ID'], + window_sizes=['3D', '7D', '14D', '30D', '60D'], + lag_periods=['1D', '3D', '7D', '14D', '30D'], + time_step='D', + verbose=True +) + +# Generate more features with more iterations +X_enhanced = bigfeat.fit( + df, target, + gen_size=10, # Generate 10 features per iteration + iterations=5, # Run 5 iterations + estimator='avg', # Use ensemble estimator + selection='stability' # Use stability selection +) +``` + +### 3. Incremental Processing for Large Datasets + +```python +# Process data in chunks for memory efficiency +def process_large_dataset(df, target, chunk_size=10000): + # Initial fit on first chunk + first_chunk = df.iloc[:chunk_size] + first_target = target.iloc[:chunk_size] + + bigfeat = BigFeat( + enable_time_series=True, + datetime_col='Date', + groupby_cols=['ID'], + verbose=False + ) + + X_enhanced = bigfeat.fit(first_chunk, first_target) + + # Transform remaining chunks + results = [X_enhanced] + for i in range(chunk_size, len(df), chunk_size): + chunk = df.iloc[i:i+chunk_size] + X_chunk = bigfeat.transform(chunk) + results.append(X_chunk) + + return np.vstack(results) +``` + +## Troubleshooting + +### Common Issues and Solutions + +#### 1. "No numeric feature columns found" + +```python +# Problem: DataFrame contains only datetime/categorical columns +df = pd.DataFrame({ + 'Date': pd.date_range('2023-01-01', periods=100), + 'Category': ['A', 'B'] * 50, + 'Status': ['Active', 'Inactive'] * 50 +}) + +# Solution: Create numeric features first +df['Category_encoded'] = pd.factorize(df['Category'])[0] +df['Status_encoded'] = pd.factorize(df['Status'])[0] +# Now BigFeat can work with Category_encoded and Status_encoded +``` + +#### 2. "Shape mismatch" errors + +```python +# Problem: Inconsistent data shapes during transform +# Solution: Ensure consistent column structure + +# During fit +train_df = df[['Date', 'feature1', 'feature2', 'feature3']] +bigfeat.fit(train_df, target) + +# During transform - use same columns +test_df = test_df[['Date', 'feature1', 'feature2', 'feature3']] +X_enhanced = bigfeat.transform(test_df) +``` + +#### 3. Poor time series performance + +```python +# Problem: Data not properly sorted by time +df = df.sample(frac=1) # Random shuffle - BAD! + +# Solution: Always sort by datetime (and groupby columns) +df = df.sort_values(['GroupCol', 'Date']).reset_index(drop=True) + +# Problem: Window sizes too large for dataset +bigfeat = BigFeat(window_sizes=['100D', '200D']) # Bad for 300-row dataset + +# Solution: Scale windows to data size +max_window = len(df) // 10 +window_sizes = [w for w in ['3D', '7D', '14D', '30D'] if w <= max_window] +``` + +#### 4. Memory issues with large datasets + +```python +# Problem: Out of memory with large time series +# Solution: Reduce parameters or process in chunks + +# Lighter configuration +bigfeat = BigFeat( + enable_time_series=True, + datetime_col='Date', + window_sizes=['3D', '7D'], # Fewer options + lag_periods=['1D', '3D'], # Fewer options + gen_size=3, # Fewer generated features + iterations=2 # Fewer iterations +) +``` + +## Real-World Examples + +### Example 1: Stock Price Direction Prediction + +```python +import yfinance as yf + +# Download stock data +ticker = yf.Ticker("AAPL") +df = ticker.history(period="2y") +df = df.reset_index() + +# Add technical features +df['Returns'] = df['Close'].pct_change() +df['Volatility'] = df['Returns'].rolling(20).std() +df['Volume_MA'] = df['Volume'].rolling(20).mean() + +# Create target: next day price direction +df['Next_Return'] = df['Returns'].shift(-1) +df['Price_Up'] = (df['Next_Return'] > 0).astype(int) + +# Remove missing values +df = df.dropna() + +# Configure BigFeat for stock analysis +bigfeat = BigFeat( + task_type='classification', + enable_time_series=True, + datetime_col='Date', + window_sizes=['3D', '7D', '14D', '30D'], # 3 days to 1 month + lag_periods=['1D', '3D', '7D'], # 1-7 days back + time_step='D', + verbose=True +) + +# Features to use (exclude target and date) +feature_cols = ['Open', 'High', 'Low', 'Close', 'Volume', 'Returns', 'Volatility', 'Volume_MA'] +X = df[['Date'] + feature_cols] +y = df['Price_Up'] + +# Time series split +split_idx = int(0.8 * len(df)) +X_train, X_test = X.iloc[:split_idx], X.iloc[split_idx:] +y_train, y_test = y.iloc[:split_idx], y.iloc[split_idx:] + +# Generate enhanced features +X_train_enhanced = bigfeat.fit(X_train, y_train, + gen_size=5, + iterations=3, + estimator='rf') + +X_test_enhanced = bigfeat.transform(X_test) + +# Train final model +from sklearn.ensemble import RandomForestClassifier +model = RandomForestClassifier(random_state=42) +model.fit(X_train_enhanced, y_train) + +# Evaluate +predictions = model.predict(X_test_enhanced) +accuracy = accuracy_score(y_test, predictions) +print(f"Accuracy with time series features: {accuracy:.4f}") +``` + +### Example 2: Retail Sales Forecasting + +```python +# Create synthetic retail data +np.random.seed(42) +dates = pd.date_range('2022-01-01', periods=730, freq='D') +stores = ['Store_A', 'Store_B', 'Store_C'] + +data = [] +for store in stores: + for i, date in enumerate(dates): + # Base sales with trends and seasonality + base_sales = 1000 + i * 2 # Growing trend + seasonal = 500 * np.sin(2 * np.pi * date.dayofyear / 365) # Yearly + weekly = 200 * np.sin(2 * np.pi * date.weekday / 7) # Weekly + weekend_boost = 300 if date.weekday >= 5 else 0 + noise = np.random.normal(0, 100) + + sales = base_sales + seasonal + weekly + weekend_boost + noise + + data.append({ + 'Date': date, + 'Store': store, + 'Sales': sales, + 'DayOfWeek': date.weekday, + 'Month': date.month, + 'IsWeekend': int(date.weekday >= 5) + }) + +df = pd.DataFrame(data) + +# Create target: next day sales +df['NextDaySales'] = df.groupby('Store')['Sales'].shift(-1) +df = df.dropna() + +# Configure for retail forecasting +bigfeat = BigFeat( + task_type='regression', + enable_time_series=True, + datetime_col='Date', + groupby_cols=['Store'], # Separate analysis per store + window_sizes=['7D', '14D', '30D'], # 1 week to 1 month + lag_periods=['1D', '7D', '14D'], # 1 day, 1 week, 2 weeks + time_step='D', + verbose=True +) + +# Feature columns +feature_cols = ['Sales', 'DayOfWeek', 'Month', 'IsWeekend'] +X = df[['Date', 'Store'] + feature_cols] +y = df['NextDaySales'] + +# Time split (80% train, 20% test) +split_date = df['Date'].quantile(0.8) +train_mask = df['Date'] <= split_date +test_mask = df['Date'] > split_date + +X_train, X_test = X[train_mask], X[test_mask] +y_train, y_test = y[train_mask], y[test_mask] + +# Generate features +X_train_enhanced = bigfeat.fit(X_train, y_train, + gen_size=6, + iterations=4, + estimator='avg') + +X_test_enhanced = bigfeat.transform(X_test) + +# Train and evaluate +from sklearn.ensemble import RandomForestRegressor +model = RandomForestRegressor(n_estimators=100, random_state=42) +model.fit(X_train_enhanced, y_train) + +predictions = model.predict(X_test_enhanced) +r2 = r2_score(y_test, predictions) +mae = np.mean(np.abs(y_test - predictions)) + +print(f"R² Score with time series features: {r2:.4f}") +print(f"Mean Absolute Error: {mae:.2f}") +``` + +### Example 3: IoT Anomaly Detection + +```python +# Create synthetic sensor data +np.random.seed(42) +timestamps = pd.date_range('2023-01-01', periods=8760, freq='H') +sensors = ['Sensor_1', 'Sensor_2', 'Sensor_3'] + +data = [] +for sensor in sensors: + for i, timestamp in enumerate(timestamps): + # Normal operating patterns + temp = 25 + 10 * np.sin(2 * np.pi * timestamp.hour / 24) # Daily cycle + temp += 5 * np.sin(2 * np.pi * timestamp.dayofyear / 365) # Seasonal + temp += np.random.normal(0, 1) # Noise + + # Occasional anomalies + is_anomaly = np.random.random() < 0.02 # 2% anomaly rate + if is_anomaly: + temp += np.random.normal(0, 10) # Large deviation + + humidity = 50 + 20 * np.sin(2 * np.pi * timestamp.hour / 24 + np.pi/4) + humidity += np.random.normal(0, 2) + + data.append({ + 'timestamp': timestamp, + 'sensor_id': sensor, + 'temperature': temp, + 'humidity': humidity, + 'hour': timestamp.hour, + 'day_of_week': timestamp.weekday(), + 'anomaly': int(is_anomaly) + }) + +df = pd.DataFrame(data) + +# Configure for anomaly detection +bigfeat = BigFeat( + task_type='classification', + enable_time_series=True, + datetime_col='timestamp', + groupby_cols=['sensor_id'], + window_sizes=['1H', '6H', '12H', '24H'], # 1h to 1 day + lag_periods=['1H', '6H', '12H'], # 1h to 12h + time_step='H', + verbose=True +) + +# Features (exclude target) +feature_cols = ['temperature', 'humidity', 'hour', 'day_of_week'] +X = df[['timestamp', 'sensor_id'] + feature_cols] +y = df['anomaly'] + +# Split data +split_idx = int(0.8 * len(df)) +X_train, X_test = X.iloc[:split_idx], X.iloc[split_idx:] +y_train, y_test = y.iloc[:split_idx], y.iloc[split_idx:] + +# Generate features +X_train_enhanced = bigfeat.fit(X_train, y_train, + gen_size=8, + iterations=3) + +X_test_enhanced = bigfeat.transform(X_test) + +# Train anomaly detector +from sklearn.ensemble import IsolationForest +from sklearn.metrics import classification_report + +# Use enhanced features for better anomaly detection +detector = IsolationForest(contamination=0.02, random_state=42) +detector.fit(X_train_enhanced[y_train == 0]) # Train on normal data only + +# Predict anomalies +anomaly_predictions = detector.predict(X_test_enhanced) +anomaly_predictions = (anomaly_predictions == -1).astype(int) + +print("Anomaly Detection Results:") +print(classification_report(y_test, anomaly_predictions)) +``` + +## Performance Optimization + +### 1. Configuration Tuning + +```python +# Light configuration for development/testing +config_light = { + 'window_sizes': ['3D', '7D'], + 'lag_periods': ['1D', '3D'], + 'gen_size': 3, + 'iterations': 2 +} + +# Heavy configuration for production +config_heavy = { + 'window_sizes': ['3D', '7D', '14D', '30D', '60D'], + 'lag_periods': ['1D', '3D', '7D', '14D', '30D'], + 'gen_size': 10, + 'iterations': 5 +} + +# Auto-scaling based on data size +def get_scaled_config(data_length): + if data_length < 500: + return config_light + elif data_length < 5000: + return { + 'window_sizes': ['3D', '7D', '14D'], + 'lag_periods': ['1D', '3D', '7D'], + 'gen_size': 5, + 'iterations': 3 + } + else: + return config_heavy + +# Auto-scaling based on data size +max_window = len(df) // 10 +window_sizes = [w for w in ['3D', '7D', '14D', '30D'] if w <= max_window] +``` + +### 2. Memory Management + +```python +# Monitor memory usage +import psutil +import gc + +def check_memory(): + process = psutil.Process() + return process.memory_info().rss / 1024 / 1024 # MB + +print(f"Memory before: {check_memory():.1f} MB") + +# Process with memory cleanup +X_enhanced = bigfeat.fit(X_train, y_train) +gc.collect() # Force garbage collection + +print(f"Memory after: {check_memory():.1f} MB") +``` + +### 3. Parallel Processing + +```python +# Use multiple cores for feature generation +bigfeat = BigFeat( + enable_time_series=True, + datetime_col='Date', + n_jobs=-1, # Use all available cores + verbose=True +) +``` + +## Best Practices + +### 1. Data Quality + +```python +# Always validate your data before processing +def validate_time_series_data(df, datetime_col, feature_cols): + """Validate data quality for time series processing""" + + # Check datetime column + assert datetime_col in df.columns, f"Datetime column '{datetime_col}' not found" + assert pd.api.types.is_datetime64_any_dtype(df[datetime_col]), "Datetime column must be datetime type" + + # Check for missing values + missing = df[feature_cols].isnull().sum() + if missing.any(): + print(f"Warning: Missing values found:\n{missing[missing > 0]}") + + # Check for infinite values + infinite = np.isinf(df[feature_cols].select_dtypes(include=[np.number])).sum() + if infinite.any(): + print(f"Warning: Infinite values found:\n{infinite[infinite > 0]}") + + # Check temporal ordering + if not df[datetime_col].is_monotonic_increasing: + print("Warning: Data is not sorted by datetime") + + print("Data validation complete") + +# Use validation +validate_time_series_data(df, 'Date', ['feature1', 'feature2']) +``` + +### 2. Feature Engineering Pipeline + +```python +def create_time_series_pipeline(df, datetime_col, feature_cols, target_col, + groupby_cols=None, test_size=0.2): + """Complete pipeline for time series feature engineering""" + + # 1. Data validation + validate_time_series_data(df, datetime_col, feature_cols) + + # 2. Sort data + sort_cols = (groupby_cols or []) + [datetime_col] + df = df.sort_values(sort_cols).reset_index(drop=True) + + # 3. Create time-based split + split_date = df[datetime_col].quantile(0.8) + train_mask = df[datetime_col] <= split_date + test_mask = df[datetime_col] > split_date + + train_df = df[train_mask] + test_df = df[test_mask] + + # 4. Configure BigFeat + bigfeat = BigFeat( + task_type='classification' if df[target_col].dtype == 'int' else 'regression', + enable_time_series=True, + datetime_col=datetime_col, + groupby_cols=groupby_cols, + verbose=True + ) + + # 5. Prepare feature data + X_train = train_df[[datetime_col] + (groupby_cols or []) + feature_cols] + X_test = test_df[[datetime_col] + (groupby_cols or []) + feature_cols] + y_train = train_df[target_col] + y_test = test_df[target_col] + + # 6. Generate features + X_train_enhanced = bigfeat.fit(X_train, y_train) + X_test_enhanced = bigfeat.transform(X_test) + + return X_train_enhanced, X_test_enhanced, y_train, y_test, bigfeat + +# Use pipeline +X_train, X_test, y_train, y_test, bigfeat = create_time_series_pipeline( + df, 'Date', ['feature1', 'feature2'], 'target', + groupby_cols=['group'] +) +``` + +### 3. Model Selection and Validation + +```python +def evaluate_time_series_features(df, datetime_col, feature_cols, target_col, + groupby_cols=None): + """Compare performance with and without time series features""" + + # Prepare data + X_train, X_test, y_train, y_test, bigfeat = create_time_series_pipeline( + df, datetime_col, feature_cols, target_col, groupby_cols + ) + + # Baseline model (no time series) + bigfeat_baseline = BigFeat( + task_type='classification' if df[target_col].dtype == 'int' else 'regression', + enable_time_series=False + ) + + # Time-based split for baseline + split_date = df[datetime_col].quantile(0.8) + train_mask = df[datetime_col] <= split_date + test_mask = df[datetime_col] > split_date + + X_train_baseline = bigfeat_baseline.fit( + df[train_mask][feature_cols], y_train + ) + X_test_baseline = bigfeat_baseline.transform( + df[test_mask][feature_cols] + ) + + # Compare models + from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor + + if df[target_col].dtype == 'int': # Classification + model = RandomForestClassifier(random_state=42) + metric = accuracy_score + metric_name = "Accuracy" + else: # Regression + model = RandomForestRegressor(random_state=42) + metric = r2_score + metric_name = "R² Score" + + # Baseline performance + model.fit(X_train_baseline, y_train) + baseline_pred = model.predict(X_test_baseline) + baseline_score = metric(y_test, baseline_pred) + + # Time series enhanced performance + model.fit(X_train, y_train) + enhanced_pred = model.predict(X_test) + enhanced_score = metric(y_test, enhanced_pred) + + # Results + improvement = enhanced_score - baseline_score + improvement_pct = (improvement / abs(baseline_score)) * 100 if baseline_score != 0 else 0 + + print(f"\n=== Time Series Feature Evaluation ===") + print(f"Baseline {metric_name}: {baseline_score:.4f}") + print(f"Enhanced {metric_name}: {enhanced_score:.4f}") + print(f"Improvement: {improvement:+.4f} ({improvement_pct:+.1f}%)") + print(f"Features: {X_train_baseline.shape[1]} → {X_train.shape[1]}") + + return { + 'baseline_score': baseline_score, + 'enhanced_score': enhanced_score, + 'improvement': improvement, + 'improvement_pct': improvement_pct, + 'baseline_features': X_train_baseline.shape[1], + 'enhanced_features': X_train.shape[1] + } + +# Use evaluation +results = evaluate_time_series_features(df, 'Date', ['feature1', 'feature2'], 'target') +``` + +### 4. Production Deployment + +```python +def deploy_time_series_model(bigfeat, model, feature_cols, datetime_col, + groupby_cols=None): + """Create production-ready prediction function""" + + def predict_new_data(new_df): + """Predict on new time series data""" + + # Validate input + required_cols = [datetime_col] + (groupby_cols or []) + feature_cols + missing_cols = set(required_cols) - set(new_df.columns) + if missing_cols: + raise ValueError(f"Missing columns: {missing_cols}") + + # Prepare data + X_new = new_df[required_cols].copy() + X_new[datetime_col] = pd.to_datetime(X_new[datetime_col]) + + # Sort data + sort_cols = (groupby_cols or []) + [datetime_col] + X_new = X_new.sort_values(sort_cols).reset_index(drop=True) + + # Generate features + try: + X_enhanced = bigfeat.transform(X_new) + predictions = model.predict(X_enhanced) + + # Add predictions to original dataframe + result_df = new_df.copy() + result_df['prediction'] = predictions + result_df['prediction_timestamp'] = pd.Timestamp.now() + + return result_df + + except Exception as e: + print(f"Error in prediction: {str(e)}") + raise + + return predict_new_data + +# Create production predictor +predictor = deploy_time_series_model(bigfeat, model, feature_cols, 'Date', ['group']) + +# Use for new predictions +new_predictions = predictor(new_data) +``` + +## Advanced Techniques + +### 1. Custom Time Series Operators + +```python +# You can extend BigFeat with custom time series operations +class CustomBigFeat(BigFeat): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Add custom operators + if self.enable_time_series: + self.custom_operators = [ + self._custom_rolling_quantile, + self._custom_seasonal_decompose, + self._custom_autocorr_feature + ] + self.operators.extend(self.custom_operators) + self.unary_operators.extend(self.custom_operators) + + def _custom_rolling_quantile(self, feature_data): + """Custom time-based rolling quantile operator""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'rolling_quantile') + else: + try: + window_size = self.rng.choice([3, 5, 7, 10, 14, 21, 30]) + window_size = min(window_size, len(feature_data)) + quantile = self.rng.choice([0.25, 0.5, 0.75]) + result = pd.Series(feature_data).rolling( + window=window_size, min_periods=1 + ).quantile(quantile) + return self._clean_feature(result) + except Exception: + return feature_data + + def _custom_seasonal_decompose(self, feature_data): + """Simple seasonal decomposition""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'seasonal_decompose') + else: + try: + # Simple seasonal pattern extraction + series = pd.Series(feature_data) + # Create a simple seasonal pattern based on position in series + season_length = min(365, len(series) // 4) if len(series) > 365 else len(series) // 4 + if season_length < 2: + return feature_data + seasonal = series.rolling(window=season_length, center=True, min_periods=1).mean() + return self._clean_feature(seasonal.fillna(series.mean()).values) + except Exception: + return feature_data + + def _custom_autocorr_feature(self, feature_data): + """Autocorrelation-based feature""" + if self.enable_time_series and hasattr(self, '_current_data') and hasattr(self, '_current_feature_index'): + feature_col = self.feature_columns[ + self._current_feature_index] if self.feature_columns else f'feature_{self._current_feature_index}' + return self._apply_time_based_operation(self._current_data, feature_col, 'autocorr') + else: + try: + lag = self.rng.choice([1, 2, 3, 5, 7, 10]) + lag = min(lag, len(feature_data) - 1) + series = pd.Series(feature_data) + lagged = series.shift(lag) + correlation = series.corr(lagged) + + # Create feature based on correlation strength + corr_feature = np.full_like(feature_data, correlation if not np.isnan(correlation) else 0) + return self._clean_feature(corr_feature) + except Exception: + return feature_data + +# Use custom BigFeat +custom_bigfeat = CustomBigFeat( + enable_time_series=True, + datetime_col='Date', + verbose=True +) +``` + +### 2. Multi-Step Ahead Forecasting + +```python +def create_multi_step_targets(df, target_col, steps=[1, 3, 7], groupby_cols=None): + """Create multiple forecasting horizons""" + + target_cols = {} + + for step in steps: + col_name = f"{target_col}_t+{step}" + + if groupby_cols: + df[col_name] = df.groupby(groupby_cols)[target_col].shift(-step) + else: + df[col_name] = df[target_col].shift(-step) + + target_cols[f"step_{step}"] = col_name + + return df, target_cols + +# Create multi-step targets +df_multi, target_mapping = create_multi_step_targets( + df, 'sales', steps=[1, 3, 7], groupby_cols=['store'] +) + +# Train separate models for each horizon +models = {} +for step_name, target_col in target_mapping.items(): + print(f"\nTraining model for {step_name}...") + + # Remove rows with missing targets + df_clean = df_multi.dropna(subset=[target_col]) + + # Configure BigFeat for this horizon + bigfeat = BigFeat( + task_type='regression', + enable_time_series=True, + datetime_col='Date', + groupby_cols=['store'], + verbose=False + ) + + # Time-based split + split_date = df_clean['Date'].quantile(0.8) + train_mask = df_clean['Date'] <= split_date + test_mask = df_clean['Date'] > split_date + + X_train = df_clean[train_mask][['Date', 'store'] + feature_cols] + X_test = df_clean[test_mask][['Date', 'store'] + feature_cols] + y_train = df_clean[train_mask][target_col] + y_test = df_clean[test_mask][target_col] + + # Generate features and train + X_train_enhanced = bigfeat.fit(X_train, y_train) + X_test_enhanced = bigfeat.transform(X_test) + + model = RandomForestRegressor(random_state=42) + model.fit(X_train_enhanced, y_train) + + # Evaluate + predictions = model.predict(X_test_enhanced) + r2 = r2_score(y_test, predictions) + + models[step_name] = { + 'bigfeat': bigfeat, + 'model': model, + 'r2_score': r2 + } + + print(f"{step_name} R² Score: {r2:.4f}") + +print("\nMulti-step forecasting models trained successfully!") +``` + +### 3. Feature Importance Analysis + +```python +def analyze_time_series_features(bigfeat, model, X_enhanced, feature_cols): + """Analyze which time series features are most important""" + + # Get feature importances + if hasattr(model, 'feature_importances_'): + importances = model.feature_importances_ + else: + from sklearn.inspection import permutation_importance + perm_imp = permutation_importance(model, X_enhanced, y_test) + importances = perm_imp.importances_mean + + # Create feature descriptions + n_generated = len(bigfeat.tracking_ops) if hasattr(bigfeat, 'tracking_ops') else 0 + n_original = len(feature_cols) + + feature_names = [] + feature_types = [] + + # Generated features + if hasattr(bigfeat, 'tracking_ops'): + for i, (ops, ids) in enumerate(zip(bigfeat.tracking_ops, bigfeat.tracking_ids)): + if not ops: + # Original feature + feat_name = f"Original_{feature_cols[ids[0]] if ids and ids[0] < len(feature_cols) else 'Unknown'}" + feat_type = "Original" + else: + # Generated feature + op_names = [] + for op_info in ops: + if len(op_info) > 0: + op_name = getattr(op_info[0], '__name__', 'Unknown') + op_name = op_name.replace('_safe_', '') + op_names.append(op_name) + + feat_name = f"Generated_{i}_{'_'.join(op_names[:2])}" + feat_type = "Time Series" if any('rolling' in op or 'lag' in op or 'ewm' in op + for op in op_names) else "Generated" + + feature_names.append(feat_name) + feature_types.append(feat_type) + + # Add remaining original features + remaining = len(importances) - len(feature_names) + for i in range(remaining): + if i < len(feature_cols): + feature_names.append(f"Original_{feature_cols[i]}") + feature_types.append("Original") + else: + feature_names.append(f"Feature_{i}") + feature_types.append("Unknown") + + # Create importance DataFrame + importance_df = pd.DataFrame({ + 'feature': feature_names[:len(importances)], + 'importance': importances, + 'type': feature_types[:len(importances)] + }).sort_values('importance', ascending=False) + + # Analyze by type + type_analysis = importance_df.groupby('type').agg({ + 'importance': ['sum', 'mean', 'count'] + }).round(4) + + print("\n=== Feature Importance Analysis ===") + print(f"\nTop 10 Most Important Features:") + print(importance_df.head(10).to_string(index=False)) + + print(f"\nImportance by Feature Type:") + print(type_analysis.to_string()) + + # Plot if matplotlib available + try: + import matplotlib.pyplot as plt + + # Feature type distribution + fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 5)) + + # Top features + importance_df.head(15).plot(x='feature', y='importance', kind='barh', ax=ax1) + ax1.set_title('Top 15 Features by Importance') + ax1.set_xlabel('Importance') + + # Importance by type + type_summary = importance_df.groupby('type')['importance'].sum() + type_summary.plot(kind='pie', ax=ax2, autopct='%1.1f%%') + ax2.set_title('Importance by Feature Type') + + plt.tight_layout() + plt.savefig('feature_importance_analysis.png', dpi=300, bbox_inches='tight') + plt.show() + + except ImportError: + print("Matplotlib not available for plotting") + + return importance_df + +# Use feature importance analysis +importance_df = analyze_time_series_features(bigfeat, model, X_test_enhanced, feature_cols) +``` + +## Summary + +This comprehensive guide covers everything you need to know about using BigFeat's time series operations: + +### Key Takeaways: + +1. **Enable time series with proper configuration**: Set `enable_time_series=True` and specify your datetime column +2. **Prepare data correctly**: Always ensure datetime columns are properly formatted and data is sorted chronologically +3. **Configure parameters thoughtfully**: Choose time-based window sizes and lag periods that make sense for your domain and data frequency +4. **Use groupby for multi-series data**: Essential for preventing cross-contamination between different time series +5. **Validate and monitor**: Always check data quality and feature generation results +6. **Start simple, then optimize**: Begin with basic configurations and gradually add complexity based on performance + +### Quick Reference: + +```python +# Basic setup +bigfeat = BigFeat( + enable_time_series=True, + datetime_col='Date', + groupby_cols=['ID'], # For multi-series + window_sizes=['3D', '7D', '14D'], + lag_periods=['1D', '3D', '7D'], + time_step='D' +) + +# Generate features +X_enhanced = bigfeat.fit(df_with_datetime, target) +X_new_enhanced = bigfeat.transform(new_df_with_datetime) +``` + +With this guide, you should be able to effectively leverage BigFeat's time series capabilities to enhance your temporal machine learning projects! \ No newline at end of file diff --git a/docs/bigfeat-time-series-operators-and-rolling-analysis.md b/docs/bigfeat-time-series-operators-and-rolling-analysis.md new file mode 100644 index 0000000..618fee2 --- /dev/null +++ b/docs/bigfeat-time-series-operators-and-rolling-analysis.md @@ -0,0 +1,390 @@ +# BigFeat Time Series Operators & Rolling Analysis + +## Overview +BigFeat's time series enhancement provides automated feature generation for temporal data through sophisticated time-based rolling window operations, lag features, and time-aware transformations. This document explains the implementation, lifecycle, and usage of these time series operators. + +## Architecture Overview +``` +textInput Data (DataFrame with DateTime) + ↓ + Data Preparation & Validation + ↓ + Time Series Operators Applied + ↓ + Feature Generation & Selection + ↓ + Enhanced Feature Set Output +``` + +## Core Components +## 1. Time Series Operators +The BigFeat implementation includes 15 specialized time series operators: + +### Rolling Window Operations + +- `_safe_rolling_mean`: Time-based moving average calculations +- `_safe_rolling_std`: Time-based rolling standard deviation for volatility measures +- `_safe_rolling_min`: Time-based rolling minimum values +- `_safe_rolling_max`: Time-based rolling maximum values +- `_safe_rolling_median`: Time-based rolling median for robust central tendency +- `_safe_rolling_sum`: Time-based rolling sum aggregations + +### Temporal Shift Operations + +- `_safe_lag_feature`: Time-based lagged versions of features +- `_safe_diff_feature`: Time-based first and higher-order differences +- `_safe_pct_change`: Time-based percentage change calculations + +### Advanced Time Series Features + +- `_safe_ewm`: Time-based exponentially weighted moving averages +- `_safe_momentum`: Time-based momentum indicators (price - lagged_price) +- `_safe_seasonal_decompose`: Simple seasonal pattern extraction +- `_safe_trend_feature`: Simple trend as rolling slope +- `_safe_weekday_mean`: Mean value by weekday +- `_safe_month_mean`: Mean value by month + +## 2. Data Preparation Infrastructure + +```python +def _prepare_time_series_data(self, X, y=None): + """ + Organizes data with datetime and groupby columns for proper time series operations + """ + # Convert to DataFrame if needed + # Add datetime column from stored original data + # Add groupby columns for multi-series data + # Sort by datetime and groupby columns + return processed_dataframe +``` + +### Key Features: + +- Automatic datetime column integration +- Support for multi-series data via groupby columns +- Proper temporal ordering ensures time series integrity +- Fallback handling for missing datetime information + +## 3. Safe Operation Framework +Each time series operator follows a consistent safety pattern: +```python +def _safe_rolling_mean(self, feature_data): + # Check if datetime-aware processing is available + if self.enable_time_series and hasattr(self, '_current_data'): + # Use datetime-aware operations with proper grouping + return self._apply_time_based_operation(...) + else: + # Fallback to basic rolling operations + try: + window_size = self.rng.choice([3, 5, 7, 10, 14, 21, 30]) + window_size = min(window_size, len(feature_data)) + result = pd.Series(feature_data).rolling(window=window_size, min_periods=1).mean().bfill().values + return self._clean_feature(result) + except Exception: + return feature_data +``` + +## Implementation Lifecycle +### Phase 1: Initialization +```python +bigfeat = BigFeat( + task_type='classification', + enable_time_series=True, + datetime_col='Date', + groupby_cols=['Symbol', 'Store'], + window_sizes=['7D', '14D', '30D', '3M', '6M', '1Y'], + lag_periods=['1D', '7D', '30D'], + verbose=True, + time_step='D' +) +``` +### Configuration Parameters: + +- `enable_time_series`: Activates time series functionality +- `datetime_col`: Specifies the datetime column name +- `groupby_cols`: Columns for grouping multi-series data +- `window_sizes`: Time-based rolling window sizes (str or pd.Timedelta) +- `lag_periods`: Time-based lag periods (str or pd.Timedelta) +- `time_step`: Time step for resampling (e.g., 'D' for daily, 'H' for hourly) + +### Phase 2: Data Processing +```python +# Data ingestion and preparation +self.original_data = X.copy() # Store original DataFrame +self.feature_columns = [numeric_columns_only] # Extract feature columns +self._current_data = self._prepare_time_series_data(X) # Prepare for TS ops +``` +### Data Flow: + +1. **Original Data Storage**: Full DataFrame preserved for datetime/groupby access +2. **Feature Column Identification**: Automatic detection of numeric feature columns +3. **Data Preparation**: Sorting and organizing for time series operations +4. **Validation**: Ensure datetime columns and groupby integrity + +### Phase 3: Feature Generation +```python +def feat_with_depth(self, X, depth, op_ls, feat_ls): + """ Recursively generate a new features - Enhanced to handle datetime-aware time series operators """ + if depth == 0: + feat_ind = self.rng.choice(np.arange(len(self.ig_vector)), p=self.ig_vector) + feat_ls.append(feat_ind) + # Set current feature index for time series operations + if self.enable_time_series: + self._current_feature_index = feat_ind + return X[:, feat_ind] + + depth -= 1 + op = self.rng.choice(self.operators, p=self.operator_weights) + + if op in self.binary_operators: + feat_1 = self.feat_with_depth(X, depth, op_ls, feat_ls) + feat_2 = self.feat_with_depth(X, depth, op_ls, feat_ls) + op_ls.append((op, depth)) + result = op(feat_1, feat_2) + return self._clean_feature(result) if self.enable_time_series else result + + elif op in self.unary_operators: + feat_1 = self.feat_with_depth(X, depth, op_ls, feat_ls) + op_ls.append((op, depth)) + result = op(feat_1) + return self._clean_feature(result) if self.enable_time_series else result +``` + +### Generation Process: + +1. **Operator Selection**: Weighted random selection including TS operators +2. **Context Setting**: Current feature index set for TS operations +3. **Safe Application**: Each operator includes error handling and fallbacks +4. **Feature Cleaning**: Automatic handling of NaN, infinity, and extreme values + +### Phase 4: Time Series Operation Execution +```python +def _apply_time_based_operation(self, data, feature_col, operation, window_size=None, lag_period=None): + """ + Apply time-based series operation to a specific feature column with proper grouping + """ + try: + if feature_col not in data.columns or self.datetime_col not in data.columns: + return np.zeros(len(data)) + + # Set datetime as index for time-based operations + if self.groupby_cols and any(col in data.columns for col in self.groupby_cols): + # Group data by groupby columns + groupby_cols = [col for col in self.groupby_cols if col in data.columns] + + results = [] + for name, group in data.groupby(groupby_cols): + group_sorted = group.set_index(self.datetime_col).sort_index() + group_result = self._apply_single_group_operation( + group_sorted, feature_col, operation, window_size, lag_period + ) + # Restore original order + group_result = group_result.reindex(group[self.datetime_col]).values + results.extend(group_result) + + return np.array(results) + else: + # Single group operation + data_sorted = data.set_index(self.datetime_col).sort_index() + result = self._apply_single_group_operation( + data_sorted, feature_col, operation, window_size, lag_period + ) + # Restore original order + return result.reindex(data[self.datetime_col]).values + + except Exception as e: + if self.verbose: + print(f"Warning: Time-based operation {operation} failed for {feature_col}: {str(e)}") + return np.zeros(len(data)) +``` + +### Operation Features: + +- **Groupby Support**: Proper handling of multi-series data +- **Parameter Management**: Dynamic window sizes and lag periods +- **Robust Execution**: Comprehensive error handling +- **Data Cleaning**: Automatic post-processing of results + +## Rolling Analysis Implementation +### Window Size Strategy +```python +# Default window sizes optimized for different data types +financial_windows = ['3D', '7D', '14D', '30D'] # Short-term trading patterns +retail_windows = ['7D', '14D', '21D', '30D'] # Weekly/monthly cycles +general_windows = ['3D', '7D', '14D', '21D', '30D', '60D', '90D'] # Comprehensive coverage +``` + +### Selection Logic: + +- **Dynamic Selection**: Random selection from configured ranges +- **Minimum Periods**: Always set to 1 to avoid NaN proliferation +- **Adaptive Sizing**: Window size limited by data length + +### Groupby Mechanics +```python +# Multi-series handling example +# Data: [Date, Symbol, Price, Volume, ...] +# Groupby: ['Symbol'] +# Result: Rolling operations applied separately per symbol + +grouped = data.groupby(['Symbol'])['Price'] +rolling_mean = grouped.rolling(window=pd.Timedelta(days=10), min_periods=1).mean() +``` + +### Benefits: + +- **Series Isolation**: Each time series processed independently +- **Temporal Integrity**: No cross-contamination between different series +- **Scalability**: Efficient processing of large multi-series datasets + +### Data Cleaning Pipeline +```python +def _clean_feature(self, feature_data): + """Clean feature data to ensure stability""" + try: + feature_data = np.asarray(feature_data, dtype=float) + # Replace inf with large finite values + feature_data = np.where(np.isinf(feature_data), np.sign(feature_data) * 1e8, feature_data) + # Replace nan with zeros + feature_data = np.where(np.isnan(feature_data), 0, feature_data) + # Clip extreme values + feature_data = np.clip(feature_data, -1e8, 1e8) + return feature_data + except Exception: + return np.zeros_like(feature_data, dtype=float) +``` + +### Cleaning Steps: + +- **Type Conversion**: Ensure numeric data types +- **Infinity Handling**: Replace with large finite values +- **NaN Replacement**: Fill with zeros (preserves array shape) +- **Extreme Value Clipping**: Prevent numerical instability + +## Feature Validation +### Quality Checks +```python +def _validate_feature(self, feature_data): + """Validate features for stability and usefulness""" + try: + if len(feature_data) == 0: + return False + feature_data = np.asarray(feature_data, dtype=float) + if not np.isfinite(feature_data).all(): + return False + if np.std(feature_data) < 1e-10: + return False + if np.max(np.abs(feature_data)) > 1e8: + return False + return True + except Exception: + return False +``` + + ### Validation Criteria: + +- **Non-empty**: Features must contain data +- **Finite Values**: No NaN or infinite values after cleaning +- **Sufficient Variance**: Avoid constant or near-constant features +- **Reasonable Magnitude**: Prevent numerical overflow issues + +## Usage Examples +### Basic Time Series Setup +```python +# Initialize with time series support +bigfeat = BigFeat( + task_type='classification', + enable_time_series=True, + datetime_col='Date', + groupby_cols=['Symbol'], + window_sizes=['7D', '14D', '30D', '3M', '6M', '1Y'], + lag_periods=['1D', '7D', '30D'], + time_step='D' +) + +# Fit with DataFrame including datetime column +X_enhanced = bigfeat.fit(df, target_column) +``` + +### Multi-Series Configuration +```python +# Multiple time series (e.g., stock data) +bigfeat = BigFeat( + enable_time_series=True, + datetime_col='Date', + groupby_cols=['Symbol'], # Separate processing per stock + window_sizes=['3D', '7D', '14D', '21D'], + lag_periods=['1D', '3D', '7D'], + time_step='D' +) +``` +### Transform New Data + +```python +# Apply same transformations to new data +X_test_enhanced = bigfeat.transform(test_df) +``` + +## Performance Considerations +### Computational Complexity + +- **Rolling Operations**: O(n × w) where n is data length, w is window size (time-based) +- **Groupby Operations**: O(n × g) where g is number of groups +- **Feature Generation**: O(f × d × o) where f is features, d is depth, o is operations + +### Memory Management + +- **Original Data Storage**: Full DataFrame kept for datetime access +- **Processed Data Caching**: Temporary storage during generation +- **Result Cleaning**: Immediate cleanup of intermediate results + +### Optimization Strategies + +- **Lazy Evaluation**: Operations only computed when needed +- **Vectorized Operations**: Pandas/NumPy optimizations utilized +- **Memory Cleanup**: Intermediate results freed promptly +- **Efficient Grouping**: Optimized groupby operations + +## Error Handling +### Robust Fallbacks +```python +try: + # Attempt datetime-aware operation + result = self._apply_time_based_operation(...) +except Exception as e: + if self.verbose: + print(f"Warning: Time-based operation failed: {str(e)}") + # Fallback to basic operation or zeros + return self._safe_fallback_operation(feature_data) +``` + +### Common Error Scenarios + +- **Missing DateTime Column**: Graceful degradation to basic operations +- **Insufficient Data**: Minimum periods handling prevents NaN proliferation +- **Type Mismatches**: Automatic type conversion and validation +- **Memory Issues**: Chunked processing for large datasets + +## Best Practices +### Data Preparation + +- **Sort Data**: Ensure proper temporal ordering before processing +- **Handle Missing Values**: Clean data before applying time series operations +- **Validate DateTime**: Ensure datetime column is properly formatted +- **Check Groupby Columns**: Verify grouping variables are meaningful + +### Configuration Tuning + +- **Window Sizes**: Match to data frequency and patterns (e.g., '7D' for weekly cycles) +- **Lag Periods**: Consider the prediction horizon (e.g., '1D' for next-day predictions) +- **Operator Selection**: Balance comprehensive coverage with computational cost +- **Groupby Strategy**: Group by meaningful time series identifiers + +### Performance Optimization + +- **Feature Selection**: Use stability selection to choose best time series features +- **Correlation Checking**: Remove highly correlated rolling features +- **Memory Monitoring**: Consider chunked processing for very large datasets +- **Validation Strategy**: Use time series cross-validation techniques + +This comprehensive time series framework enables BigFeat to automatically discover and generate meaningful temporal features while maintaining robustness and performance across diverse datasets. \ No newline at end of file diff --git a/docs/bigfeat-time-series-testing-script-analysis.md b/docs/bigfeat-time-series-testing-script-analysis.md new file mode 100644 index 0000000..d9a15b0 --- /dev/null +++ b/docs/bigfeat-time-series-testing-script-analysis.md @@ -0,0 +1,505 @@ +# BigFeat Time Series Testing Script Analysis + +## Overview + +The comprehensive testing script (`time_series_testing.py`) is designed to validate BigFeat's time series capabilities across multiple real-world and synthetic datasets. This document provides a detailed analysis of the testing methodology, implementation, and results interpretation. + +## Testing Architecture +``` +Data Sources → Dataset Loading → Feature Engineering → Testing Configurations → Model Training → Results Analysis +text +``` + +### Core Components +1. **ComprehensiveTimeSeriesTester**: Main testing orchestrator +2. **Data Loaders**: Multiple data source handlers +3. **Configuration Manager**: Test parameter management +4. **Results Analyzer**: Performance evaluation and reporting +5. **Artifact Generator**: JSON and visualization output + +## Data Sources & Loading + +### 1. Financial Data (Yahoo Finance) + +```python +def load_stock_data(self, symbols=['AAPL', 'GOOGL', 'MSFT'], period='2y'): + # Downloads stock data with comprehensive feature engineering + # Creates technical indicators: RSI, MACD, Bollinger Bands + # Generates time-based features: day of week, month, quarter + # Creates target variables: next return, price direction, volatility +``` + +#### Features Generated: +- **Price Features**: Open, High, Low, Close, Volume +- **Technical Indicators**: RSI (14-period), MACD, Bollinger Bands +- **Derived Features**: Returns, log returns, volatility, price range +- **Time Features**: Day of week, month, quarter, days from start +- **Target Variables**: Next-day return, price up/down, high volatility + +#### Data Characteristics: +- **Symbols**: Multiple stocks for groupby testing +- **Timespan**: 2 years of daily data (~1500 rows) +- **Temporal Patterns**: Market cycles, volatility clustering +- **Challenges**: High noise, non-stationarity, regime changes + +### 2. Cryptocurrency Data +```pythondef load_crypto_data(self, symbols=['BTC-USD', 'ETH-USD'], period='1y'): + # Similar to stock data but adapted for crypto characteristics + # Higher volatility patterns, 24/7 trading, different seasonality +``` + +#### Unique Characteristics: +- **Higher Volatility**: More extreme price movements +- **24/7 Trading**: No market closure gaps +- **Different Patterns**: Less traditional seasonal effects +- **Volume Patterns**: Different from traditional markets + +### 3. Synthetic Sales Data +```python +def create_synthetic_sales_data(self, n_stores=5, days=730): + # Creates realistic retail sales simulation + # Multiple seasonal patterns, promotions, external factors + # Controlled ground truth for validation +``` + +#### Synthetic Complexity: +```python +# Multi-layered pattern generation +yearly_trend = 500 * (i / len(dates)) +monthly_seasonal = 1000 * np.sin(2 * np.pi * date.month / 12) +weekly_pattern = 800 * np.sin(2 * np.pi * date.weekday() / 7) +weather_effect = 300 * np.sin(2 * np.pi * (date.dayofyear - 80) / 365) +``` + +#### Features: +- **Multi-store Data**: Perfect for groupby testing +- **Known Patterns**: Controllable seasonality and trends +- **External Factors**: Promotions, holidays, weather, competition +- **Realistic Noise**: Random variations maintaining believability + +### 4. Hourly Energy Consumption Data +```python +def create_hourly_energy_data(self, days=180): + # Creates synthetic hourly energy data + # Hourly, daily, seasonal patterns + # Weather and holiday effects +``` + +#### Data Characteristics: +- **Frequency**: Hourly data for high-resolution testing +- **Patterns**: Multi-level temporal hierarchies (hour/day/week/season) +- **Targets**: Next-hour consumption, high consumption classification +- **Challenges**: High-frequency noise, strong daily cycles + +### 5. Simple Weekly Time Series +```python +# Create a simple time series dataset for weekly analysis +np.random.seed(42) +dates = pd.date_range('2022-01-01', periods=520, freq='W') # Weekly data for 10 years + +# Create trend + seasonality + noise +trend = np.linspace(100, 200, len(dates)) +seasonality = 20 * np.sin(2 * np.pi * np.arange(len(dates)) / 52) # yearly seasonality +noise = np.random.normal(0, 5, len(dates)) + +values = trend + seasonality + noise + +simple_df = pd.DataFrame({ + 'Date': dates, + 'Value': values, + 'WeekOfYear': dates.isocalendar().week, + 'Month': dates.month, + 'Quarter': dates.quarter, + 'IsEndOfMonth': dates.is_month_end.astype(int), + 'Feature1': np.random.normal(10, 2, len(dates)), + 'Feature2': np.random.normal(5, 1, len(dates)), + 'Feature3': values * 0.1 + np.random.normal(0, 1, len(dates)) +}) + +# Create targets +simple_df['NextValue'] = simple_df['Value'].shift(-1) +simple_df['HighValue'] = (simple_df['Value'] > simple_df['Value'].quantile(0.7)).astype(int) +simple_df = simple_df.dropna() +``` + +**Purpose**: Baseline validation with clear, interpretable temporal structure. + +## Testing Methodology +### Configuration Matrix +Each dataset is tested with multiple configurations, including time-based window horizons: +#### 1. Baseline Configuration +```python +{ + 'name': 'Baseline (No Time Series)', + 'params': { + 'enable_time_series': False, + 'verbose': False + }, + 'fit_params': { + 'gen_size': 3, + 'iterations': 2, + 'selection': 'stability' + } +} +``` + +#### 2. Time Series Short-term +```python +{ + 'name': 'Time Series (Short-term)', + 'params': { + 'enable_time_series': True, + 'datetime_col': date_col, + 'groupby_cols': groupby_cols, + 'window_sizes': window_configs['short_term'], # e.g., ['3D', '7D', '14D', '21D'] + 'lag_periods': lag_configs['short_term'], # e.g., ['1D', '3D', '7D'] + 'time_step': time_step, + 'verbose': False + }, + 'fit_params': { + 'gen_size': 4, + 'iterations': 3, + 'selection': 'stability' + } +} +``` + +#### 3. Time Series Medium-term +Similar to short-term but with medium-term windows/lags, e.g., ['30D', '60D', '90D'] / ['14D', '30D'] + +####4. Time Series Long-term +With long-term windows/lags, e.g., ['6M', '1Y'] / ['60D', '90D'] + +#### 5. Time Series Mixed +Combination of short and medium-term windows/lags + +### Target Variables & Tasks + +#### Classification Tasks +- **Stock Direction**: Predict if next-day return is positive +- **Volatility Prediction**: Identify high volatility periods +- **Sales Performance**: Classify high vs. normal sales days +- **Energy Consumption**: Classify high consumption hours +- **Simple Weekly**: Classify high value periods + +#### Regression Tasks +- **Return Prediction**: Predict actual next-day returns +- **Sales Forecasting**: Predict next-day sales values +- **Energy Forecasting**: Predict next-hour consumption +- **Simple Weekly**: Predict next value + +### Time-Based Data Splitting +```python +# Proper time series split (no data leakage) +split_date = df[date_col].quantile(0.8) +train_mask = df[date_col] <= split_date +test_mask = df[date_col] > split_date +``` + +#### Benefits: +- **No Future Leakage**: Test data is strictly chronologically after training +- **Realistic Evaluation**: Mimics real-world deployment scenarios +- **Temporal Integrity**: Preserves time series structure + +## Feature Generation & Tracking +### Automated Feature Description +```python +# Feature naming and description generation +for i, (ops, ids) in enumerate(zip(bigfeat.tracking_ops, bigfeat.tracking_ids)): + if not ops or len(ops) == 0: + # Original feature + feat_name = f"Original_{feature_cols[ids[0]]}" + desc = f"Original: {feature_cols[ids[0]]}" + else: + # Generated feature + op_names = [] + for op_info in ops: + if len(op_info) > 0: + op = op_info[0] + op_name = getattr(op, '__name__', str(op)).replace('_safe_', + '').replace( + '', '') + op_names.append(op_name) + + feat_indices = [] + if ids: + for idx in ids: + if idx < len(feature_cols): + feat_indices.append(feature_cols[idx]) + else: + feat_indices.append(f"feat_{idx}") + + if op_names: + feat_name = f"Gen_Feat_{i}_{'_'.join(op_names[:2])}" + desc = f"{' -> '.join(op_names)}({', '.join(feat_indices)})" + else: + feat_name = f"Gen_Feat_{i}" + desc = f"Generated feature {i}" +``` + +### Time Series Operation Counting +```python +# Accurate counting of time series operations +time_series_op_names = [ + '_safe_rolling_mean', '_safe_rolling_std', '_safe_rolling_min', '_safe_rolling_max', + '_safe_rolling_median', '_safe_rolling_sum', '_safe_lag_feature', '_safe_diff_feature', + '_safe_pct_change', '_safe_ewm', '_safe_momentum', '_safe_seasonal_decompose', + '_safe_trend_feature', '_safe_weekday_mean', '_safe_month_mean' +] + +for ops in bigfeat.tracking_ops: + if ops: # Check if ops list is not empty + for op_info in ops: + if len(op_info) > 0 and callable(op_info[0]): + op_name = getattr(op_info[0], '__name__', '') + if op_name in time_series_op_names: + ts_ops_count += 1 +``` + +### Artifact Generation +```python +# Comprehensive result preservation +feature_info = { + 'feature_names': feature_names[:X_train_enhanced.shape[1]], + 'feature_descriptions': feature_descriptions[:X_train_enhanced.shape[1]], + 'n_generated_features': len(bigfeat.tracking_ops) if hasattr(bigfeat, + 'tracking_ops') else 0, + 'n_original_features': len(feature_cols), + 'total_features': X_train_enhanced.shape[1], + 'ts_ops_count': ts_ops_count, + 'datetime_col': date_col, + 'groupby_cols': groupby_cols, + 'window_sizes': config['params'].get('window_sizes', []), + 'lag_periods': config['params'].get('lag_periods', []), + 'time_step': config['params'].get('time_step', 'D') +} +``` + +#### Outputs: +- **Feature Metadata**: JSON with feature descriptions and generation details +- **Performance Metrics**: Comprehensive scoring across all configurations +- **Visualizations**: Improvement distributions, time period performance, best improvements + +## Results Analysis Framework + +### Performance Metrics + +#### Classification Tasks +- **Primary**: Accuracy score +- **Class Distribution**: Reported for imbalance awareness +- **Improvement**: Absolute difference from baseline + +#### Regression Tasks +- **Primary**: R² score +- **Secondary**: MAE (Mean Absolute Error), RMSE (Root Mean Square Error) +- **Improvement**: R² difference from baseline + +#### Statistical Analysis +```python +# Comprehensive improvement analysis +total_tests = 55 +successful_tests = 18 (32.7%) +significant_improvements = 12 (21.8%) +average_improvement = -0.1296 +best_improvement = +0.8554 +worst_improvement = -4.4491 +``` + +### Best Improvements by Category +| Dataset | Task | Best Method | Score | Improvement | +|-----------------------------|-----------------------------------|------------------------------|---------|-------------| +| Stock_Market_Daily | Stock_Direction_Prediction | Time Series (Medium-term) | 0.4500 | +0.0200 | +| Stock_Market_Daily | Stock_Return_Prediction | Time Series (Mixed) | -0.3695 | +0.0589 | +| Stock_Market_Daily | Stock_Volatility_Prediction | Time Series (Long-term) | 0.5767 | +0.0733 | +| Cryptocurrency_Daily | Crypto_Direction_Prediction | Time Series (Short-term) | 0.4653 | +0.0347 | +| Cryptocurrency_Daily | Crypto_Return_Prediction | Time Series (Medium-term) | -0.1408 | +0.0521 | +| Retail_Sales_Daily | Sales_High_Performance | Time Series (Mixed) | 0.9972 | +0.0083 | +| Retail_Sales_Daily | Sales_Next_Day_Prediction | Baseline (No Time Series) | 0.6401 | +0.0000 | +| Energy_Consumption_Hourly | Energy_High_Consumption | Time Series (Medium-term) | 0.8588 | +0.0081 | +| Energy_Consumption_Hourly | Energy_Next_Hour_Prediction | Time Series (Medium-term) | 0.4875 | +0.1238 | +| Simple_Weekly_TimeSeries | Simple_Weekly_Regression | Time Series (Mixed) | 0.1716 | +0.8554 | +| Simple_Weekly_TimeSeries | Simple_Weekly_Classification | Baseline (No Time Series) | 0.7308 | +0.0000 | + +## Key Findings & Insights + +### 1. Time Series Effectiveness Patterns + +#### High Success Cases: +- **Simple Weekly Time Series**: Strong improvements (R² from -0.6838 to 0.1716) +- **Classification Tasks**: Generally better improvements than regression +- **Clean Temporal Patterns**: Time series operators excel with clear seasonality + +#### Challenging Cases: +- **Financial Return Prediction**: Inherently difficult (negative R² common) +- **High Noise Data**: Time series features can sometimes add noise +- **Complex Multi-factor Systems**: Traditional features may already capture key patterns + +### 2. Configuration Performance + +#### Time Period Effectiveness: +- **Short-term**: Average improvement -0.2309 +- **Medium-term**: Average improvement -0.0612 +- **Long-term**: Average improvement -0.3606 +- **Mixed**: Average improvement +0.0045 + +**Parameter Sensitivity**: Window sizes and lag periods matter significantly + +### 3. Data Type Insights +#### Stock Market Data +```text +Direction Prediction: ✓ Consistent improvements (1.3-2.0%) +Return Prediction: ± Mixed results (some improve, some degrade) +Volatility Prediction: ✓ Good improvements (7.3%) +``` + +#### Cryptocurrency Data +```text +Direction Prediction: ✓ Good improvements (0.7-3.5%) +Return Prediction: ± Volatile results (large variation) +``` + +#### Retail Sales Data +```text +High Performance Classification: ✓ Modest improvements (0.0-0.8%) +Next Day Prediction: ± Mixed results (-4.5% to -0.2%) +``` + +#### Energy Consumption Data +```text +High Consumption Classification: ± Mixed results (-1.7% to +0.8%) +Next Hour Prediction: ✓ Strong improvements in medium-term (12.4%) +``` + +#### Simple Weekly Time Series +```text +Regression: ✓✓ Outstanding improvements (0.86 R² gain in mixed) +Classification: ± Mixed results (-10.6% to 0.0%) +``` + +### 4. Time Series Operation Usage + +#### Most Effective Operators: +- **Rolling Mean**: Trend capturing, noise reduction +- **Lag Features**: Temporal dependency modeling +- **Rolling Standard Deviation**: Volatility and regime detection +- **Exponential Smoothing**: Adaptive trend following + +#### Usage Patterns: +- **Financial Data**: 9-16 TS operations per configuration +- **Simple Data**: 1-6 operations (focused application) +- **Retail Data**: 0-4 operations (moderate complexity) + +## Testing Script Architecture Analysis + +### Strengths +- **Comprehensive Coverage**: Multiple data types, tasks, and configurations +- **Proper Time Series Validation**: No data leakage, temporal splits +- **Detailed Artifact Generation**: Complete traceability and reproducibility +- **Robust Error Handling**: Graceful degradation and error reporting +- **Statistical Rigor**: Multiple metrics, improvement tracking +- **Real-world Applicability**: Actual financial and business data + +### Design Patterns +#### Data Loading Strategy +```python +# Modular data loaders with consistent interface +def load_X_data(self, params): + # Download/generate data + # Apply feature engineering + # Create targets + # Return standardized DataFrame +``` + +#### Configuration Management +```python +# Systematic parameter testing +configurations = [baseline, short_term, medium_term, long_term, mixed] +for config in configurations: + bigfeat = BigFeat(**config['params']) + results = bigfeat.fit(X, y, **config['fit_params']) +``` + +#### Results Aggregation +```python +# Hierarchical result storage +all_results[dataset_name][config_name][method_name] = { + 'score': performance_metric, + 'n_features': feature_count, + 'ts_ops_count': time_series_operations, + 'improvement': score - baseline_score +} +``` + +### Validation Methodology + +#### Cross-Dataset Validation +- **Multiple Domains**: Finance, crypto, retail, energy, synthetic +- **Various Complexities**: From clean synthetic to noisy real-world +- **Different Scales**: Small (hundreds) to large (thousands) of samples +- **Frequencies**: Hourly, daily, weekly + +#### Multi-Task Validation +- **Classification**: Binary prediction tasks +- **Regression**: Continuous value prediction +- **Multi-target**: Various prediction horizons and types + +#### Statistical Validation +- **Baseline Comparison**: Every enhancement measured against no-TS baseline +- **Multiple Runs**: Consistent random state for reproducibility +- **Effect Size**: Both absolute and relative improvements tracked + +## Interpretation Guidelines + +### Success Indicators + +#### Strong Positive Results (>5% improvement): +- Time series operators are capturing meaningful temporal patterns +- Features complement existing information effectively +- Configuration parameters well-matched to data characteristics + +#### Modest Positive Results (1-5% improvement): +- Time series features provide incremental value +- May indicate subtle temporal patterns or noise reduction +- Consider feature selection to isolate most valuable TS features + +#### Neutral Results (±1% improvement): +- Existing features may already capture temporal patterns +- Time series patterns may be weak or irregular +- Consider different window sizes or lag periods + +#### Negative Results (<-1% improvement): +- Time series features may be adding noise +- Overfitting to training temporal patterns +- Consider simpler configurations or feature selection + +### Common Patterns + +#### By Data Type +- **High-frequency Financial**: Mixed results, challenging to predict +- **Lower-frequency Business**: More consistent positive results +- **Synthetic/Clean**: Excellent results, validates implementation +- **Multi-series**: Groupby functionality crucial for success + +#### By Task Type +- **Classification**: Generally more successful than regression +- **Direction Prediction**: Often more successful than magnitude prediction +- **Volatility Tasks**: Time series features particularly effective + +### Deployment Recommendations + +#### High Confidence (>10% improvement): +- Deploy time series enhanced model +- Monitor for regime changes that might affect TS patterns +- Consider online learning to adapt TS parameters + +#### Moderate Confidence (2-10% improvement): +- A/B test enhanced vs. baseline models +- Implement feature importance monitoring +- Use cross-validation specific to time series + +#### Low Confidence (<2% improvement): +- Stick with baseline unless marginal gains are valuable +- Investigate alternative TS configurations +- Consider domain-specific time series features + +This comprehensive testing framework provides robust validation of BigFeat's time series capabilities while offering detailed insights into when and how temporal features add value across diverse applications. \ No newline at end of file diff --git a/docs/bigfeat_time_series_changes.md b/docs/bigfeat_time_series_changes.md new file mode 100644 index 0000000..5ddba33 --- /dev/null +++ b/docs/bigfeat_time_series_changes.md @@ -0,0 +1,302 @@ +# BigFeat Time Series Enhancement Documentation + +## Overview + +This document outlines the enhancements made to the BigFeat library to support time series feature engineering while maintaining 100% backward compatibility with the original implementation. + +## Summary of Changes + +The enhanced BigFeat adds **optional** time series capabilities without modifying any existing functionality. When time series features are disabled (default behavior), the library behaves identically to the original implementation. + +## Core Enhancements + +### 1. Time Series Initialization Parameters + +The `__init__` method now accepts additional parameters for time series functionality: + +```python +def __init__(self, task_type='classification', enable_time_series=False, + window_sizes=None, lag_periods=None, verbose=True, + datetime_col=None, groupby_cols=None, time_step='D'): +``` + +**New Parameters:** +- `enable_time_series` (bool): Enables/disables time series operators (default: False) +- `window_sizes` (list): Time-based window sizes for rolling operations +- `lag_periods` (list): Time-based lag periods for time series operations +- `verbose` (bool): Progress reporting (default: True) +- `datetime_col` (str): Name of datetime column for time series operations +- `groupby_cols` (list): Columns to group by when applying time series operations +- `time_step` (str): Time step for resampling operations (default: 'D') + +### 2. Time Series Operators + +When `enable_time_series=True`, 15 new operators are added to the existing operator set: + +#### Rolling Window Operations +- `_safe_rolling_mean()`: Time-aware rolling averages +- `_safe_rolling_std()`: Time-aware rolling standard deviation +- `_safe_rolling_min()`: Time-aware rolling minimum +- `_safe_rolling_max()`: Time-aware rolling maximum +- `_safe_rolling_median()`: Time-aware rolling median +- `_safe_rolling_sum()`: Time-aware rolling sum + +#### Temporal Transformation Operations +- `_safe_lag_feature()`: Time-aware lagged features +- `_safe_diff_feature()`: Time-aware differencing +- `_safe_pct_change()`: Time-aware percentage changes +- `_safe_ewm()`: Exponential weighted moving averages +- `_safe_momentum()`: Momentum calculations + +#### Advanced Time Series Operations +- `_safe_seasonal_decompose()`: Seasonal pattern extraction +- `_safe_trend_feature()`: Trend analysis +- `_safe_weekday_mean()`: Day-of-week patterns +- `_safe_month_mean()`: Monthly patterns + +### 3. Intelligent Data Handling + +#### DataFrame Processing +```python +# Automatic detection and separation of datetime vs feature columns +if isinstance(X, pd.DataFrame): + self.original_data = X.copy() + # Exclude datetime and groupby columns from features + exclude_cols = [self.datetime_col] + self.groupby_cols + # Filter for numeric columns only + numeric_feature_cols = [col for col in X.columns + if col not in exclude_cols and is_numeric(col)] +``` + +#### Time Series Data Preparation +```python +def _prepare_time_series_data(self, X, y=None): + """Organize data with datetime and groupby columns for time-based operations""" + # Ensures proper datetime indexing and grouping for time series operations +``` + +### 4. Time-Based Operations Engine + +#### Group-Aware Processing +```python +def _apply_time_based_operation(self, data, feature_col, operation, + window_size=None, lag_period=None): + """Apply operations with proper grouping and time-awareness""" + if self.groupby_cols: + # Process each group separately + for name, group in data.groupby(self.groupby_cols): + # Apply time-based operations within group + else: + # Single group operation +``` + +#### Flexible Time Period Parsing +```python +def _parse_time_periods(self, periods): + """Parse time periods from various formats ('7D', '30D', '3M', etc.)""" + # Supports string formats: '7D', '30D', '3M', '1Y' + # Supports pandas Timedelta objects + # Intelligent fallbacks for different formats +``` + +### 5. Enhanced Feature Generation + +#### Time-Aware Feature Creation +The core `feat_with_depth()` method now supports time series context: + +```python +def feat_with_depth(self, X, depth, op_ls, feat_ls): + """Enhanced to handle datetime-aware time series operators""" + # Original logic preserved + if depth == 0: + feat_ind = self.rng.choice(np.arange(len(self.ig_vector)), p=self.ig_vector) + # NEW: Set context for time series operations + if self.enable_time_series: + self._current_feature_index = feat_ind + return X[:, feat_ind] + # Rest of method unchanged... +``` + +#### Fallback Mechanisms +Each time series operator includes intelligent fallbacks: + +```python +def _safe_rolling_mean(self, feature_data): + if self.enable_time_series and hasattr(self, '_current_data'): + # Use time-based operations with datetime awareness + return self._apply_time_based_operation(...) + else: + # Fallback to pandas rolling (original behavior) + return pd.Series(feature_data).rolling(...).mean() +``` + +## Backward Compatibility + +### Original Behavior Preserved +- **Default Settings**: `enable_time_series=False` maintains exact original behavior +- **Operator Set**: Original operators unchanged, time series operators only added when enabled +- **Method Signatures**: All original methods maintain identical signatures +- **Output Format**: Same output structure and data types + +### Migration Path +```python +# Original usage (unchanged) +bf = BigFeat(task_type='classification') +features = bf.fit(X, y) + +# Enhanced usage (new capabilities) +bf = BigFeat(task_type='classification', + enable_time_series=True, + datetime_col='timestamp', + window_sizes=['7D', '30D', '90D']) +features = bf.fit(X_with_datetime, y) +``` + +## New Capabilities + +### 1. Time-Aware Feature Engineering +```python +# Supports DataFrames with datetime columns +df = pd.DataFrame({ + 'timestamp': pd.date_range('2020-01-01', periods=1000, freq='D'), + 'feature1': np.random.randn(1000), + 'feature2': np.random.randn(1000), + 'group_id': np.random.choice(['A', 'B', 'C'], 1000) +}) + +bf = BigFeat(enable_time_series=True, + datetime_col='timestamp', + groupby_cols=['group_id'], + window_sizes=['7D', '14D', '30D'], + lag_periods=['1D', '7D', '14D']) + +features = bf.fit(df, target) +``` + +### 2. Flexible Time Window Definitions +```python +# String formats +window_sizes = ['7D', '14D', '30D', '3M', '6M', '1Y'] + +# Pandas Timedelta objects +window_sizes = [pd.Timedelta(days=7), pd.Timedelta(days=30)] + +# Mixed formats supported +``` + +### 3. Grouped Time Series Operations +- Automatically handles multiple time series within the same dataset +- Respects group boundaries when applying temporal operations +- Maintains proper temporal ordering within groups + +### 4. Robust Error Handling +```python +def _clean_feature(self, feature_data): + """Clean feature data to ensure stability""" + # Replace inf with large finite values + # Replace nan with zeros + # Clip extreme values + # Type safety checks +``` + +## Implementation Details + +### Memory Efficiency +- Time series data is processed incrementally where possible +- Original data is stored only when needed for datetime operations +- Efficient groupby operations using pandas native methods + +### Performance Optimizations +- Lazy evaluation of time series operations +- Caching of group structures +- Vectorized operations where possible +- Intelligent fallbacks to avoid computation overhead + +### Error Resilience +- All time series operations wrapped in try-catch blocks +- Graceful fallbacks to non-time-aware operations +- Data validation and cleaning at multiple stages +- Informative warning messages when operations fail + +## Testing and Validation + +### Backward Compatibility Tests +- All original test cases should pass unchanged +- Same random seed produces identical results when time series disabled +- Performance benchmarks maintained for non-time-series usage + +### New Functionality Tests +- Time series operations with various window sizes +- Grouped time series handling +- DateTime column detection and processing +- Edge cases (missing data, irregular time series, etc.) + +## Usage Examples + +### Basic Time Series Enhancement +```python +import pandas as pd +from enhanced_bigfeat import BigFeat + +# Prepare time series data +df = pd.DataFrame({ + 'date': pd.date_range('2020-01-01', periods=365), + 'sales': np.random.randn(365).cumsum(), + 'price': np.random.randn(365) + 100, + 'store_id': np.random.choice(['A', 'B', 'C'], 365) +}) + +# Create BigFeat with time series support +bf = BigFeat( + task_type='regression', + enable_time_series=True, + datetime_col='date', + groupby_cols=['store_id'], + window_sizes=['7D', '30D', '90D'], + verbose=True +) + +# Generate features +features = bf.fit(df, target) +``` + +### Advanced Configuration +```python +# Custom time periods and operations +bf = BigFeat( + enable_time_series=True, + datetime_col='timestamp', + window_sizes=[ + pd.Timedelta(days=7), + pd.Timedelta(weeks=2), + pd.Timedelta(days=90) + ], + lag_periods=['1D', '3D', '7D', '14D'], + time_step='H' # Hourly resampling +) +``` + +## Migration Guide + +### For Existing Users +1. **No Changes Required**: Existing code continues to work unchanged +2. **Gradual Migration**: Add time series parameters incrementally +3. **Testing**: Verify results match expectations before deploying + +### For New Time Series Projects +1. **DataFrame Input**: Use pandas DataFrames with datetime columns +2. **Column Specification**: Clearly specify datetime and groupby columns +3. **Window Selection**: Choose appropriate time windows for your domain +4. **Validation**: Test with known time series patterns + +## Conclusion + +The enhanced BigFeat successfully extends the original library's capabilities while maintaining perfect backward compatibility. The time series enhancements provide powerful new feature engineering capabilities for temporal data while preserving all existing functionality for users who don't need time series features. + +Key benefits: +- ✅ **100% Backward Compatible**: Existing code unchanged +- ✅ **Powerful Time Series Support**: 15 new temporal operators +- ✅ **Flexible Configuration**: Customizable windows and periods +- ✅ **Robust Implementation**: Error handling and fallbacks +- ✅ **Performance Optimized**: Efficient time series processing +- ✅ **Well Documented**: Clear usage patterns and examples \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index cd77771..935b038 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,12 +1,40 @@ +beautifulsoup4==4.13.4 bigfeat==0.1 +certifi==2025.8.3 +cffi==1.17.1 +charset-normalizer==3.4.3 +contourpy==1.3.3 +curl_cffi==0.13.0 +cycler==0.12.1 +fonttools==4.59.0 +frozendict==2.4.6 +idna==3.10 joblib==1.4.2 +kiwisolver==1.4.9 lightgbm==4.6.0 +matplotlib==3.10.5 +multitasking==0.0.12 numpy==2.2.5 +packaging==25.0 pandas==2.2.3 +pandas-stubs==2.3.0.250703 +peewee==3.18.2 +pillow==11.3.0 +platformdirs==4.3.8 +protobuf==6.31.1 +pycparser==2.22 +pyparsing==3.2.3 python-dateutil==2.9.0.post0 pytz==2025.2 +requests==2.32.4 scikit-learn==1.6.1 scipy==1.15.2 +seaborn==0.13.2 six==1.17.0 +soupsieve==2.7 threadpoolctl==3.6.0 +typing_extensions==4.14.1 tzdata==2025.2 +urllib3==2.5.0 +websockets==15.0.1 +yfinance==0.2.65 diff --git a/testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Long-term)_feature_info_20250814_194036.json b/testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Long-term)_feature_info_20250814_194036.json new file mode 100644 index 0000000..a47d2c0 --- /dev/null +++ b/testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Long-term)_feature_info_20250814_194036.json @@ -0,0 +1,63 @@ +{ + "feature_names": [ + "Gen_Feat_0_absolute_square", + "Gen_Feat_1_trend_feature", + "Gen_Feat_2_rolling_sum_absolute", + "Gen_Feat_3_absolute_seasonal_decompose", + "Gen_Feat_4_subtract", + "Gen_Feat_5_multiply", + "Gen_Feat_6_add", + "Gen_Feat_7_rolling_std_seasonal_decompose", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_Price_Range", + "Original_SMA_7", + "Original_SMA_30", + "Original_Price_Position", + "Original_DayOfWeek", + "Original_Month" + ], + "feature_descriptions": [ + "absolute -> square -> add -> absolute(Price_Range, SMA_30)", + "trend_feature(Open)", + "rolling_sum -> absolute -> rolling_std(Volatility)", + "absolute -> seasonal_decompose(Volatility)", + "subtract(Price_Position, Price_Range)", + "multiply(Volatility, High)", + "add(Price_Position, Price_Range)", + "rolling_std -> seasonal_decompose(Low)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: Price_Range", + "Original: SMA_7", + "Original: SMA_30", + "Original: Price_Position", + "Original: DayOfWeek", + "Original: Month" + ], + "n_generated_features": 8, + "n_original_features": 12, + "total_features": 20, + "ts_ops_count": 6, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "6M", + "1Y" + ], + "lag_periods": [ + "60D", + "90D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Medium-term)_feature_info_20250814_194033.json b/testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Medium-term)_feature_info_20250814_194033.json new file mode 100644 index 0000000..f5d5d3a --- /dev/null +++ b/testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Medium-term)_feature_info_20250814_194033.json @@ -0,0 +1,68 @@ +{ + "feature_names": [ + "Gen_Feat_0_subtract_absolute", + "Gen_Feat_1_absolute", + "Gen_Feat_2_trend_feature", + "Gen_Feat_3_subtract", + "Gen_Feat_4_rolling_std", + "Gen_Feat_5_square", + "Gen_Feat_6_trend_feature", + "Gen_Feat_7_rolling_std_rolling_median", + "Gen_Feat_8_add_absolute", + "Gen_Feat_9_seasonal_decompose", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_Price_Range", + "Original_SMA_7", + "Original_SMA_30", + "Original_Price_Position", + "Original_DayOfWeek", + "Original_Month" + ], + "feature_descriptions": [ + "subtract -> absolute(SMA_30, DayOfWeek)", + "absolute(Returns)", + "trend_feature(SMA_7)", + "subtract(Volatility, DayOfWeek)", + "rolling_std(SMA_7)", + "square(Price_Position)", + "trend_feature(Volatility)", + "rolling_std -> rolling_median -> add(DayOfWeek, Volatility)", + "add -> absolute(DayOfWeek, Month)", + "seasonal_decompose(Volatility)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: Price_Range", + "Original: SMA_7", + "Original: SMA_30", + "Original: Price_Position", + "Original: DayOfWeek", + "Original: Month" + ], + "n_generated_features": 10, + "n_original_features": 12, + "total_features": 22, + "ts_ops_count": 6, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "30D", + "60D", + "90D" + ], + "lag_periods": [ + "14D", + "30D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Mixed)_feature_info_20250814_194041.json b/testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Mixed)_feature_info_20250814_194041.json new file mode 100644 index 0000000..8637d91 --- /dev/null +++ b/testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Mixed)_feature_info_20250814_194041.json @@ -0,0 +1,79 @@ +{ + "feature_names": [ + "Gen_Feat_0_multiply", + "Gen_Feat_1_add_rolling_std", + "Gen_Feat_2_rolling_sum", + "Gen_Feat_3_add_rolling_std", + "Gen_Feat_4_trend_feature", + "Gen_Feat_5_square", + "Gen_Feat_6_add", + "Gen_Feat_7_add_rolling_sum", + "Gen_Feat_8_add_rolling_std", + "Gen_Feat_9_rolling_max_square", + "Gen_Feat_10_pct_change_rolling_std", + "Gen_Feat_11_rolling_min", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_Price_Range", + "Original_SMA_7", + "Original_SMA_30", + "Original_Price_Position", + "Original_DayOfWeek", + "Original_Month" + ], + "feature_descriptions": [ + "multiply(Volatility, Price_Position)", + "add -> rolling_std(DayOfWeek, Price_Position)", + "rolling_sum(Price_Position)", + "add -> rolling_std(SMA_30, Volatility)", + "trend_feature(Open)", + "square(Price_Position)", + "add(SMA_30, High)", + "add -> rolling_sum(Volatility, Volatility)", + "add -> rolling_std(Returns, Returns)", + "rolling_max -> square -> rolling_sum(Returns)", + "pct_change -> rolling_std -> seasonal_decompose(Price_Position)", + "rolling_min(Price_Position)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: Price_Range", + "Original: SMA_7", + "Original: SMA_30", + "Original: Price_Position", + "Original: DayOfWeek", + "Original: Month" + ], + "n_generated_features": 12, + "n_original_features": 12, + "total_features": 24, + "ts_ops_count": 12, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "3D", + "7D", + "14D", + "21D", + "30D", + "60D", + "90D" + ], + "lag_periods": [ + "1D", + "3D", + "7D", + "14D", + "30D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Short-term)_feature_info_20250814_194030.json b/testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Short-term)_feature_info_20250814_194030.json new file mode 100644 index 0000000..f0b7db8 --- /dev/null +++ b/testing/results/Cryptocurrency_Daily_Crypto_Direction_Prediction_Time Series (Short-term)_feature_info_20250814_194030.json @@ -0,0 +1,70 @@ +{ + "feature_names": [ + "Gen_Feat_0_trend_feature_diff_feature", + "Gen_Feat_1_absolute_trend_feature", + "Gen_Feat_2_ewm_square", + "Gen_Feat_3_add", + "Gen_Feat_4_add_absolute", + "Gen_Feat_5_rolling_std", + "Gen_Feat_6_seasonal_decompose_lag_feature", + "Gen_Feat_7_rolling_std", + "Gen_Feat_8_rolling_median", + "Gen_Feat_9_trend_feature", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_Price_Range", + "Original_SMA_7", + "Original_SMA_30", + "Original_Price_Position", + "Original_DayOfWeek", + "Original_Month" + ], + "feature_descriptions": [ + "trend_feature -> diff_feature -> seasonal_decompose(Price_Position)", + "absolute -> trend_feature -> add(SMA_30, Price_Range)", + "ewm -> square -> rolling_std(Price_Position)", + "add(Returns, Returns)", + "add -> absolute -> trend_feature(High, Open)", + "rolling_std(SMA_7)", + "seasonal_decompose -> lag_feature -> trend_feature(SMA_30)", + "rolling_std(SMA_7)", + "rolling_median(Returns)", + "trend_feature(Returns)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: Price_Range", + "Original: SMA_7", + "Original: SMA_30", + "Original: Price_Position", + "Original: DayOfWeek", + "Original: Month" + ], + "n_generated_features": 10, + "n_original_features": 12, + "total_features": 22, + "ts_ops_count": 14, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "3D", + "7D", + "14D", + "21D" + ], + "lag_periods": [ + "1D", + "3D", + "7D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Long-term)_feature_info_20250814_194055.json b/testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Long-term)_feature_info_20250814_194055.json new file mode 100644 index 0000000..6ef0052 --- /dev/null +++ b/testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Long-term)_feature_info_20250814_194055.json @@ -0,0 +1,63 @@ +{ + "feature_names": [ + "Gen_Feat_0_rolling_median_momentum", + "Gen_Feat_1_absolute", + "Gen_Feat_2_subtract", + "Gen_Feat_3_multiply_subtract", + "Gen_Feat_4_diff_feature_seasonal_decompose", + "Gen_Feat_5_square", + "Gen_Feat_6_subtract", + "Gen_Feat_7_pct_change_absolute", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_Price_Range", + "Original_SMA_7", + "Original_SMA_30", + "Original_Price_Position", + "Original_DayOfWeek", + "Original_Month" + ], + "feature_descriptions": [ + "rolling_median -> momentum -> diff_feature -> seasonal_decompose -> add(SMA_30, Open)", + "absolute(Volatility)", + "subtract(SMA_30, High)", + "multiply -> subtract -> multiply(Price_Position, Volatility, SMA_7, Price_Position)", + "diff_feature -> seasonal_decompose(Price_Position)", + "square(Price_Position)", + "subtract(Price_Range, Low)", + "pct_change -> absolute -> rolling_sum(Price_Position)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: Price_Range", + "Original: SMA_7", + "Original: SMA_30", + "Original: Price_Position", + "Original: DayOfWeek", + "Original: Month" + ], + "n_generated_features": 8, + "n_original_features": 12, + "total_features": 20, + "ts_ops_count": 8, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "6M", + "1Y" + ], + "lag_periods": [ + "60D", + "90D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Medium-term)_feature_info_20250814_194051.json b/testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Medium-term)_feature_info_20250814_194051.json new file mode 100644 index 0000000..d9579a4 --- /dev/null +++ b/testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Medium-term)_feature_info_20250814_194051.json @@ -0,0 +1,72 @@ +{ + "feature_names": [ + "Gen_Feat_0_multiply", + "Gen_Feat_1_rolling_std", + "Gen_Feat_2_absolute", + "Gen_Feat_3_subtract", + "Gen_Feat_4_weekday_mean", + "Gen_Feat_5_month_mean_seasonal_decompose", + "Gen_Feat_6_month_mean_rolling_mean", + "Gen_Feat_7_trend_feature_square", + "Gen_Feat_8_seasonal_decompose", + "Gen_Feat_9_multiply", + "Gen_Feat_10_rolling_std", + "Gen_Feat_11_seasonal_decompose_month_mean", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_Price_Range", + "Original_SMA_7", + "Original_SMA_30", + "Original_Price_Position", + "Original_DayOfWeek", + "Original_Month" + ], + "feature_descriptions": [ + "multiply(Returns, Low)", + "rolling_std(Month)", + "absolute(Returns)", + "subtract(Returns, DayOfWeek)", + "weekday_mean(Price_Position)", + "month_mean -> seasonal_decompose(Volatility)", + "month_mean -> rolling_mean -> multiply(Volatility, Price_Position)", + "trend_feature -> square(Month)", + "seasonal_decompose(Returns)", + "multiply(Returns, Volatility)", + "rolling_std(Volatility)", + "seasonal_decompose -> month_mean -> trend_feature(Price_Range)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: Price_Range", + "Original: SMA_7", + "Original: SMA_30", + "Original: Price_Position", + "Original: DayOfWeek", + "Original: Month" + ], + "n_generated_features": 12, + "n_original_features": 12, + "total_features": 24, + "ts_ops_count": 12, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "30D", + "60D", + "90D" + ], + "lag_periods": [ + "14D", + "30D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Mixed)_feature_info_20250814_194100.json b/testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Mixed)_feature_info_20250814_194100.json new file mode 100644 index 0000000..273dc05 --- /dev/null +++ b/testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Mixed)_feature_info_20250814_194100.json @@ -0,0 +1,77 @@ +{ + "feature_names": [ + "Gen_Feat_0_add", + "Gen_Feat_1_rolling_mean", + "Gen_Feat_2_rolling_std_rolling_mean", + "Gen_Feat_3_add_rolling_mean", + "Gen_Feat_4_rolling_median", + "Gen_Feat_5_add", + "Gen_Feat_6_rolling_median_rolling_mean", + "Gen_Feat_7_multiply_rolling_mean", + "Gen_Feat_8_multiply_rolling_mean", + "Gen_Feat_9_multiply", + "Gen_Feat_10_rolling_sum", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_Price_Range", + "Original_SMA_7", + "Original_SMA_30", + "Original_Price_Position", + "Original_DayOfWeek", + "Original_Month" + ], + "feature_descriptions": [ + "add(Volatility, DayOfWeek)", + "rolling_mean(Volatility)", + "rolling_std -> rolling_mean -> add(SMA_30, Returns)", + "add -> rolling_mean -> subtract -> multiply -> rolling_mean -> add(Returns, Price_Position, Volatility, Volatility, Price_Position)", + "rolling_median(Volatility)", + "add(SMA_30, Volatility)", + "rolling_median -> rolling_mean -> rolling_mean(Returns)", + "multiply -> rolling_mean(Price_Position, Volatility)", + "multiply -> rolling_mean(Low, Returns)", + "multiply(Price_Position, Volatility)", + "rolling_sum(Returns)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: Price_Range", + "Original: SMA_7", + "Original: SMA_30", + "Original: Price_Position", + "Original: DayOfWeek", + "Original: Month" + ], + "n_generated_features": 11, + "n_original_features": 12, + "total_features": 23, + "ts_ops_count": 12, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "3D", + "7D", + "14D", + "21D", + "30D", + "60D", + "90D" + ], + "lag_periods": [ + "1D", + "3D", + "7D", + "14D", + "30D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Short-term)_feature_info_20250814_194046.json b/testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Short-term)_feature_info_20250814_194046.json new file mode 100644 index 0000000..b078433 --- /dev/null +++ b/testing/results/Cryptocurrency_Daily_Crypto_Return_Prediction_Time Series (Short-term)_feature_info_20250814_194046.json @@ -0,0 +1,70 @@ +{ + "feature_names": [ + "Gen_Feat_0_add_rolling_std", + "Gen_Feat_1_add", + "Gen_Feat_2_rolling_sum", + "Gen_Feat_3_lag_feature_absolute", + "Gen_Feat_4_rolling_median", + "Gen_Feat_5_add_absolute", + "Gen_Feat_6_add_absolute", + "Gen_Feat_7_rolling_max_trend_feature", + "Gen_Feat_8_add", + "Gen_Feat_9_rolling_min", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_Price_Range", + "Original_SMA_7", + "Original_SMA_30", + "Original_Price_Position", + "Original_DayOfWeek", + "Original_Month" + ], + "feature_descriptions": [ + "add -> rolling_std(Price_Range, Price_Position)", + "add(Price_Range, Volatility)", + "rolling_sum(Returns)", + "lag_feature -> absolute -> trend_feature(Open)", + "rolling_median(Returns)", + "add -> absolute(SMA_30, DayOfWeek)", + "add -> absolute(DayOfWeek, Month)", + "rolling_max -> trend_feature -> month_mean -> rolling_std -> add(Low, Volatility)", + "add(Open, Month)", + "rolling_min(Volatility)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: Price_Range", + "Original: SMA_7", + "Original: SMA_30", + "Original: Price_Position", + "Original: DayOfWeek", + "Original: Month" + ], + "n_generated_features": 10, + "n_original_features": 12, + "total_features": 22, + "ts_ops_count": 10, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "3D", + "7D", + "14D", + "21D" + ], + "lag_periods": [ + "1D", + "3D", + "7D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Long-term)_feature_info_20250814_194250.json b/testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Long-term)_feature_info_20250814_194250.json new file mode 100644 index 0000000..34e7761 --- /dev/null +++ b/testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Long-term)_feature_info_20250814_194250.json @@ -0,0 +1,56 @@ +{ + "feature_names": [ + "Gen_Feat_0_multiply", + "Gen_Feat_1_rolling_median", + "Gen_Feat_2_add_absolute", + "Gen_Feat_3_multiply", + "Gen_Feat_4_trend_feature", + "Gen_Feat_5_month_mean_absolute", + "Original_Temperature", + "Original_Hour", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_IsWeekend", + "Original_IsHoliday", + "Original_IsBusinessHour", + "Original_HourlyPattern", + "Original_WeatherEffect" + ], + "feature_descriptions": [ + "multiply(WeatherEffect, Temperature)", + "rolling_median(Temperature)", + "add -> absolute -> subtract(WeatherEffect, DayOfWeek, WeatherEffect)", + "multiply(Temperature, HourlyPattern)", + "trend_feature(DayOfWeek)", + "month_mean -> absolute -> add(HourlyPattern, Temperature)", + "Original: Temperature", + "Original: Hour", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: IsWeekend", + "Original: IsHoliday", + "Original: IsBusinessHour", + "Original: HourlyPattern", + "Original: WeatherEffect" + ], + "n_generated_features": 6, + "n_original_features": 10, + "total_features": 16, + "ts_ops_count": 3, + "datetime_col": "DateTime", + "groupby_cols": [], + "window_sizes": [ + "7D", + "14D", + "30D", + "60D" + ], + "lag_periods": [ + "7D", + "14D", + "30D" + ], + "time_step": "H" +} \ No newline at end of file diff --git a/testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Medium-term)_feature_info_20250814_194241.json b/testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Medium-term)_feature_info_20250814_194241.json new file mode 100644 index 0000000..2786cde --- /dev/null +++ b/testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Medium-term)_feature_info_20250814_194241.json @@ -0,0 +1,52 @@ +{ + "feature_names": [ + "Gen_Feat_0_absolute", + "Gen_Feat_1_rolling_max", + "Gen_Feat_2_month_mean_absolute", + "Gen_Feat_3_absolute_absolute", + "Original_Temperature", + "Original_Hour", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_IsWeekend", + "Original_IsHoliday", + "Original_IsBusinessHour", + "Original_HourlyPattern", + "Original_WeatherEffect" + ], + "feature_descriptions": [ + "absolute(HourlyPattern)", + "rolling_max(Temperature)", + "month_mean -> absolute -> multiply(Month, WeatherEffect)", + "absolute -> absolute -> multiply -> absolute(Month, HourlyPattern)", + "Original: Temperature", + "Original: Hour", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: IsWeekend", + "Original: IsHoliday", + "Original: IsBusinessHour", + "Original: HourlyPattern", + "Original: WeatherEffect" + ], + "n_generated_features": 4, + "n_original_features": 10, + "total_features": 14, + "ts_ops_count": 2, + "datetime_col": "DateTime", + "groupby_cols": [], + "window_sizes": [ + "1D", + "3D", + "7D", + "14D" + ], + "lag_periods": [ + "1D", + "3D", + "7D" + ], + "time_step": "H" +} \ No newline at end of file diff --git a/testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Mixed)_feature_info_20250814_194301.json b/testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Mixed)_feature_info_20250814_194301.json new file mode 100644 index 0000000..83bfaf7 --- /dev/null +++ b/testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Mixed)_feature_info_20250814_194301.json @@ -0,0 +1,63 @@ +{ + "feature_names": [ + "Gen_Feat_0_multiply", + "Gen_Feat_1_rolling_sum", + "Gen_Feat_2_rolling_max", + "Gen_Feat_3_add", + "Gen_Feat_4_multiply_add", + "Original_Temperature", + "Original_Hour", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_IsWeekend", + "Original_IsHoliday", + "Original_IsBusinessHour", + "Original_HourlyPattern", + "Original_WeatherEffect" + ], + "feature_descriptions": [ + "multiply(HourlyPattern, Temperature)", + "rolling_sum(DayOfWeek)", + "rolling_max(Temperature)", + "add(HourlyPattern, WeatherEffect)", + "multiply -> add -> add(HourlyPattern, Temperature, Hour, Temperature)", + "Original: Temperature", + "Original: Hour", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: IsWeekend", + "Original: IsHoliday", + "Original: IsBusinessHour", + "Original: HourlyPattern", + "Original: WeatherEffect" + ], + "n_generated_features": 5, + "n_original_features": 10, + "total_features": 15, + "ts_ops_count": 2, + "datetime_col": "DateTime", + "groupby_cols": [], + "window_sizes": [ + "1H", + "3H", + "6H", + "12H", + "1D", + "1D", + "3D", + "7D", + "14D" + ], + "lag_periods": [ + "1H", + "3H", + "6H", + "12H", + "1D", + "3D", + "7D" + ], + "time_step": "H" +} \ No newline at end of file diff --git a/testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Short-term)_feature_info_20250814_194233.json b/testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Short-term)_feature_info_20250814_194233.json new file mode 100644 index 0000000..8221625 --- /dev/null +++ b/testing/results/Energy_Consumption_Hourly_Energy_High_Consumption_Time Series (Short-term)_feature_info_20250814_194233.json @@ -0,0 +1,54 @@ +{ + "feature_names": [ + "Gen_Feat_0_seasonal_decompose", + "Gen_Feat_1_subtract", + "Gen_Feat_2_subtract", + "Gen_Feat_3_rolling_std_rolling_max", + "Original_Temperature", + "Original_Hour", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_IsWeekend", + "Original_IsHoliday", + "Original_IsBusinessHour", + "Original_HourlyPattern", + "Original_WeatherEffect" + ], + "feature_descriptions": [ + "seasonal_decompose(Temperature)", + "subtract(IsWeekend, HourlyPattern)", + "subtract(Temperature, IsWeekend)", + "rolling_std -> rolling_max -> month_mean -> seasonal_decompose -> subtract -> multiply(IsBusinessHour, HourlyPattern, Temperature)", + "Original: Temperature", + "Original: Hour", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: IsWeekend", + "Original: IsHoliday", + "Original: IsBusinessHour", + "Original: HourlyPattern", + "Original: WeatherEffect" + ], + "n_generated_features": 4, + "n_original_features": 10, + "total_features": 14, + "ts_ops_count": 5, + "datetime_col": "DateTime", + "groupby_cols": [], + "window_sizes": [ + "1H", + "3H", + "6H", + "12H", + "1D" + ], + "lag_periods": [ + "1H", + "3H", + "6H", + "12H" + ], + "time_step": "H" +} \ No newline at end of file diff --git a/testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Long-term)_feature_info_20250814_194338.json b/testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Long-term)_feature_info_20250814_194338.json new file mode 100644 index 0000000..24ca316 --- /dev/null +++ b/testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Long-term)_feature_info_20250814_194338.json @@ -0,0 +1,56 @@ +{ + "feature_names": [ + "Gen_Feat_0_absolute_absolute", + "Gen_Feat_1_subtract_square", + "Gen_Feat_2_month_mean_absolute", + "Gen_Feat_3_rolling_std", + "Gen_Feat_4_square", + "Gen_Feat_5_multiply", + "Original_Temperature", + "Original_Hour", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_IsWeekend", + "Original_IsHoliday", + "Original_IsBusinessHour", + "Original_HourlyPattern", + "Original_WeatherEffect" + ], + "feature_descriptions": [ + "absolute -> absolute(Hour)", + "subtract -> square(Month, HourlyPattern)", + "month_mean -> absolute -> add(HourlyPattern, Temperature)", + "rolling_std(Quarter)", + "square(DayOfWeek)", + "multiply(HourlyPattern, Month)", + "Original: Temperature", + "Original: Hour", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: IsWeekend", + "Original: IsHoliday", + "Original: IsBusinessHour", + "Original: HourlyPattern", + "Original: WeatherEffect" + ], + "n_generated_features": 6, + "n_original_features": 10, + "total_features": 16, + "ts_ops_count": 2, + "datetime_col": "DateTime", + "groupby_cols": [], + "window_sizes": [ + "7D", + "14D", + "30D", + "60D" + ], + "lag_periods": [ + "7D", + "14D", + "30D" + ], + "time_step": "H" +} \ No newline at end of file diff --git a/testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Medium-term)_feature_info_20250814_194326.json b/testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Medium-term)_feature_info_20250814_194326.json new file mode 100644 index 0000000..14acde9 --- /dev/null +++ b/testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Medium-term)_feature_info_20250814_194326.json @@ -0,0 +1,58 @@ +{ + "feature_names": [ + "Gen_Feat_0_trend_feature", + "Gen_Feat_1_absolute", + "Gen_Feat_2_rolling_std_rolling_median", + "Gen_Feat_3_rolling_std", + "Gen_Feat_4_rolling_std", + "Gen_Feat_5_trend_feature_trend_feature", + "Gen_Feat_6_absolute_square", + "Original_Temperature", + "Original_Hour", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_IsWeekend", + "Original_IsHoliday", + "Original_IsBusinessHour", + "Original_HourlyPattern", + "Original_WeatherEffect" + ], + "feature_descriptions": [ + "trend_feature(Temperature)", + "absolute(DayOfWeek)", + "rolling_std -> rolling_median(Temperature)", + "rolling_std(Temperature)", + "rolling_std(Temperature)", + "trend_feature -> trend_feature(HourlyPattern)", + "absolute -> square -> add -> absolute(Month, HourlyPattern)", + "Original: Temperature", + "Original: Hour", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: IsWeekend", + "Original: IsHoliday", + "Original: IsBusinessHour", + "Original: HourlyPattern", + "Original: WeatherEffect" + ], + "n_generated_features": 7, + "n_original_features": 10, + "total_features": 17, + "ts_ops_count": 7, + "datetime_col": "DateTime", + "groupby_cols": [], + "window_sizes": [ + "1D", + "3D", + "7D", + "14D" + ], + "lag_periods": [ + "1D", + "3D", + "7D" + ], + "time_step": "H" +} \ No newline at end of file diff --git a/testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Mixed)_feature_info_20250814_194355.json b/testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Mixed)_feature_info_20250814_194355.json new file mode 100644 index 0000000..80773b5 --- /dev/null +++ b/testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Mixed)_feature_info_20250814_194355.json @@ -0,0 +1,63 @@ +{ + "feature_names": [ + "Gen_Feat_0_rolling_max", + "Gen_Feat_1_rolling_mean", + "Gen_Feat_2_rolling_max", + "Gen_Feat_3_multiply", + "Gen_Feat_4_add_absolute", + "Original_Temperature", + "Original_Hour", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_IsWeekend", + "Original_IsHoliday", + "Original_IsBusinessHour", + "Original_HourlyPattern", + "Original_WeatherEffect" + ], + "feature_descriptions": [ + "rolling_max(DayOfWeek)", + "rolling_mean(DayOfWeek)", + "rolling_max(Temperature)", + "multiply(HourlyPattern, Quarter)", + "add -> absolute(HourlyPattern, WeatherEffect)", + "Original: Temperature", + "Original: Hour", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: IsWeekend", + "Original: IsHoliday", + "Original: IsBusinessHour", + "Original: HourlyPattern", + "Original: WeatherEffect" + ], + "n_generated_features": 5, + "n_original_features": 10, + "total_features": 15, + "ts_ops_count": 3, + "datetime_col": "DateTime", + "groupby_cols": [], + "window_sizes": [ + "1H", + "3H", + "6H", + "12H", + "1D", + "1D", + "3D", + "7D", + "14D" + ], + "lag_periods": [ + "1H", + "3H", + "6H", + "12H", + "1D", + "3D", + "7D" + ], + "time_step": "H" +} \ No newline at end of file diff --git a/testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Short-term)_feature_info_20250814_194316.json b/testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Short-term)_feature_info_20250814_194316.json new file mode 100644 index 0000000..a2928a5 --- /dev/null +++ b/testing/results/Energy_Consumption_Hourly_Energy_Next_Hour_Prediction_Time Series (Short-term)_feature_info_20250814_194316.json @@ -0,0 +1,56 @@ +{ + "feature_names": [ + "Gen_Feat_0_rolling_min", + "Gen_Feat_1_subtract", + "Gen_Feat_2_subtract", + "Gen_Feat_3_square_pct_change", + "Gen_Feat_4_add", + "Original_Temperature", + "Original_Hour", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_IsWeekend", + "Original_IsHoliday", + "Original_IsBusinessHour", + "Original_HourlyPattern", + "Original_WeatherEffect" + ], + "feature_descriptions": [ + "rolling_min(Temperature)", + "subtract(HourlyPattern, Temperature)", + "subtract(Temperature, Quarter)", + "square -> pct_change -> rolling_sum(DayOfWeek)", + "add(Quarter, HourlyPattern)", + "Original: Temperature", + "Original: Hour", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: IsWeekend", + "Original: IsHoliday", + "Original: IsBusinessHour", + "Original: HourlyPattern", + "Original: WeatherEffect" + ], + "n_generated_features": 5, + "n_original_features": 10, + "total_features": 15, + "ts_ops_count": 3, + "datetime_col": "DateTime", + "groupby_cols": [], + "window_sizes": [ + "1H", + "3H", + "6H", + "12H", + "1D" + ], + "lag_periods": [ + "1H", + "3H", + "6H", + "12H" + ], + "time_step": "H" +} \ No newline at end of file diff --git a/testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Long-term)_feature_info_20250814_194119.json b/testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Long-term)_feature_info_20250814_194119.json new file mode 100644 index 0000000..494c243 --- /dev/null +++ b/testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Long-term)_feature_info_20250814_194119.json @@ -0,0 +1,48 @@ +{ + "feature_names": [ + "Gen_Feat_0_multiply", + "Gen_Feat_1_add", + "Gen_Feat_2_month_mean_absolute", + "Original_Customers", + "Original_AvgTransaction", + "Original_FootTraffic", + "Original_HasPromo", + "Original_IsWeekend", + "Original_Temperature", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_WeekOfYear" + ], + "feature_descriptions": [ + "multiply(Customers, AvgTransaction)", + "add(Customers, Customers)", + "month_mean -> absolute -> multiply -> multiply -> square -> multiply -> multiply(FootTraffic, AvgTransaction, Customers, Customers, Customers)", + "Original: Customers", + "Original: AvgTransaction", + "Original: FootTraffic", + "Original: HasPromo", + "Original: IsWeekend", + "Original: Temperature", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: WeekOfYear" + ], + "n_generated_features": 3, + "n_original_features": 10, + "total_features": 13, + "ts_ops_count": 1, + "datetime_col": "Date", + "groupby_cols": [ + "Store" + ], + "window_sizes": [ + "1Y" + ], + "lag_periods": [ + "90D", + "180D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Medium-term)_feature_info_20250814_194112.json b/testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Medium-term)_feature_info_20250814_194112.json new file mode 100644 index 0000000..4a7c63b --- /dev/null +++ b/testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Medium-term)_feature_info_20250814_194112.json @@ -0,0 +1,50 @@ +{ + "feature_names": [ + "Gen_Feat_0_square", + "Gen_Feat_1_square", + "Gen_Feat_2_multiply", + "Original_Customers", + "Original_AvgTransaction", + "Original_FootTraffic", + "Original_HasPromo", + "Original_IsWeekend", + "Original_Temperature", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_WeekOfYear" + ], + "feature_descriptions": [ + "square(Customers)", + "square(AvgTransaction)", + "multiply(Customers, AvgTransaction)", + "Original: Customers", + "Original: AvgTransaction", + "Original: FootTraffic", + "Original: HasPromo", + "Original: IsWeekend", + "Original: Temperature", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: WeekOfYear" + ], + "n_generated_features": 3, + "n_original_features": 10, + "total_features": 13, + "ts_ops_count": 0, + "datetime_col": "Date", + "groupby_cols": [ + "Store" + ], + "window_sizes": [ + "60D", + "90D", + "180D" + ], + "lag_periods": [ + "30D", + "60D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Mixed)_feature_info_20250814_194126.json b/testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Mixed)_feature_info_20250814_194126.json new file mode 100644 index 0000000..c00d677 --- /dev/null +++ b/testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Mixed)_feature_info_20250814_194126.json @@ -0,0 +1,56 @@ +{ + "feature_names": [ + "Gen_Feat_0_absolute", + "Gen_Feat_1_add", + "Gen_Feat_2_multiply_lag_feature", + "Original_Customers", + "Original_AvgTransaction", + "Original_FootTraffic", + "Original_HasPromo", + "Original_IsWeekend", + "Original_Temperature", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_WeekOfYear" + ], + "feature_descriptions": [ + "absolute(Customers)", + "add(AvgTransaction, Customers)", + "multiply -> lag_feature -> subtract(Customers, AvgTransaction, FootTraffic)", + "Original: Customers", + "Original: AvgTransaction", + "Original: FootTraffic", + "Original: HasPromo", + "Original: IsWeekend", + "Original: Temperature", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: WeekOfYear" + ], + "n_generated_features": 3, + "n_original_features": 10, + "total_features": 13, + "ts_ops_count": 1, + "datetime_col": "Date", + "groupby_cols": [ + "Store" + ], + "window_sizes": [ + "7D", + "14D", + "30D", + "60D", + "90D", + "180D" + ], + "lag_periods": [ + "1D", + "7D", + "14D", + "30D", + "60D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Short-term)_feature_info_20250814_194106.json b/testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Short-term)_feature_info_20250814_194106.json new file mode 100644 index 0000000..3bdbf5f --- /dev/null +++ b/testing/results/Retail_Sales_Daily_Sales_High_Performance_Time Series (Short-term)_feature_info_20250814_194106.json @@ -0,0 +1,49 @@ +{ + "feature_names": [ + "Gen_Feat_0_add", + "Gen_Feat_1_absolute", + "Original_Customers", + "Original_AvgTransaction", + "Original_FootTraffic", + "Original_HasPromo", + "Original_IsWeekend", + "Original_Temperature", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_WeekOfYear" + ], + "feature_descriptions": [ + "add(FootTraffic, AvgTransaction)", + "absolute(Customers)", + "Original: Customers", + "Original: AvgTransaction", + "Original: FootTraffic", + "Original: HasPromo", + "Original: IsWeekend", + "Original: Temperature", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: WeekOfYear" + ], + "n_generated_features": 2, + "n_original_features": 10, + "total_features": 12, + "ts_ops_count": 0, + "datetime_col": "Date", + "groupby_cols": [ + "Store" + ], + "window_sizes": [ + "7D", + "14D", + "30D" + ], + "lag_periods": [ + "1D", + "7D", + "14D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Long-term)_feature_info_20250814_194207.json b/testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Long-term)_feature_info_20250814_194207.json new file mode 100644 index 0000000..1875f18 --- /dev/null +++ b/testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Long-term)_feature_info_20250814_194207.json @@ -0,0 +1,58 @@ +{ + "feature_names": [ + "Gen_Feat_0_multiply_multiply", + "Gen_Feat_1_month_mean_absolute", + "Gen_Feat_2_multiply", + "Gen_Feat_3_rolling_std", + "Gen_Feat_4_multiply", + "Gen_Feat_5_multiply", + "Gen_Feat_6_multiply", + "Gen_Feat_7_multiply", + "Original_Customers", + "Original_AvgTransaction", + "Original_FootTraffic", + "Original_HasPromo", + "Original_IsWeekend", + "Original_Temperature", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_WeekOfYear" + ], + "feature_descriptions": [ + "multiply -> multiply -> multiply(FootTraffic, AvgTransaction, WeekOfYear, Customers)", + "month_mean -> absolute -> add(DayOfWeek, Customers)", + "multiply(AvgTransaction, Customers)", + "rolling_std(Customers)", + "multiply(HasPromo, FootTraffic)", + "multiply(Customers, FootTraffic)", + "multiply(DayOfWeek, DayOfWeek)", + "multiply(WeekOfYear, WeekOfYear)", + "Original: Customers", + "Original: AvgTransaction", + "Original: FootTraffic", + "Original: HasPromo", + "Original: IsWeekend", + "Original: Temperature", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: WeekOfYear" + ], + "n_generated_features": 8, + "n_original_features": 10, + "total_features": 18, + "ts_ops_count": 2, + "datetime_col": "Date", + "groupby_cols": [ + "Store" + ], + "window_sizes": [ + "1Y" + ], + "lag_periods": [ + "90D", + "180D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Medium-term)_feature_info_20250814_194154.json b/testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Medium-term)_feature_info_20250814_194154.json new file mode 100644 index 0000000..e7f6a6c --- /dev/null +++ b/testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Medium-term)_feature_info_20250814_194154.json @@ -0,0 +1,60 @@ +{ + "feature_names": [ + "Gen_Feat_0_absolute", + "Gen_Feat_1_absolute", + "Gen_Feat_2_add", + "Gen_Feat_3_seasonal_decompose", + "Gen_Feat_4_absolute", + "Gen_Feat_5_subtract_absolute", + "Gen_Feat_6_subtract", + "Gen_Feat_7_multiply_subtract", + "Original_Customers", + "Original_AvgTransaction", + "Original_FootTraffic", + "Original_HasPromo", + "Original_IsWeekend", + "Original_Temperature", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_WeekOfYear" + ], + "feature_descriptions": [ + "absolute(DayOfWeek)", + "absolute(Customers)", + "add(WeekOfYear, Temperature)", + "seasonal_decompose(Customers)", + "absolute(AvgTransaction)", + "subtract -> absolute -> multiply(Temperature, WeekOfYear, FootTraffic)", + "subtract(AvgTransaction, WeekOfYear)", + "multiply -> subtract -> subtract -> absolute(WeekOfYear, WeekOfYear, Temperature, Customers)", + "Original: Customers", + "Original: AvgTransaction", + "Original: FootTraffic", + "Original: HasPromo", + "Original: IsWeekend", + "Original: Temperature", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: WeekOfYear" + ], + "n_generated_features": 8, + "n_original_features": 10, + "total_features": 18, + "ts_ops_count": 1, + "datetime_col": "Date", + "groupby_cols": [ + "Store" + ], + "window_sizes": [ + "60D", + "90D", + "180D" + ], + "lag_periods": [ + "30D", + "60D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Mixed)_feature_info_20250814_194222.json b/testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Mixed)_feature_info_20250814_194222.json new file mode 100644 index 0000000..4bdc164 --- /dev/null +++ b/testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Mixed)_feature_info_20250814_194222.json @@ -0,0 +1,62 @@ +{ + "feature_names": [ + "Gen_Feat_0_absolute_multiply", + "Gen_Feat_1_subtract", + "Gen_Feat_2_add", + "Gen_Feat_3_absolute", + "Gen_Feat_4_absolute", + "Gen_Feat_5_multiply_trend_feature", + "Original_Customers", + "Original_AvgTransaction", + "Original_FootTraffic", + "Original_HasPromo", + "Original_IsWeekend", + "Original_Temperature", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_WeekOfYear" + ], + "feature_descriptions": [ + "absolute -> multiply -> multiply(WeekOfYear, WeekOfYear, Customers)", + "subtract(Customers, WeekOfYear)", + "add(AvgTransaction, Customers)", + "absolute(HasPromo)", + "absolute(FootTraffic)", + "multiply -> trend_feature(FootTraffic, FootTraffic)", + "Original: Customers", + "Original: AvgTransaction", + "Original: FootTraffic", + "Original: HasPromo", + "Original: IsWeekend", + "Original: Temperature", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: WeekOfYear" + ], + "n_generated_features": 6, + "n_original_features": 10, + "total_features": 16, + "ts_ops_count": 1, + "datetime_col": "Date", + "groupby_cols": [ + "Store" + ], + "window_sizes": [ + "7D", + "14D", + "30D", + "60D", + "90D", + "180D" + ], + "lag_periods": [ + "1D", + "7D", + "14D", + "30D", + "60D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Short-term)_feature_info_20250814_194142.json b/testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Short-term)_feature_info_20250814_194142.json new file mode 100644 index 0000000..514d771 --- /dev/null +++ b/testing/results/Retail_Sales_Daily_Sales_Next_Day_Prediction_Time Series (Short-term)_feature_info_20250814_194142.json @@ -0,0 +1,63 @@ +{ + "feature_names": [ + "Gen_Feat_0_weekday_mean_rolling_std", + "Gen_Feat_1_add", + "Gen_Feat_2_subtract", + "Gen_Feat_3_subtract", + "Gen_Feat_4_rolling_std", + "Gen_Feat_5_square_momentum", + "Gen_Feat_6_add", + "Gen_Feat_7_add", + "Gen_Feat_8_add", + "Original_Customers", + "Original_AvgTransaction", + "Original_FootTraffic", + "Original_HasPromo", + "Original_IsWeekend", + "Original_Temperature", + "Original_DayOfWeek", + "Original_Month", + "Original_Quarter", + "Original_WeekOfYear" + ], + "feature_descriptions": [ + "weekday_mean -> rolling_std -> multiply(WeekOfYear, FootTraffic)", + "add(AvgTransaction, FootTraffic)", + "subtract(FootTraffic, WeekOfYear)", + "subtract(HasPromo, Temperature)", + "rolling_std(Temperature)", + "square -> momentum -> subtract -> absolute -> add(AvgTransaction, HasPromo, Customers)", + "add(Customers, WeekOfYear)", + "add(FootTraffic, DayOfWeek)", + "add(FootTraffic, Customers)", + "Original: Customers", + "Original: AvgTransaction", + "Original: FootTraffic", + "Original: HasPromo", + "Original: IsWeekend", + "Original: Temperature", + "Original: DayOfWeek", + "Original: Month", + "Original: Quarter", + "Original: WeekOfYear" + ], + "n_generated_features": 9, + "n_original_features": 10, + "total_features": 19, + "ts_ops_count": 4, + "datetime_col": "Date", + "groupby_cols": [ + "Store" + ], + "window_sizes": [ + "7D", + "14D", + "30D" + ], + "lag_periods": [ + "1D", + "7D", + "14D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Long-term)_feature_info_20250814_194409.json b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Long-term)_feature_info_20250814_194409.json new file mode 100644 index 0000000..f0154f0 --- /dev/null +++ b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Long-term)_feature_info_20250814_194409.json @@ -0,0 +1,36 @@ +{ + "feature_names": [ + "Gen_Feat_0_multiply", + "Original_WeekOfYear", + "Original_Month", + "Original_Quarter", + "Original_IsEndOfMonth", + "Original_Feature1", + "Original_Feature2", + "Original_Feature3" + ], + "feature_descriptions": [ + "multiply(Feature3, Feature3)", + "Original: WeekOfYear", + "Original: Month", + "Original: Quarter", + "Original: IsEndOfMonth", + "Original: Feature1", + "Original: Feature2", + "Original: Feature3" + ], + "n_generated_features": 1, + "n_original_features": 7, + "total_features": 8, + "ts_ops_count": 0, + "datetime_col": "Date", + "groupby_cols": [], + "window_sizes": [ + "1Y" + ], + "lag_periods": [ + "90D", + "180D" + ], + "time_step": "W" +} \ No newline at end of file diff --git a/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Medium-term)_feature_info_20250814_194407.json b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Medium-term)_feature_info_20250814_194407.json new file mode 100644 index 0000000..13026d1 --- /dev/null +++ b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Medium-term)_feature_info_20250814_194407.json @@ -0,0 +1,38 @@ +{ + "feature_names": [ + "Gen_Feat_0_multiply", + "Original_WeekOfYear", + "Original_Month", + "Original_Quarter", + "Original_IsEndOfMonth", + "Original_Feature1", + "Original_Feature2", + "Original_Feature3" + ], + "feature_descriptions": [ + "multiply(Feature3, Feature3)", + "Original: WeekOfYear", + "Original: Month", + "Original: Quarter", + "Original: IsEndOfMonth", + "Original: Feature1", + "Original: Feature2", + "Original: Feature3" + ], + "n_generated_features": 1, + "n_original_features": 7, + "total_features": 8, + "ts_ops_count": 0, + "datetime_col": "Date", + "groupby_cols": [], + "window_sizes": [ + "60D", + "90D", + "180D" + ], + "lag_periods": [ + "30D", + "60D" + ], + "time_step": "W" +} \ No newline at end of file diff --git a/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Mixed)_feature_info_20250814_194411.json b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Mixed)_feature_info_20250814_194411.json new file mode 100644 index 0000000..0c2e739 --- /dev/null +++ b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Mixed)_feature_info_20250814_194411.json @@ -0,0 +1,44 @@ +{ + "feature_names": [ + "Gen_Feat_0_rolling_min", + "Original_WeekOfYear", + "Original_Month", + "Original_Quarter", + "Original_IsEndOfMonth", + "Original_Feature1", + "Original_Feature2", + "Original_Feature3" + ], + "feature_descriptions": [ + "rolling_min(Feature3)", + "Original: WeekOfYear", + "Original: Month", + "Original: Quarter", + "Original: IsEndOfMonth", + "Original: Feature1", + "Original: Feature2", + "Original: Feature3" + ], + "n_generated_features": 1, + "n_original_features": 7, + "total_features": 8, + "ts_ops_count": 1, + "datetime_col": "Date", + "groupby_cols": [], + "window_sizes": [ + "7D", + "14D", + "30D", + "60D", + "90D", + "180D" + ], + "lag_periods": [ + "1D", + "7D", + "14D", + "30D", + "60D" + ], + "time_step": "W" +} \ No newline at end of file diff --git a/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Short-term)_feature_info_20250814_194406.json b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Short-term)_feature_info_20250814_194406.json new file mode 100644 index 0000000..fd37e9b --- /dev/null +++ b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Classification_Time Series (Short-term)_feature_info_20250814_194406.json @@ -0,0 +1,39 @@ +{ + "feature_names": [ + "Gen_Feat_0_rolling_sum", + "Original_WeekOfYear", + "Original_Month", + "Original_Quarter", + "Original_IsEndOfMonth", + "Original_Feature1", + "Original_Feature2", + "Original_Feature3" + ], + "feature_descriptions": [ + "rolling_sum(Feature3)", + "Original: WeekOfYear", + "Original: Month", + "Original: Quarter", + "Original: IsEndOfMonth", + "Original: Feature1", + "Original: Feature2", + "Original: Feature3" + ], + "n_generated_features": 1, + "n_original_features": 7, + "total_features": 8, + "ts_ops_count": 1, + "datetime_col": "Date", + "groupby_cols": [], + "window_sizes": [ + "7D", + "14D", + "30D" + ], + "lag_periods": [ + "1D", + "7D", + "14D" + ], + "time_step": "W" +} \ No newline at end of file diff --git a/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Long-term)_feature_info_20250814_194401.json b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Long-term)_feature_info_20250814_194401.json new file mode 100644 index 0000000..6804050 --- /dev/null +++ b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Long-term)_feature_info_20250814_194401.json @@ -0,0 +1,38 @@ +{ + "feature_names": [ + "Gen_Feat_0_absolute", + "Gen_Feat_1_month_mean_absolute", + "Original_WeekOfYear", + "Original_Month", + "Original_Quarter", + "Original_IsEndOfMonth", + "Original_Feature1", + "Original_Feature2", + "Original_Feature3" + ], + "feature_descriptions": [ + "absolute(Feature3)", + "month_mean -> absolute -> add(Feature3, WeekOfYear)", + "Original: WeekOfYear", + "Original: Month", + "Original: Quarter", + "Original: IsEndOfMonth", + "Original: Feature1", + "Original: Feature2", + "Original: Feature3" + ], + "n_generated_features": 2, + "n_original_features": 7, + "total_features": 9, + "ts_ops_count": 1, + "datetime_col": "Date", + "groupby_cols": [], + "window_sizes": [ + "1Y" + ], + "lag_periods": [ + "90D", + "180D" + ], + "time_step": "W" +} \ No newline at end of file diff --git a/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Medium-term)_feature_info_20250814_194359.json b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Medium-term)_feature_info_20250814_194359.json new file mode 100644 index 0000000..f28eba3 --- /dev/null +++ b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Medium-term)_feature_info_20250814_194359.json @@ -0,0 +1,40 @@ +{ + "feature_names": [ + "Gen_Feat_0_rolling_sum", + "Gen_Feat_1_rolling_max", + "Original_WeekOfYear", + "Original_Month", + "Original_Quarter", + "Original_IsEndOfMonth", + "Original_Feature1", + "Original_Feature2", + "Original_Feature3" + ], + "feature_descriptions": [ + "rolling_sum(Feature3)", + "rolling_max(WeekOfYear)", + "Original: WeekOfYear", + "Original: Month", + "Original: Quarter", + "Original: IsEndOfMonth", + "Original: Feature1", + "Original: Feature2", + "Original: Feature3" + ], + "n_generated_features": 2, + "n_original_features": 7, + "total_features": 9, + "ts_ops_count": 2, + "datetime_col": "Date", + "groupby_cols": [], + "window_sizes": [ + "60D", + "90D", + "180D" + ], + "lag_periods": [ + "30D", + "60D" + ], + "time_step": "W" +} \ No newline at end of file diff --git a/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Mixed)_feature_info_20250814_194404.json b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Mixed)_feature_info_20250814_194404.json new file mode 100644 index 0000000..060b14b --- /dev/null +++ b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Mixed)_feature_info_20250814_194404.json @@ -0,0 +1,44 @@ +{ + "feature_names": [ + "Gen_Feat_0_rolling_mean", + "Original_WeekOfYear", + "Original_Month", + "Original_Quarter", + "Original_IsEndOfMonth", + "Original_Feature1", + "Original_Feature2", + "Original_Feature3" + ], + "feature_descriptions": [ + "rolling_mean(Feature3)", + "Original: WeekOfYear", + "Original: Month", + "Original: Quarter", + "Original: IsEndOfMonth", + "Original: Feature1", + "Original: Feature2", + "Original: Feature3" + ], + "n_generated_features": 1, + "n_original_features": 7, + "total_features": 8, + "ts_ops_count": 1, + "datetime_col": "Date", + "groupby_cols": [], + "window_sizes": [ + "7D", + "14D", + "30D", + "60D", + "90D", + "180D" + ], + "lag_periods": [ + "1D", + "7D", + "14D", + "30D", + "60D" + ], + "time_step": "W" +} \ No newline at end of file diff --git a/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Short-term)_feature_info_20250814_194358.json b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Short-term)_feature_info_20250814_194358.json new file mode 100644 index 0000000..fbc6de7 --- /dev/null +++ b/testing/results/Simple_Weekly_TimeSeries_Simple_Weekly_Regression_Time Series (Short-term)_feature_info_20250814_194358.json @@ -0,0 +1,41 @@ +{ + "feature_names": [ + "Gen_Feat_0_rolling_sum_rolling_max", + "Gen_Feat_1_weekday_mean_weekday_mean", + "Original_WeekOfYear", + "Original_Month", + "Original_Quarter", + "Original_IsEndOfMonth", + "Original_Feature1", + "Original_Feature2", + "Original_Feature3" + ], + "feature_descriptions": [ + "rolling_sum -> rolling_max -> add -> multiply -> seasonal_decompose -> multiply(Feature3, Feature3, Feature3, Feature3)", + "weekday_mean -> weekday_mean -> rolling_std(Feature3)", + "Original: WeekOfYear", + "Original: Month", + "Original: Quarter", + "Original: IsEndOfMonth", + "Original: Feature1", + "Original: Feature2", + "Original: Feature3" + ], + "n_generated_features": 2, + "n_original_features": 7, + "total_features": 9, + "ts_ops_count": 6, + "datetime_col": "Date", + "groupby_cols": [], + "window_sizes": [ + "7D", + "14D", + "30D" + ], + "lag_periods": [ + "1D", + "7D", + "14D" + ], + "time_step": "W" +} \ No newline at end of file diff --git a/testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Long-term)_feature_info_20250814_193920.json b/testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Long-term)_feature_info_20250814_193920.json new file mode 100644 index 0000000..5f9875f --- /dev/null +++ b/testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Long-term)_feature_info_20250814_193920.json @@ -0,0 +1,75 @@ +{ + "feature_names": [ + "Gen_Feat_0_rolling_sum", + "Gen_Feat_1_rolling_sum_trend_feature", + "Gen_Feat_2_add", + "Gen_Feat_3_rolling_sum", + "Gen_Feat_4_add", + "Gen_Feat_5_rolling_std", + "Gen_Feat_6_subtract", + "Gen_Feat_7_subtract", + "Gen_Feat_8_ewm_square", + "Gen_Feat_9_seasonal_decompose", + "Gen_Feat_10_subtract", + "Gen_Feat_11_square", + "Gen_Feat_12_rolling_std_pct_change", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_HL_Pct", + "Original_Volume_MA", + "Original_RSI", + "Original_MACD", + "Original_DayOfWeek", + "Original_Month", + "Original_DaysFromStart" + ], + "feature_descriptions": [ + "rolling_sum(MACD)", + "rolling_sum -> trend_feature(MACD)", + "add(Volatility, Volume)", + "rolling_sum(HL_Pct)", + "add(Open, Volume)", + "rolling_std(Volatility)", + "subtract(HL_Pct, DaysFromStart)", + "subtract(Returns, HL_Pct)", + "ewm -> square -> rolling_std(DayOfWeek)", + "seasonal_decompose(HL_Pct)", + "subtract(Volatility, HL_Pct)", + "square(MACD)", + "rolling_std -> pct_change -> seasonal_decompose(Volume)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: HL_Pct", + "Original: Volume_MA", + "Original: RSI", + "Original: MACD", + "Original: DayOfWeek", + "Original: Month", + "Original: DaysFromStart" + ], + "n_generated_features": 13, + "n_original_features": 13, + "total_features": 26, + "ts_ops_count": 11, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "6M", + "1Y" + ], + "lag_periods": [ + "60D", + "90D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Medium-term)_feature_info_20250814_193914.json b/testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Medium-term)_feature_info_20250814_193914.json new file mode 100644 index 0000000..b768593 --- /dev/null +++ b/testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Medium-term)_feature_info_20250814_193914.json @@ -0,0 +1,76 @@ +{ + "feature_names": [ + "Gen_Feat_0_month_mean_trend_feature", + "Gen_Feat_1_add", + "Gen_Feat_2_trend_feature", + "Gen_Feat_3_rolling_std", + "Gen_Feat_4_month_mean_rolling_median", + "Gen_Feat_5_subtract", + "Gen_Feat_6_rolling_sum", + "Gen_Feat_7_rolling_std", + "Gen_Feat_8_add", + "Gen_Feat_9_rolling_median", + "Gen_Feat_10_rolling_std", + "Gen_Feat_11_rolling_std", + "Gen_Feat_12_trend_feature_rolling_std", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_HL_Pct", + "Original_Volume_MA", + "Original_RSI", + "Original_MACD", + "Original_DayOfWeek", + "Original_Month", + "Original_DaysFromStart" + ], + "feature_descriptions": [ + "month_mean -> trend_feature(Open)", + "add(RSI, Volume_MA)", + "trend_feature(Volume_MA)", + "rolling_std(MACD)", + "month_mean -> rolling_median(Volatility)", + "subtract(DayOfWeek, Volume_MA)", + "rolling_sum(DaysFromStart)", + "rolling_std(DaysFromStart)", + "add(Volume, Low)", + "rolling_median(Open)", + "rolling_std(RSI)", + "rolling_std(Returns)", + "trend_feature -> rolling_std(HL_Pct)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: HL_Pct", + "Original: Volume_MA", + "Original: RSI", + "Original: MACD", + "Original: DayOfWeek", + "Original: Month", + "Original: DaysFromStart" + ], + "n_generated_features": 13, + "n_original_features": 13, + "total_features": 26, + "ts_ops_count": 13, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "30D", + "60D", + "90D" + ], + "lag_periods": [ + "14D", + "30D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Mixed)_feature_info_20250814_193927.json b/testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Mixed)_feature_info_20250814_193927.json new file mode 100644 index 0000000..b6e5de9 --- /dev/null +++ b/testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Mixed)_feature_info_20250814_193927.json @@ -0,0 +1,83 @@ +{ + "feature_names": [ + "Gen_Feat_0_add", + "Gen_Feat_1_seasonal_decompose_rolling_min", + "Gen_Feat_2_add", + "Gen_Feat_3_rolling_sum", + "Gen_Feat_4_rolling_min", + "Gen_Feat_5_subtract_weekday_mean", + "Gen_Feat_6_trend_feature", + "Gen_Feat_7_subtract", + "Gen_Feat_8_rolling_min_rolling_sum", + "Gen_Feat_9_rolling_sum_seasonal_decompose", + "Gen_Feat_10_add", + "Gen_Feat_11_subtract", + "Gen_Feat_12_trend_feature", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_HL_Pct", + "Original_Volume_MA", + "Original_RSI", + "Original_MACD", + "Original_DayOfWeek", + "Original_Month", + "Original_DaysFromStart" + ], + "feature_descriptions": [ + "add(RSI, DaysFromStart)", + "seasonal_decompose -> rolling_min -> add(MACD, DaysFromStart)", + "add(Low, Volume_MA)", + "rolling_sum(HL_Pct)", + "rolling_min(MACD)", + "subtract -> weekday_mean -> rolling_min(HL_Pct, Returns)", + "trend_feature(Volatility)", + "subtract(Volume_MA, MACD)", + "rolling_min -> rolling_sum(Low)", + "rolling_sum -> seasonal_decompose(DaysFromStart)", + "add(RSI, Volatility)", + "subtract(Volatility, DayOfWeek)", + "trend_feature(Volume_MA)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: HL_Pct", + "Original: Volume_MA", + "Original: RSI", + "Original: MACD", + "Original: DayOfWeek", + "Original: Month", + "Original: DaysFromStart" + ], + "n_generated_features": 13, + "n_original_features": 13, + "total_features": 26, + "ts_ops_count": 12, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "3D", + "7D", + "14D", + "21D", + "30D", + "60D", + "90D" + ], + "lag_periods": [ + "1D", + "3D", + "7D", + "14D", + "30D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Short-term)_feature_info_20250814_193909.json b/testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Short-term)_feature_info_20250814_193909.json new file mode 100644 index 0000000..a5d608c --- /dev/null +++ b/testing/results/Stock_Market_Daily_Stock_Direction_Prediction_Time Series (Short-term)_feature_info_20250814_193909.json @@ -0,0 +1,72 @@ +{ + "feature_names": [ + "Gen_Feat_0_multiply_trend_feature", + "Gen_Feat_1_weekday_mean_month_mean", + "Gen_Feat_2_subtract", + "Gen_Feat_3_ewm_rolling_sum", + "Gen_Feat_4_month_mean_rolling_mean", + "Gen_Feat_5_seasonal_decompose", + "Gen_Feat_6_absolute", + "Gen_Feat_7_add", + "Gen_Feat_8_absolute", + "Gen_Feat_9_ewm_square", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_HL_Pct", + "Original_Volume_MA", + "Original_RSI", + "Original_MACD", + "Original_DayOfWeek", + "Original_Month", + "Original_DaysFromStart" + ], + "feature_descriptions": [ + "multiply -> trend_feature(HL_Pct, Volatility)", + "weekday_mean -> month_mean -> multiply -> rolling_min(Volatility, DaysFromStart)", + "subtract(RSI, MACD)", + "ewm -> rolling_sum(DaysFromStart)", + "month_mean -> rolling_mean(RSI)", + "seasonal_decompose(Low)", + "absolute(HL_Pct)", + "add(RSI, HL_Pct)", + "absolute(Returns)", + "ewm -> square -> rolling_std(MACD)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: HL_Pct", + "Original: Volume_MA", + "Original: RSI", + "Original: MACD", + "Original: DayOfWeek", + "Original: Month", + "Original: DaysFromStart" + ], + "n_generated_features": 10, + "n_original_features": 13, + "total_features": 23, + "ts_ops_count": 11, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "3D", + "7D", + "14D", + "21D" + ], + "lag_periods": [ + "1D", + "3D", + "7D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Long-term)_feature_info_20250814_193958.json b/testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Long-term)_feature_info_20250814_193958.json new file mode 100644 index 0000000..ead6d2e --- /dev/null +++ b/testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Long-term)_feature_info_20250814_193958.json @@ -0,0 +1,75 @@ +{ + "feature_names": [ + "Gen_Feat_0_subtract", + "Gen_Feat_1_rolling_std_seasonal_decompose", + "Gen_Feat_2_rolling_sum", + "Gen_Feat_3_rolling_sum_trend_feature", + "Gen_Feat_4_month_mean", + "Gen_Feat_5_multiply_trend_feature", + "Gen_Feat_6_absolute_seasonal_decompose", + "Gen_Feat_7_seasonal_decompose", + "Gen_Feat_8_multiply", + "Gen_Feat_9_multiply_month_mean", + "Gen_Feat_10_subtract", + "Gen_Feat_11_trend_feature_diff_feature", + "Gen_Feat_12_multiply_seasonal_decompose", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_HL_Pct", + "Original_Volume_MA", + "Original_RSI", + "Original_MACD", + "Original_DayOfWeek", + "Original_Month", + "Original_DaysFromStart" + ], + "feature_descriptions": [ + "subtract(Returns, HL_Pct)", + "rolling_std -> seasonal_decompose(Volatility)", + "rolling_sum(RSI)", + "rolling_sum -> trend_feature -> diff_feature -> rolling_sum -> multiply(DaysFromStart, RSI)", + "month_mean(RSI)", + "multiply -> trend_feature(Volume, DaysFromStart)", + "absolute -> seasonal_decompose -> rolling_median(Volatility)", + "seasonal_decompose(Returns)", + "multiply(Low, Open)", + "multiply -> month_mean -> multiply -> trend_feature(Volatility, RSI, Low)", + "subtract(MACD, Volume_MA)", + "trend_feature -> diff_feature -> seasonal_decompose(RSI)", + "multiply -> seasonal_decompose(HL_Pct, DaysFromStart)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: HL_Pct", + "Original: Volume_MA", + "Original: RSI", + "Original: MACD", + "Original: DayOfWeek", + "Original: Month", + "Original: DaysFromStart" + ], + "n_generated_features": 13, + "n_original_features": 13, + "total_features": 26, + "ts_ops_count": 18, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "6M", + "1Y" + ], + "lag_periods": [ + "60D", + "90D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Medium-term)_feature_info_20250814_193948.json b/testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Medium-term)_feature_info_20250814_193948.json new file mode 100644 index 0000000..37363b7 --- /dev/null +++ b/testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Medium-term)_feature_info_20250814_193948.json @@ -0,0 +1,76 @@ +{ + "feature_names": [ + "Gen_Feat_0_absolute", + "Gen_Feat_1_rolling_std_ewm", + "Gen_Feat_2_add", + "Gen_Feat_3_subtract", + "Gen_Feat_4_ewm_rolling_sum", + "Gen_Feat_5_rolling_mean", + "Gen_Feat_6_add", + "Gen_Feat_7_add_rolling_std", + "Gen_Feat_8_trend_feature", + "Gen_Feat_9_add", + "Gen_Feat_10_add", + "Gen_Feat_11_ewm_rolling_mean", + "Gen_Feat_12_seasonal_decompose", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_HL_Pct", + "Original_Volume_MA", + "Original_RSI", + "Original_MACD", + "Original_DayOfWeek", + "Original_Month", + "Original_DaysFromStart" + ], + "feature_descriptions": [ + "absolute(Volatility)", + "rolling_std -> ewm -> add(Volume_MA, Volume_MA)", + "add(Open, DaysFromStart)", + "subtract(Returns, Low)", + "ewm -> rolling_sum -> rolling_std(Returns)", + "rolling_mean(MACD)", + "add(Returns, DaysFromStart)", + "add -> rolling_std -> rolling_std(Volume_MA, Open)", + "trend_feature(Returns)", + "add(Returns, Returns)", + "add(Returns, Volume)", + "ewm -> rolling_mean -> absolute(Month)", + "seasonal_decompose(RSI)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: HL_Pct", + "Original: Volume_MA", + "Original: RSI", + "Original: MACD", + "Original: DayOfWeek", + "Original: Month", + "Original: DaysFromStart" + ], + "n_generated_features": 13, + "n_original_features": 13, + "total_features": 26, + "ts_ops_count": 12, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "30D", + "60D", + "90D" + ], + "lag_periods": [ + "14D", + "30D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Mixed)_feature_info_20250814_194008.json b/testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Mixed)_feature_info_20250814_194008.json new file mode 100644 index 0000000..9f40bb7 --- /dev/null +++ b/testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Mixed)_feature_info_20250814_194008.json @@ -0,0 +1,81 @@ +{ + "feature_names": [ + "Gen_Feat_0_month_mean_rolling_mean", + "Gen_Feat_1_rolling_median", + "Gen_Feat_2_add", + "Gen_Feat_3_rolling_median_rolling_mean", + "Gen_Feat_4_momentum_weekday_mean", + "Gen_Feat_5_absolute_absolute", + "Gen_Feat_6_rolling_mean_seasonal_decompose", + "Gen_Feat_7_subtract", + "Gen_Feat_8_rolling_sum", + "Gen_Feat_9_absolute_rolling_min", + "Gen_Feat_10_rolling_median", + "Gen_Feat_11_rolling_median", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_HL_Pct", + "Original_Volume_MA", + "Original_RSI", + "Original_MACD", + "Original_DayOfWeek", + "Original_Month", + "Original_DaysFromStart" + ], + "feature_descriptions": [ + "month_mean -> rolling_mean(Volume_MA)", + "rolling_median(Returns)", + "add(Month, Volume_MA)", + "rolling_median -> rolling_mean -> subtract(Returns, RSI)", + "momentum -> weekday_mean(Returns)", + "absolute -> absolute(High)", + "rolling_mean -> seasonal_decompose(MACD)", + "subtract(RSI, HL_Pct)", + "rolling_sum(MACD)", + "absolute -> rolling_min(Returns)", + "rolling_median(Volatility)", + "rolling_median(HL_Pct)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: HL_Pct", + "Original: Volume_MA", + "Original: RSI", + "Original: MACD", + "Original: DayOfWeek", + "Original: Month", + "Original: DaysFromStart" + ], + "n_generated_features": 12, + "n_original_features": 13, + "total_features": 25, + "ts_ops_count": 13, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "3D", + "7D", + "14D", + "21D", + "30D", + "60D", + "90D" + ], + "lag_periods": [ + "1D", + "3D", + "7D", + "14D", + "30D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Short-term)_feature_info_20250814_193939.json b/testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Short-term)_feature_info_20250814_193939.json new file mode 100644 index 0000000..77e8ffe --- /dev/null +++ b/testing/results/Stock_Market_Daily_Stock_Return_Prediction_Time Series (Short-term)_feature_info_20250814_193939.json @@ -0,0 +1,78 @@ +{ + "feature_names": [ + "Gen_Feat_0_rolling_sum", + "Gen_Feat_1_subtract", + "Gen_Feat_2_multiply_trend_feature", + "Gen_Feat_3_multiply", + "Gen_Feat_4_rolling_min", + "Gen_Feat_5_add", + "Gen_Feat_6_absolute", + "Gen_Feat_7_add", + "Gen_Feat_8_absolute_seasonal_decompose", + "Gen_Feat_9_seasonal_decompose", + "Gen_Feat_10_subtract", + "Gen_Feat_11_subtract", + "Gen_Feat_12_rolling_min", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_Volatility", + "Original_HL_Pct", + "Original_Volume_MA", + "Original_RSI", + "Original_MACD", + "Original_DayOfWeek", + "Original_Month", + "Original_DaysFromStart" + ], + "feature_descriptions": [ + "rolling_sum(Returns)", + "subtract(Month, Volume_MA)", + "multiply -> trend_feature(HL_Pct, Volatility)", + "multiply(MACD, MACD)", + "rolling_min(Returns)", + "add(RSI, HL_Pct)", + "absolute(Returns)", + "add(Returns, DaysFromStart)", + "absolute -> seasonal_decompose(Open)", + "seasonal_decompose(HL_Pct)", + "subtract(Low, Returns)", + "subtract(Volume, Volatility)", + "rolling_min(RSI)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: Volatility", + "Original: HL_Pct", + "Original: Volume_MA", + "Original: RSI", + "Original: MACD", + "Original: DayOfWeek", + "Original: Month", + "Original: DaysFromStart" + ], + "n_generated_features": 13, + "n_original_features": 13, + "total_features": 26, + "ts_ops_count": 6, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "3D", + "7D", + "14D", + "21D" + ], + "lag_periods": [ + "1D", + "3D", + "7D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Long-term)_feature_info_20250814_194021.json b/testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Long-term)_feature_info_20250814_194021.json new file mode 100644 index 0000000..22e608b --- /dev/null +++ b/testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Long-term)_feature_info_20250814_194021.json @@ -0,0 +1,69 @@ +{ + "feature_names": [ + "Gen_Feat_0_square_square", + "Gen_Feat_1_rolling_sum_absolute", + "Gen_Feat_2_square", + "Gen_Feat_3_rolling_sum_rolling_mean", + "Gen_Feat_4_trend_feature", + "Gen_Feat_5_rolling_sum_square", + "Gen_Feat_6_add", + "Gen_Feat_7_rolling_max_rolling_mean", + "Gen_Feat_8_subtract_square", + "Gen_Feat_9_subtract", + "Gen_Feat_10_rolling_std", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_HL_Pct", + "Original_Volume_MA", + "Original_RSI", + "Original_MACD", + "Original_DayOfWeek", + "Original_Month", + "Original_DaysFromStart" + ], + "feature_descriptions": [ + "square -> square(Open)", + "rolling_sum -> absolute(DaysFromStart)", + "square(DaysFromStart)", + "rolling_sum -> rolling_mean(RSI)", + "trend_feature(Month)", + "rolling_sum -> square -> subtract(MACD, MACD)", + "add(Volume_MA, DaysFromStart)", + "rolling_max -> rolling_mean -> seasonal_decompose(Volume_MA)", + "subtract -> square(High, MACD)", + "subtract(DaysFromStart, Month)", + "rolling_std(Month)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: HL_Pct", + "Original: Volume_MA", + "Original: RSI", + "Original: MACD", + "Original: DayOfWeek", + "Original: Month", + "Original: DaysFromStart" + ], + "n_generated_features": 11, + "n_original_features": 12, + "total_features": 23, + "ts_ops_count": 9, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "6M", + "1Y" + ], + "lag_periods": [ + "60D", + "90D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Medium-term)_feature_info_20250814_194017.json b/testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Medium-term)_feature_info_20250814_194017.json new file mode 100644 index 0000000..30a2e2e --- /dev/null +++ b/testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Medium-term)_feature_info_20250814_194017.json @@ -0,0 +1,60 @@ +{ + "feature_names": [ + "Gen_Feat_0_rolling_mean", + "Gen_Feat_1_add_absolute", + "Gen_Feat_2_add", + "Gen_Feat_3_multiply", + "Gen_Feat_4_absolute", + "Gen_Feat_5_rolling_median_rolling_mean", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_HL_Pct", + "Original_Volume_MA", + "Original_RSI", + "Original_MACD", + "Original_DayOfWeek", + "Original_Month", + "Original_DaysFromStart" + ], + "feature_descriptions": [ + "rolling_mean(Open)", + "add -> absolute(MACD, MACD)", + "add(Returns, Volume_MA)", + "multiply(High, Volume_MA)", + "absolute(DaysFromStart)", + "rolling_median -> rolling_mean(Month)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: HL_Pct", + "Original: Volume_MA", + "Original: RSI", + "Original: MACD", + "Original: DayOfWeek", + "Original: Month", + "Original: DaysFromStart" + ], + "n_generated_features": 6, + "n_original_features": 12, + "total_features": 18, + "ts_ops_count": 3, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "30D", + "60D", + "90D" + ], + "lag_periods": [ + "14D", + "30D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Mixed)_feature_info_20250814_194026.json b/testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Mixed)_feature_info_20250814_194026.json new file mode 100644 index 0000000..352981f --- /dev/null +++ b/testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Mixed)_feature_info_20250814_194026.json @@ -0,0 +1,69 @@ +{ + "feature_names": [ + "Gen_Feat_0_multiply_square", + "Gen_Feat_1_absolute", + "Gen_Feat_2_add", + "Gen_Feat_3_subtract_seasonal_decompose", + "Gen_Feat_4_diff_feature_rolling_mean", + "Gen_Feat_5_rolling_max", + "Gen_Feat_6_absolute", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_HL_Pct", + "Original_Volume_MA", + "Original_RSI", + "Original_MACD", + "Original_DayOfWeek", + "Original_Month", + "Original_DaysFromStart" + ], + "feature_descriptions": [ + "multiply -> square(High, High)", + "absolute(MACD)", + "add(Volume_MA, Volume_MA)", + "subtract -> seasonal_decompose -> subtract -> absolute(Volume_MA, Returns, High)", + "diff_feature -> rolling_mean -> subtract(MACD, MACD)", + "rolling_max(DaysFromStart)", + "absolute(DaysFromStart)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: HL_Pct", + "Original: Volume_MA", + "Original: RSI", + "Original: MACD", + "Original: DayOfWeek", + "Original: Month", + "Original: DaysFromStart" + ], + "n_generated_features": 7, + "n_original_features": 12, + "total_features": 19, + "ts_ops_count": 4, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "3D", + "7D", + "14D", + "21D", + "30D", + "60D", + "90D" + ], + "lag_periods": [ + "1D", + "3D", + "7D", + "14D", + "30D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Short-term)_feature_info_20250814_194013.json b/testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Short-term)_feature_info_20250814_194013.json new file mode 100644 index 0000000..29a6e52 --- /dev/null +++ b/testing/results/Stock_Market_Daily_Stock_Volatility_Prediction_Time Series (Short-term)_feature_info_20250814_194013.json @@ -0,0 +1,62 @@ +{ + "feature_names": [ + "Gen_Feat_0_subtract", + "Gen_Feat_1_seasonal_decompose", + "Gen_Feat_2_multiply", + "Gen_Feat_3_rolling_median_rolling_median", + "Gen_Feat_4_absolute", + "Gen_Feat_5_multiply", + "Original_Open", + "Original_High", + "Original_Low", + "Original_Volume", + "Original_Returns", + "Original_HL_Pct", + "Original_Volume_MA", + "Original_RSI", + "Original_MACD", + "Original_DayOfWeek", + "Original_Month", + "Original_DaysFromStart" + ], + "feature_descriptions": [ + "subtract(HL_Pct, DaysFromStart)", + "seasonal_decompose(Open)", + "multiply(DaysFromStart, HL_Pct)", + "rolling_median -> rolling_median -> multiply(DaysFromStart, High)", + "absolute(Volume_MA)", + "multiply(DaysFromStart, Volume_MA)", + "Original: Open", + "Original: High", + "Original: Low", + "Original: Volume", + "Original: Returns", + "Original: HL_Pct", + "Original: Volume_MA", + "Original: RSI", + "Original: MACD", + "Original: DayOfWeek", + "Original: Month", + "Original: DaysFromStart" + ], + "n_generated_features": 6, + "n_original_features": 12, + "total_features": 18, + "ts_ops_count": 3, + "datetime_col": "Date", + "groupby_cols": [ + "Symbol" + ], + "window_sizes": [ + "3D", + "7D", + "14D", + "21D" + ], + "lag_periods": [ + "1D", + "3D", + "7D" + ], + "time_step": "D" +} \ No newline at end of file diff --git a/testing/results/time_based_analysis.png b/testing/results/time_based_analysis.png new file mode 100644 index 0000000000000000000000000000000000000000..59c28b2a1e20b3b945064c03374fb1b051a15fbb GIT binary patch literal 620058 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

FDol62lO2r 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

}_$SfJ<%Z#Ce< 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 z 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 N@)Hs-GvTdX)AJsX9?o5f|ge4Ln9A7}T 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

WGvB^r=uPlg?FUzyr7871tEjB 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 literal 0 HcmV?d00001 diff --git a/testing/results/time_based_test_results_20250814_194412.json b/testing/results/time_based_test_results_20250814_194412.json new file mode 100644 index 0000000..36cf968 --- /dev/null +++ b/testing/results/time_based_test_results_20250814_194412.json @@ -0,0 +1,414 @@ +{ + "Stock_Market_Daily": { + "Stock_Direction_Prediction": { + "Baseline (No Time Series)": { + "score": 0.4666666666666667, + "n_features": 24, + "ts_ops_count": 0, + "model": "DecisionTreeClassifier" + }, + "Time Series (Short-term)": { + "score": 0.49333333333333335, + "n_features": 23, + "ts_ops_count": 11, + "model": "DecisionTreeClassifier" + }, + "Time Series (Medium-term)": { + "score": 0.47333333333333333, + "n_features": 26, + "ts_ops_count": 13, + "model": "RandomForestClassifier" + }, + "Time Series (Long-term)": { + "score": 0.45666666666666667, + "n_features": 26, + "ts_ops_count": 11, + "model": "RandomForestClassifier" + }, + "Time Series (Mixed)": { + "score": 0.46, + "n_features": 26, + "ts_ops_count": 12, + "model": "DecisionTreeClassifier" + } + }, + "Stock_Return_Prediction": { + "Baseline (No Time Series)": { + "score": -0.46450851460084563, + "n_features": 26, + "ts_ops_count": 0, + "model": "RandomForestRegressor", + "mae": 0.020819449769296238, + "rmse": 0.026888213077421914 + }, + "Time Series (Short-term)": { + "score": -0.2957381232636589, + "n_features": 26, + "ts_ops_count": 6, + "model": "RandomForestRegressor", + "mae": 0.018423245051379485, + "rmse": 0.025291501253123832 + }, + "Time Series (Medium-term)": { + "score": -0.7600112736054077, + "n_features": 26, + "ts_ops_count": 12, + "model": "RandomForestRegressor", + "mae": 0.023216993383225068, + "rmse": 0.029476350728919336 + }, + "Time Series (Long-term)": { + "score": -0.3176150463991101, + "n_features": 26, + "ts_ops_count": 18, + "model": "RandomForestRegressor", + "mae": 0.018799306511167135, + "rmse": 0.0255041153156255 + }, + "Time Series (Mixed)": { + "score": -0.43240393065821525, + "n_features": 25, + "ts_ops_count": 13, + "model": "RandomForestRegressor", + "mae": 0.020224814380963303, + "rmse": 0.026591861651121197 + } + }, + "Stock_Volatility_Prediction": { + "Baseline (No Time Series)": { + "score": 0.5266666666666666, + "n_features": 17, + "ts_ops_count": 0, + "model": "DecisionTreeClassifier" + }, + "Time Series (Short-term)": { + "score": 0.47, + "n_features": 18, + "ts_ops_count": 3, + "model": "DecisionTreeClassifier" + }, + "Time Series (Medium-term)": { + "score": 0.6, + "n_features": 18, + "ts_ops_count": 3, + "model": "DecisionTreeClassifier" + }, + "Time Series (Long-term)": { + "score": 0.53, + "n_features": 23, + "ts_ops_count": 9, + "model": "DecisionTreeClassifier" + }, + "Time Series (Mixed)": { + "score": 0.5366666666666666, + "n_features": 19, + "ts_ops_count": 4, + "model": "DecisionTreeClassifier" + } + } + }, + "Cryptocurrency_Daily": { + "Crypto_Direction_Prediction": { + "Baseline (No Time Series)": { + "score": 0.4444444444444444, + "n_features": 23, + "ts_ops_count": 0, + "model": "RandomForestClassifier" + }, + "Time Series (Short-term)": { + "score": 0.4305555555555556, + "n_features": 22, + "ts_ops_count": 14, + "model": "RandomForestClassifier" + }, + "Time Series (Medium-term)": { + "score": 0.4583333333333333, + "n_features": 22, + "ts_ops_count": 6, + "model": "RandomForestClassifier" + }, + "Time Series (Long-term)": { + "score": 0.4722222222222222, + "n_features": 20, + "ts_ops_count": 6, + "model": "RandomForestClassifier" + }, + "Time Series (Mixed)": { + "score": 0.5069444444444444, + "n_features": 24, + "ts_ops_count": 12, + "model": "DecisionTreeClassifier" + } + }, + "Crypto_Return_Prediction": { + "Baseline (No Time Series)": { + "score": -0.31797776447698345, + "n_features": 21, + "ts_ops_count": 0, + "model": "RandomForestRegressor", + "mae": 0.022249075005613274, + "rmse": 0.03125818942109764 + }, + "Time Series (Short-term)": { + "score": -0.38854995471222264, + "n_features": 22, + "ts_ops_count": 10, + "model": "RandomForestRegressor", + "mae": 0.024098017530977463, + "rmse": 0.03208414949482091 + }, + "Time Series (Medium-term)": { + "score": -0.4260474258202851, + "n_features": 24, + "ts_ops_count": 12, + "model": "RandomForestRegressor", + "mae": 0.023370261508264965, + "rmse": 0.03251447615672881 + }, + "Time Series (Long-term)": { + "score": -0.54225632044469, + "n_features": 20, + "ts_ops_count": 8, + "model": "RandomForestRegressor", + "mae": 0.025501434329618346, + "rmse": 0.033813338821617786 + }, + "Time Series (Mixed)": { + "score": -0.2829747306522665, + "n_features": 23, + "ts_ops_count": 12, + "model": "RandomForestRegressor", + "mae": 0.02303889855960203, + "rmse": 0.030840316634369144 + } + } + }, + "Retail_Sales_Daily": { + "Sales_High_Performance": { + "Baseline (No Time Series)": { + "score": 0.9888888888888889, + "n_features": 13, + "ts_ops_count": 0, + "model": "RandomForestClassifier" + }, + "Time Series (Short-term)": { + "score": 0.9888888888888889, + "n_features": 12, + "ts_ops_count": 0, + "model": "DecisionTreeClassifier" + }, + "Time Series (Medium-term)": { + "score": 0.9958333333333333, + "n_features": 13, + "ts_ops_count": 0, + "model": "RandomForestClassifier" + }, + "Time Series (Long-term)": { + "score": 0.9944444444444445, + "n_features": 13, + "ts_ops_count": 1, + "model": "RandomForestClassifier" + }, + "Time Series (Mixed)": { + "score": 0.9972222222222222, + "n_features": 13, + "ts_ops_count": 1, + "model": "RandomForestClassifier" + } + }, + "Sales_Next_Day_Prediction": { + "Baseline (No Time Series)": { + "score": 0.6400815732923095, + "n_features": 19, + "ts_ops_count": 0, + "model": "RandomForestRegressor", + "mae": 1257.8882766173344, + "rmse": 1950.9111145489458 + }, + "Time Series (Short-term)": { + "score": 0.5980613099112891, + "n_features": 19, + "ts_ops_count": 4, + "model": "RandomForestRegressor", + "mae": 1474.2993906861955, + "rmse": 2061.6519469249915 + }, + "Time Series (Medium-term)": { + "score": 0.5953176280852879, + "n_features": 18, + "ts_ops_count": 1, + "model": "RandomForestRegressor", + "mae": 1453.0031489540327, + "rmse": 2068.676521701872 + }, + "Time Series (Long-term)": { + "score": 0.6382639630768223, + "n_features": 18, + "ts_ops_count": 2, + "model": "RandomForestRegressor", + "mae": 1366.000391146928, + "rmse": 1955.8310215371805 + }, + "Time Series (Mixed)": { + "score": 0.6220047815463968, + "n_features": 16, + "ts_ops_count": 1, + "model": "RandomForestRegressor", + "mae": 1364.7739491664115, + "rmse": 1999.302896415256 + } + } + }, + "Energy_Consumption_Hourly": { + "Energy_High_Consumption": { + "Baseline (No Time Series)": { + "score": 0.8506944444444444, + "n_features": 15, + "ts_ops_count": 0, + "model": "RandomForestClassifier" + }, + "Time Series (Short-term)": { + "score": 0.8425925925925926, + "n_features": 14, + "ts_ops_count": 5, + "model": "RandomForestClassifier" + }, + "Time Series (Medium-term)": { + "score": 0.8587962962962963, + "n_features": 14, + "ts_ops_count": 2, + "model": "RandomForestClassifier" + }, + "Time Series (Long-term)": { + "score": 0.8391203703703703, + "n_features": 16, + "ts_ops_count": 3, + "model": "RandomForestClassifier" + }, + "Time Series (Mixed)": { + "score": 0.8333333333333334, + "n_features": 15, + "ts_ops_count": 2, + "model": "RandomForestClassifier" + } + }, + "Energy_Next_Hour_Prediction": { + "Baseline (No Time Series)": { + "score": 0.3636889429241642, + "n_features": 17, + "ts_ops_count": 0, + "model": "RandomForestRegressor", + "mae": 192.58100982072682, + "rmse": 238.32809313758295 + }, + "Time Series (Short-term)": { + "score": 0.3549602510558745, + "n_features": 15, + "ts_ops_count": 3, + "model": "RandomForestRegressor", + "mae": 194.31943544789735, + "rmse": 239.9571759591126 + }, + "Time Series (Medium-term)": { + "score": 0.4875137979872106, + "n_features": 17, + "ts_ops_count": 7, + "model": "RandomForestRegressor", + "mae": 171.0145802078457, + "rmse": 213.88562236468127 + }, + "Time Series (Long-term)": { + "score": -4.085457147835233, + "n_features": 16, + "ts_ops_count": 2, + "model": "RandomForestRegressor", + "mae": 648.0496687030648, + "rmse": 673.7604323949798 + }, + "Time Series (Mixed)": { + "score": 0.25071410766448965, + "n_features": 15, + "ts_ops_count": 3, + "model": "RandomForestRegressor", + "mae": 210.54062906362654, + "rmse": 258.62129443940665 + } + } + }, + "Simple_Weekly_TimeSeries": { + "Simple_Weekly_Regression": { + "Baseline (No Time Series)": { + "score": -0.6837715634828103, + "n_features": 8, + "ts_ops_count": 0, + "model": "RandomForestRegressor", + "mae": 17.080125991653755, + "rmse": 18.882743951195256 + }, + "Time Series (Short-term)": { + "score": -3.028543069939156, + "n_features": 9, + "ts_ops_count": 6, + "model": "RandomForestRegressor", + "mae": 27.750998933757902, + "rmse": 29.20771111109536 + }, + "Time Series (Medium-term)": { + "score": -1.4327541755459916, + "n_features": 9, + "ts_ops_count": 2, + "model": "RandomForestRegressor", + "mae": 16.13658016817415, + "rmse": 22.697218169277598 + }, + "Time Series (Long-term)": { + "score": -0.15772261742583393, + "n_features": 9, + "ts_ops_count": 1, + "model": "RandomForestRegressor", + "mae": 13.308926461300473, + "rmse": 15.657621043518882 + }, + "Time Series (Mixed)": { + "score": 0.1716251639066324, + "n_features": 8, + "ts_ops_count": 1, + "model": "RandomForestRegressor", + "mae": 11.398739929717474, + "rmse": 13.244542696077046 + } + }, + "Simple_Weekly_Classification": { + "Baseline (No Time Series)": { + "score": 0.7307692307692307, + "n_features": 8, + "ts_ops_count": 0, + "model": "RandomForestClassifier" + }, + "Time Series (Short-term)": { + "score": 0.7115384615384616, + "n_features": 8, + "ts_ops_count": 1, + "model": "DecisionTreeClassifier" + }, + "Time Series (Medium-term)": { + "score": 0.7019230769230769, + "n_features": 8, + "ts_ops_count": 0, + "model": "RandomForestClassifier" + }, + "Time Series (Long-term)": { + "score": 0.7307692307692307, + "n_features": 8, + "ts_ops_count": 0, + "model": "RandomForestClassifier" + }, + "Time Series (Mixed)": { + "score": 0.625, + "n_features": 8, + "ts_ops_count": 1, + "model": "RandomForestClassifier" + } + } + } +} \ No newline at end of file diff --git a/testing/time_series_testing.py b/testing/time_series_testing.py new file mode 100644 index 0000000..3edf616 --- /dev/null +++ b/testing/time_series_testing.py @@ -0,0 +1,1281 @@ +import pandas as pd +import numpy as np +import warnings +from datetime import datetime, timedelta +import matplotlib.pyplot as plt +import seaborn as sns +from sklearn.model_selection import train_test_split +from sklearn.metrics import accuracy_score, r2_score, mean_absolute_error, mean_squared_error +from sklearn.preprocessing import StandardScaler, LabelEncoder +import os +import sys +import json + +# Suppress warnings for cleaner output +warnings.filterwarnings('ignore') + +# Try to import required libraries +try: + import yfinance as yf + + print("✓ yfinance imported successfully") +except ImportError: + print("⚠ yfinance not found. Install with: pip install yfinance") + print("Continuing with alternative data sources...") + +# Import your BigFeat implementation +try: + from bigfeat.bigfeat_base import BigFeat # Updated import to match your file + + print("✓ BigFeat imported successfully") +except ImportError: + print("✗ BigFeat not found. Please ensure bigfeat_base.py is in the same directory.") + sys.exit(1) + + +class ComprehensiveTimeSeriesTester: + """ + Comprehensive testing suite for BigFeat time-based series capabilities + Uses multiple real-world datasets with temporal components and time-based windows + """ + + def __init__(self, verbose=True, save_results=True): + self.verbose = verbose + self.save_results = save_results + self.results = {} + + if self.save_results: + os.makedirs('results', exist_ok=True) + + def print_section(self, title): + """Print formatted section header""" + if self.verbose: + print(f"\n{'=' * 80}") + print(f"{title}") + print(f"{'=' * 80}") + + def load_stock_data(self, symbols=['AAPL', 'GOOGL', 'MSFT'], period='2y'): + """ + Load stock data from Yahoo Finance with higher frequency for time-based analysis + """ + try: + self.print_section("LOADING FINANCIAL DATA FROM YAHOO FINANCE") + + stock_data = [] + + for symbol in symbols: + if self.verbose: + print(f"Downloading {symbol} data...") + + ticker = yf.Ticker(symbol) + # Get daily data for better time-based analysis + hist = ticker.history(period=period, interval='1d') + + if len(hist) == 0: + print(f"⚠ No data found for {symbol}") + continue + + hist = hist.reset_index() + hist['Symbol'] = symbol + + # Calculate additional features + hist['Returns'] = hist['Close'].pct_change() + hist['LogReturns'] = np.log1p(hist['Close'].pct_change()) + hist['Volatility'] = hist['Returns'].rolling(20, min_periods=1).std() + hist['HL_Pct'] = (hist['High'] - hist['Low']) / hist['Close'] + hist['Price_Change'] = hist['Close'] - hist['Open'] + hist['Volume_MA'] = hist['Volume'].rolling(20, min_periods=1).mean() + hist['RSI'] = self.calculate_rsi(hist['Close']) + hist['MACD'] = self.calculate_macd(hist['Close']) + hist['BB_Upper'], hist['BB_Lower'] = self.calculate_bollinger_bands(hist['Close']) + + # Create target variables + hist['Next_Return'] = hist['Returns'].shift(-1) + hist['Price_Up'] = (hist['Next_Return'] > 0).astype(int) + hist['High_Vol'] = (hist['Volume'] > hist['Volume'].quantile(0.75)).astype(int) + hist['Volatility_High'] = (hist['Volatility'] > hist['Volatility'].quantile(0.75)).astype(int) + + # Add time-based features for better time-series analysis + hist['DayOfWeek'] = hist['Date'].dt.dayofweek + hist['Month'] = hist['Date'].dt.month + hist['Quarter'] = hist['Date'].dt.quarter + hist['DaysFromStart'] = (hist['Date'] - hist['Date'].min()).dt.days + hist['IsMonthEnd'] = hist['Date'].dt.is_month_end.astype(int) + hist['IsQuarterEnd'] = hist['Date'].dt.is_quarter_end.astype(int) + + stock_data.append(hist) + + df = pd.concat(stock_data, ignore_index=True) + df = df.dropna() + + # Clean data to prevent infinity or large values + df = df.replace([np.inf, -np.inf], np.nan).fillna(0) + for col in df.select_dtypes(include=[np.number]).columns: + df[col] = np.clip(df[col], -1e8, 1e8) + + if self.verbose: + print(f"Stock data loaded: {len(df)} rows, {df['Symbol'].nunique()} symbols") + print(f"Date range: {df['Date'].min()} to {df['Date'].max()}") + print(f"Features: {df.select_dtypes(include=[np.number]).columns.tolist()}") + + return df + + except Exception as e: + print(f"Error loading stock data: {e}") + return None + + def load_crypto_data(self, symbols=['BTC-USD', 'ETH-USD'], period='1y'): + """ + Load cryptocurrency data from Yahoo Finance with daily frequency + """ + try: + self.print_section("LOADING CRYPTOCURRENCY DATA") + + crypto_data = [] + + for symbol in symbols: + if self.verbose: + print(f"Downloading {symbol} data...") + + ticker = yf.Ticker(symbol) + hist = ticker.history(period=period, interval='1d') + + if len(hist) == 0: + continue + + hist = hist.reset_index() + hist['Symbol'] = symbol + + # Crypto-specific features + hist['Returns'] = hist['Close'].pct_change() + hist['LogReturns'] = np.log1p(hist['Close'].pct_change()) + hist['Volatility'] = hist['Returns'].rolling(10, min_periods=1).std() + hist['Price_Range'] = hist['High'] - hist['Low'] + hist['Volume_USD'] = hist['Volume'] * hist['Close'] + + # Technical indicators adapted for crypto + hist['SMA_7'] = hist['Close'].rolling(7, min_periods=1).mean() + hist['SMA_30'] = hist['Close'].rolling(30, min_periods=1).mean() + hist['Price_Position'] = (hist['Close'] - hist['Low'].rolling(20, min_periods=1).min()) / ( + hist['High'].rolling(20, min_periods=1).max() - hist['Low'].rolling(20, + min_periods=1).min()) + + # Targets + hist['Next_Return'] = hist['Returns'].shift(-1) + hist['Price_Up'] = (hist['Next_Return'] > 0).astype(int) + hist['High_Volatility'] = (hist['Volatility'] > hist['Volatility'].quantile(0.8)).astype(int) + + # Time features + hist['DayOfWeek'] = hist['Date'].dt.dayofweek + hist['Month'] = hist['Date'].dt.month + hist['IsWeekend'] = (hist['Date'].dt.dayofweek >= 5).astype(int) + + crypto_data.append(hist) + + if crypto_data: + df = pd.concat(crypto_data, ignore_index=True) + df = df.dropna() + + # Clean data to prevent infinity or large values + df = df.replace([np.inf, -np.inf], np.nan).fillna(0) + for col in df.select_dtypes(include=[np.number]).columns: + df[col] = np.clip(df[col], -1e8, 1e8) + + if self.verbose: + print(f"Crypto data loaded: {len(df)} rows, {df['Symbol'].nunique()} symbols") + print(f"Date range: {df['Date'].min()} to {df['Date'].max()}") + print(f"Features: {df.select_dtypes(include=[np.number]).columns.tolist()}") + + return df + else: + return None + + except Exception as e: + print(f"Error loading crypto data: {e}") + return None + + def create_synthetic_sales_data(self, n_stores=5, days=730): + """ + Create synthetic sales data with complex temporal patterns - daily frequency for time-based analysis + """ + self.print_section("CREATING SYNTHETIC SALES DATA") + + np.random.seed(42) + start_date = pd.to_datetime('2022-01-01') + dates = pd.date_range(start_date, periods=days, freq='D') + + data_list = [] + + for store_id in range(1, n_stores + 1): + store_base = 5000 + store_id * 1000 + + for i, date in enumerate(dates): + yearly_trend = 500 * (i / len(dates)) + monthly_seasonal = 1000 * np.sin(2 * np.pi * date.month / 12) + weekly_pattern = 800 * np.sin(2 * np.pi * date.weekday() / 7) + is_weekend = date.weekday() >= 5 + is_holiday = (date.month == 12 and date.day >= 20) or (date.month == 1 and date.day <= 5) + is_summer = date.month in [6, 7, 8] + promo_prob = 0.1 + 0.05 * (store_id % 2) + has_promo = np.random.random() < promo_prob + recession_effect = -200 if date.year == 2023 and date.month > 6 else 0 + weather_effect = 300 * np.sin(2 * np.pi * (date.dayofyear - 80) / 365) + competition_effect = -100 if store_id > 3 and date > pd.to_datetime('2022-06-01') else 0 + + base_sales = (store_base + yearly_trend + monthly_seasonal + weekly_pattern + + weather_effect + recession_effect + competition_effect) + + if is_weekend: + base_sales *= 1.3 + if is_holiday: + base_sales *= 1.8 + if is_summer: + base_sales *= 1.1 + if has_promo: + base_sales *= np.random.uniform(1.2, 1.8) + + noise = np.random.normal(0, 300) + sales = max(100, base_sales + noise) + + customers = int(sales / np.random.uniform(15, 25)) + avg_transaction = sales / max(customers, 1) + foot_traffic = customers * np.random.uniform(1.1, 1.5) + + data_list.append({ + 'Date': date, + 'Store': store_id, + 'Sales': sales, + 'Customers': customers, + 'AvgTransaction': avg_transaction, + 'FootTraffic': foot_traffic, + 'HasPromo': int(has_promo), + 'IsWeekend': int(is_weekend), + 'IsHoliday': int(is_holiday), + 'IsSummer': int(is_summer), + 'DayOfWeek': date.weekday(), + 'Month': date.month, + 'Quarter': date.quarter, + 'WeekOfYear': date.isocalendar()[1], + 'Temperature': 20 + 15 * np.sin(2 * np.pi * (date.dayofyear - 80) / 365) + np.random.normal(0, 5), + 'CompetitorDistance': 1000 + store_id * 500 + np.random.normal(0, 100) + }) + + df = pd.DataFrame(data_list) + + # Create target variables + df['HighSales'] = (df['Sales'] > df['Sales'].quantile(0.75)).astype(int) + df['SalesGrowth'] = df.groupby('Store')['Sales'].pct_change() + df['NextDaySales'] = df.groupby('Store')['Sales'].shift(-1) + + # Add lag features for comparison + df['Sales_Lag1'] = df.groupby('Store')['Sales'].shift(1) + df['Sales_Lag7'] = df.groupby('Store')['Sales'].shift(7) + + df = df.dropna() + + if self.verbose: + print(f"Synthetic sales data created: {len(df)} rows, {df['Store'].nunique()} stores") + print(f"Date range: {df['Date'].min()} to {df['Date'].max()}") + print(f"Sales statistics: mean={df['Sales'].mean():.2f}, std={df['Sales'].std():.2f}") + + return df + + def create_hourly_energy_data(self, days=180): + """ + Create synthetic hourly energy consumption data for high-frequency time-based analysis + """ + self.print_section("CREATING HOURLY ENERGY CONSUMPTION DATA") + + np.random.seed(42) + start_date = pd.to_datetime('2023-01-01') + dates = pd.date_range(start_date, periods=days * 24, freq='H') + + data_list = [] + + for i, timestamp in enumerate(dates): + # Base consumption pattern + base_consumption = 1000 + + # Hourly pattern (lower at night, higher during day) + hourly_pattern = 300 * np.sin(2 * np.pi * (timestamp.hour - 6) / 24) + + # Weekly pattern (lower on weekends) + weekly_pattern = 200 * np.sin(2 * np.pi * timestamp.weekday() / 7) + + # Seasonal pattern (higher in winter/summer for heating/cooling) + seasonal_pattern = 400 * np.sin(2 * np.pi * (timestamp.dayofyear - 80) / 365) + + # Weather effect (temperature-based) + temp = 20 + 15 * np.sin(2 * np.pi * (timestamp.dayofyear - 80) / 365) + np.random.normal(0, 3) + weather_effect = 0 + if temp < 10: # Heating + weather_effect = (10 - temp) * 50 + elif temp > 25: # Cooling + weather_effect = (temp - 25) * 40 + + # Special events (holidays, etc.) + is_holiday = (timestamp.month == 12 and timestamp.day >= 20) or ( + timestamp.month == 1 and timestamp.day <= 5) + holiday_effect = -200 if is_holiday else 0 + + # Random noise + noise = np.random.normal(0, 100) + + consumption = max(200, base_consumption + hourly_pattern + weekly_pattern + + seasonal_pattern + weather_effect + holiday_effect + noise) + + data_list.append({ + 'DateTime': timestamp, + 'Consumption': consumption, + 'Temperature': temp, + 'Hour': timestamp.hour, + 'DayOfWeek': timestamp.weekday(), + 'Month': timestamp.month, + 'Quarter': timestamp.quarter, + 'IsWeekend': int(timestamp.weekday() >= 5), + 'IsHoliday': int(is_holiday), + 'IsBusinessHour': int(9 <= timestamp.hour <= 17), + 'HourlyPattern': hourly_pattern, + 'WeatherEffect': weather_effect + }) + + df = pd.DataFrame(data_list) + + # Create targets + df['NextHourConsumption'] = df['Consumption'].shift(-1) + df['HighConsumption'] = (df['Consumption'] > df['Consumption'].quantile(0.8)).astype(int) + df['ConsumptionChange'] = df['Consumption'].diff() + + df = df.dropna() + + if self.verbose: + print(f"Energy data created: {len(df)} rows") + print(f"Date range: {df['DateTime'].min()} to {df['DateTime'].max()}") + print(f"Consumption statistics: mean={df['Consumption'].mean():.2f}, std={df['Consumption'].std():.2f}") + + return df + + def calculate_rsi(self, prices, period=14): + """Calculate RSI (Relative Strength Index)""" + delta = prices.diff() + gain = delta.where(delta > 0, 0).rolling(window=period, min_periods=1).mean() + loss = -delta.where(delta < 0, 0).rolling(window=period, min_periods=1).mean() + rs = gain / loss + rsi = 100 - (100 / (1 + rs)) + return rsi.fillna(50) + + def calculate_macd(self, prices, fast=12, slow=26): + """Calculate MACD""" + ema_fast = prices.ewm(span=fast, adjust=False).mean() + ema_slow = prices.ewm(span=slow, adjust=False).mean() + macd = ema_fast - ema_slow + return macd.fillna(0) + + def calculate_bollinger_bands(self, prices, period=20, std_dev=2): + """Calculate Bollinger Bands""" + sma = prices.rolling(window=period, min_periods=1).mean() + std = prices.rolling(window=period, min_periods=1).std() + upper_band = sma + (std * std_dev) + lower_band = sma - (std * std_dev) + return upper_band.fillna(sma), lower_band.fillna(sma) + + def test_dataset(self, df, dataset_name, date_col, target_configs): + """ + Test a dataset with multiple target variables and configurations using time-based BigFeat implementation + """ + self.print_section(f"TESTING DATASET: {dataset_name}") + + if df is None or len(df) == 0: + print(f"⚠ Skipping {dataset_name} - no data available") + return {} + + results = {} + + df[date_col] = pd.to_datetime(df[date_col]) + df = df.sort_values([date_col]).reset_index(drop=True) + + for target_config in target_configs: + target_col = target_config['target'] + task_type = target_config['task_type'] + feature_cols = target_config['features'] + config_name = target_config['name'] + groupby_cols = target_config.get('groupby_cols', []) + time_step = target_config.get('time_step', 'D') + + print(f"\n{'-' * 60}") + print(f"Testing: {config_name} ({task_type})") + print(f"Target: {target_col}") + print(f"Features: {len(feature_cols)}") + print(f"Groupby columns: {groupby_cols}") + print(f"Time step: {time_step}") + + try: + # Prepare data - Create full DataFrame with all required columns + X_full = df[feature_cols + [date_col] + groupby_cols].copy() + y = df[target_col].copy() + + # Handle missing values + X_full[feature_cols] = X_full[feature_cols].fillna(X_full[feature_cols].mean()) + y = y.fillna(y.mean() if task_type == 'regression' else y.mode().iloc[0]) + + # Time-based split + split_date = df[date_col].quantile(0.8) + train_mask = df[date_col] <= split_date + test_mask = df[date_col] > split_date + + X_train_full = X_full[train_mask] + X_test_full = X_full[test_mask] + y_train = y[train_mask].values + y_test = y[test_mask].values + + if len(X_train_full) < 100 or len(X_test_full) < 20: + print(f"⚠ Insufficient data: train={len(X_train_full)}, test={len(X_test_full)}") + continue + + print(f"Data split: train={len(X_train_full)}, test={len(X_test_full)}") + + if task_type == 'classification': + unique_classes = len(np.unique(y_train)) + print(f"Classes: {unique_classes}, distribution: {np.bincount(y_train.astype(int))}") + else: + print(f"Target stats: mean={y_train.mean():.4f}, std={y_train.std():.4f}") + + # Define time-based window configurations + if 'hourly' in dataset_name.lower() or time_step == 'H': + # Hourly data configurations + window_configs = { + 'short_term': ['1H', '3H', '6H', '12H', '1D'], + 'medium_term': ['1D', '3D', '7D', '14D'], + 'long_term': ['7D', '14D', '30D', '60D'] + } + lag_configs = { + 'short_term': ['1H', '3H', '6H', '12H'], + 'medium_term': ['1D', '3D', '7D'], + 'long_term': ['7D', '14D', '30D'] + } + elif 'crypto' in dataset_name.lower() or 'stock' in dataset_name.lower(): + # Financial data configurations + window_configs = { + 'short_term': ['3D', '7D', '14D', '21D'], + 'medium_term': ['30D', '60D', '90D'], + 'long_term': ['6M', '1Y'] + } + lag_configs = { + 'short_term': ['1D', '3D', '7D'], + 'medium_term': ['14D', '30D'], + 'long_term': ['60D', '90D'] + } + else: + # Default daily configurations + window_configs = { + 'short_term': ['7D', '14D', '30D'], + 'medium_term': ['60D', '90D', '180D'], + 'long_term': ['1Y'] + } + lag_configs = { + 'short_term': ['1D', '7D', '14D'], + 'medium_term': ['30D', '60D'], + 'long_term': ['90D', '180D'] + } + + # Test configurations with time-based windows + configurations = [ + { + 'name': 'Baseline (No Time Series)', + 'params': { + 'task_type': task_type, + 'enable_time_series': False, + 'verbose': False + }, + 'fit_params': { + 'gen_size': 3, + 'iterations': 2, + 'random_state': 42, + 'estimator': 'rf' if task_type == 'classification' else 'rf_reg', + 'selection': 'stability' + } + }, + { + 'name': 'Time Series (Short-term)', + 'params': { + 'task_type': task_type, + 'enable_time_series': True, + 'datetime_col': date_col, + 'groupby_cols': groupby_cols, + 'window_sizes': window_configs['short_term'], + 'lag_periods': lag_configs['short_term'], + 'time_step': time_step, + 'verbose': False + }, + 'fit_params': { + 'gen_size': 4, + 'iterations': 3, + 'random_state': 42, + 'estimator': 'rf' if task_type == 'classification' else 'rf_reg', + 'selection': 'stability' + } + }, + { + 'name': 'Time Series (Medium-term)', + 'params': { + 'task_type': task_type, + 'enable_time_series': True, + 'datetime_col': date_col, + 'groupby_cols': groupby_cols, + 'window_sizes': window_configs['medium_term'], + 'lag_periods': lag_configs['medium_term'], + 'time_step': time_step, + 'verbose': False + }, + 'fit_params': { + 'gen_size': 4, + 'iterations': 3, + 'random_state': 42, + 'estimator': 'rf' if task_type == 'classification' else 'rf_reg', + 'selection': 'stability' + } + }, + { + 'name': 'Time Series (Long-term)', + 'params': { + 'task_type': task_type, + 'enable_time_series': True, + 'datetime_col': date_col, + 'groupby_cols': groupby_cols, + 'window_sizes': window_configs['long_term'], + 'lag_periods': lag_configs['long_term'], + 'time_step': time_step, + 'verbose': False + }, + 'fit_params': { + 'gen_size': 4, + 'iterations': 3, + 'random_state': 42, + 'estimator': 'avg', + 'selection': 'stability' + } + }, + { + 'name': 'Time Series (Mixed)', + 'params': { + 'task_type': task_type, + 'enable_time_series': True, + 'datetime_col': date_col, + 'groupby_cols': groupby_cols, + 'window_sizes': window_configs['short_term'] + window_configs['medium_term'], + 'lag_periods': lag_configs['short_term'] + lag_configs['medium_term'], + 'time_step': time_step, + 'verbose': False + }, + 'fit_params': { + 'gen_size': 5, + 'iterations': 4, + 'random_state': 42, + 'estimator': 'avg', + 'selection': 'stability' + } + } + ] + + config_results = {} + + for config in configurations: + try: + print(f"\n Testing: {config['name']}") + if config['params'].get('enable_time_series', False): + print(f" Window sizes: {config['params']['window_sizes']}") + print(f" Lag periods: {config['params']['lag_periods']}") + print(f" Time step: {config['params']['time_step']}") + + bigfeat = BigFeat(**config['params']) + + # Fit BigFeat with full DataFrame (including datetime and groupby columns) + X_train_enhanced = bigfeat.fit(X_train_full, y_train, **config['fit_params']) + X_test_enhanced = bigfeat.transform(X_test_full) + + # Count time series operations + ts_ops_count = 0 + if config['params'].get('enable_time_series', False) and hasattr(bigfeat, 'tracking_ops'): + time_series_op_names = [ + '_safe_rolling_mean', '_safe_rolling_std', '_safe_rolling_min', '_safe_rolling_max', + '_safe_rolling_median', '_safe_rolling_sum', '_safe_lag_feature', '_safe_diff_feature', + '_safe_pct_change', '_safe_ewm', '_safe_momentum', '_safe_seasonal_decompose', + '_safe_trend_feature', '_safe_weekday_mean', '_safe_month_mean' + ] + + for ops in bigfeat.tracking_ops: + if ops: # Check if ops list is not empty + for op_info in ops: + if len(op_info) > 0 and callable(op_info[0]): + op_name = getattr(op_info[0], '__name__', '') + if op_name in time_series_op_names: + ts_ops_count += 1 + + print(f" Generated features shape: {X_train_enhanced.shape}") + print(f" Time series operations used: {ts_ops_count}") + + # Select and train model + estimator_names = ['rf', 'dt'] if task_type == 'classification' else ['rf_reg', 'dt_reg'] + best_model = bigfeat.select_estimator(X_train_enhanced, y_train, estimator_names) + + # Make predictions + y_pred = best_model.predict(X_test_enhanced) + + # Calculate metrics + if task_type == 'classification': + score = accuracy_score(y_test, y_pred) + metric_name = 'Accuracy' + else: + score = r2_score(y_test, y_pred) + mae = mean_absolute_error(y_test, y_pred) + rmse = np.sqrt(mean_squared_error(y_test, y_pred)) + metric_name = 'R²' + + config_results[config['name']] = { + 'score': score, + 'n_features': X_train_enhanced.shape[1], + 'ts_ops_count': ts_ops_count, + 'model': type(best_model).__name__ + } + + if task_type == 'regression': + config_results[config['name']]['mae'] = mae + config_results[config['name']]['rmse'] = rmse + + print( + f" {metric_name}: {score:.4f}, Features: {X_train_enhanced.shape[1]}, TS Ops: {ts_ops_count}") + + # Save detailed results if requested + if self.save_results and config['name'] != 'Baseline (No Time Series)': + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + + # Generate feature information + feature_names = [] + feature_descriptions = [] + + if hasattr(bigfeat, 'tracking_ops') and hasattr(bigfeat, 'tracking_ids'): + for i, (ops, ids) in enumerate(zip(bigfeat.tracking_ops, bigfeat.tracking_ids)): + if not ops or len(ops) == 0: + if ids and len(ids) > 0 and ids[0] < len(feature_cols): + feat_name = f"Original_{feature_cols[ids[0]]}" + desc = f"Original: {feature_cols[ids[0]]}" + else: + feat_name = f"Original_Feat_{i}" + desc = f"Original feature {i}" + else: + # Generated feature + op_names = [] + for op_info in ops: + if len(op_info) > 0: + op = op_info[0] + op_name = getattr(op, '__name__', str(op)).replace('_safe_', + '').replace( + '', '') + op_names.append(op_name) + + feat_indices = [] + if ids: + for idx in ids: + if idx < len(feature_cols): + feat_indices.append(feature_cols[idx]) + else: + feat_indices.append(f"feat_{idx}") + + if op_names: + feat_name = f"Gen_Feat_{i}_{'_'.join(op_names[:2])}" + desc = f"{' -> '.join(op_names)}({', '.join(feat_indices)})" + else: + feat_name = f"Gen_Feat_{i}" + desc = f"Generated feature {i}" + + feature_names.append(feat_name) + feature_descriptions.append(desc) + + # Add original feature names for remaining features + while len(feature_names) < X_train_enhanced.shape[1]: + idx = len(feature_names) + if idx - len(bigfeat.tracking_ops) < len(feature_cols): + orig_idx = idx - len(bigfeat.tracking_ops) + feature_names.append(f"Original_{feature_cols[orig_idx]}") + feature_descriptions.append(f"Original: {feature_cols[orig_idx]}") + else: + feature_names.append(f"Original_Feat_Extra_{idx}") + feature_descriptions.append(f"Original feature {idx}") + + # Save feature information + feature_info = { + 'feature_names': feature_names[:X_train_enhanced.shape[1]], + 'feature_descriptions': feature_descriptions[:X_train_enhanced.shape[1]], + 'n_generated_features': len(bigfeat.tracking_ops) if hasattr(bigfeat, + 'tracking_ops') else 0, + 'n_original_features': len(feature_cols), + 'total_features': X_train_enhanced.shape[1], + 'ts_ops_count': ts_ops_count, + 'datetime_col': date_col, + 'groupby_cols': groupby_cols, + 'window_sizes': config['params'].get('window_sizes', []), + 'lag_periods': config['params'].get('lag_periods', []), + 'time_step': config['params'].get('time_step', 'D') + } + + feature_info_file = f'results/{dataset_name}_{config_name}_{config["name"]}_feature_info_{timestamp}.json' + with open(feature_info_file, 'w') as f: + json.dump(feature_info, f, indent=2) + + print(f" Feature info saved to {feature_info_file}") + + except Exception as e: + print(f" Error: {str(e)}") + import traceback + if self.verbose: + traceback.print_exc() + config_results[config['name']] = {'error': str(e), 'score': 0} + + # Calculate improvements + baseline_score = config_results.get('Baseline (No Time Series)', {}).get('score', 0) + + print(f"\n Results Summary for {config_name}:") + print(f" {'-' * 70}") + + for name, result in config_results.items(): + if 'error' not in result: + improvement = result['score'] - baseline_score + line = f" {name:30} | {metric_name}: {result['score']:7.4f} | Feat: {result.get('n_features', 0):3d} | TS: {result.get('ts_ops_count', 0):2d} | Δ: {improvement:+7.4f}" + if task_type == 'regression': + line += f" | MAE: {result.get('mae', 0):8.4f} | RMSE: {result.get('rmse', 0):8.4f}" + print(line) + else: + print(f" {name:30} | ERROR: {result['error'][:40]}...") + + results[config_name] = config_results + + except Exception as e: + print(f"Error testing {config_name}: {str(e)}") + import traceback + if self.verbose: + traceback.print_exc() + results[config_name] = {'error': str(e)} + + return results + + def generate_comprehensive_report(self, all_results): + """ + Generate a comprehensive report of all test results with time-based analysis + """ + self.print_section("COMPREHENSIVE TIME-BASED TEST RESULTS SUMMARY") + + total_tests = 0 + successful_tests = 0 + improvements = [] + best_improvements = {} + time_series_improvements = {} + + for dataset_name, dataset_results in all_results.items(): + print(f"\n{dataset_name}:") + print("-" * 70) + + for config_name, config_results in dataset_results.items(): + if isinstance(config_results, dict) and 'error' not in config_results: + + baseline_score = config_results.get('Baseline (No Time Series)', {}).get('score', 0) + + print(f"\n {config_name}:") + print(f" {'Method':<30} | {'Score':<8} | {'Features':<8} | {'TS Ops':<6} | {'Improvement':<11}") + print(f" {'-' * 75}") + + for method_name, method_result in config_results.items(): + if isinstance(method_result, dict) and 'error' not in method_result: + score = method_result.get('score', 0) + n_features = method_result.get('n_features', 0) + ts_ops = method_result.get('ts_ops_count', 0) + improvement = score - baseline_score + + improvements.append(improvement) + total_tests += 1 + + if improvement > 0: + successful_tests += 1 + + # Track time series specific improvements + if 'Time Series' in method_name: + time_period = method_name.split('(')[-1].split(')')[ + 0] if '(' in method_name else 'Mixed' + key = f"{dataset_name}_{config_name}_{time_period}" + time_series_improvements[key] = { + 'improvement': improvement, + 'method': method_name, + 'score': score, + 'ts_ops': ts_ops, + 'time_period': time_period + } + + # Track best improvements per dataset/config + key = f"{dataset_name}_{config_name}" + if key not in best_improvements or improvement > best_improvements[key]['improvement']: + best_improvements[key] = { + 'improvement': improvement, + 'method': method_name, + 'score': score, + 'dataset': dataset_name, + 'config': config_name, + 'ts_ops': ts_ops + } + + line = f" {method_name:<30} | {score:8.4f} | {n_features:8d} | {ts_ops:6d} | {improvement:+11.4f}" + if 'mae' in method_result: + line += f" | MAE: {method_result['mae']:8.4f} | RMSE: {method_result['rmse']:8.4f}" + print(line) + + elif isinstance(method_result, dict) and 'error' in method_result: + print(f" {method_name:<30} | ERROR: {method_result['error'][:40]}...") + + # Overall statistics + print(f"\n{'=' * 80}") + print("TIME-BASED SERIES PERFORMANCE ANALYSIS") + print(f"{'=' * 80}") + + if improvements: + positive_improvements = [imp for imp in improvements if imp > 0] + significant_improvements = [imp for imp in improvements if imp > 0.01] + + print(f"Total tests conducted: {total_tests}") + print( + f"Tests with positive improvement: {len(positive_improvements)} ({len(positive_improvements) / total_tests * 100:.1f}%)") + print( + f"Tests with significant improvement (>0.01): {len(significant_improvements)} ({len(significant_improvements) / total_tests * 100:.1f}%)") + print(f"Average improvement: {np.mean(improvements):+.4f}") + print(f"Best improvement: {np.max(improvements):+.4f}") + print(f"Worst improvement: {np.min(improvements):+.4f}") + + print(f"\nBest Time-Based Window Performance Analysis:") + print(f"{'-' * 80}") + + # Analyze performance by time period + time_period_performance = {} + for key, result in time_series_improvements.items(): + period = result['time_period'] + if period not in time_period_performance: + time_period_performance[period] = [] + time_period_performance[period].append(result['improvement']) + + print(f"{'Time Period':<15} | {'Avg Improvement':<15} | {'Best Improvement':<15} | {'Count':<8}") + print(f"{'-' * 65}") + for period, improvements_list in time_period_performance.items(): + avg_imp = np.mean(improvements_list) + best_imp = np.max(improvements_list) + count = len(improvements_list) + print(f"{period:<15} | {avg_imp:+15.4f} | {best_imp:+15.4f} | {count:<8}") + + print(f"\nBest Improvements by Dataset/Task:") + print(f"{'-' * 70}") + print( + f"{'Dataset':<20} | {'Task':<25} | {'Method':<25} | {'Score':<8} | {'TS Ops':<6} | {'Improvement':<11}") + print(f"{'-' * 85}") + for key, result in best_improvements.items(): + print( + f"{result['dataset']:<20} | {result['config']:<25} | {result['method']:<25} | {result['score']:8.4f} | {result.get('ts_ops', 0):6d} | {result['improvement']:+11.4f}") + + # Generate visualization + if self.save_results: + self.plot_time_based_improvements(improvements, best_improvements, time_series_improvements) + + else: + print("No valid test results to analyze.") + + def plot_time_based_improvements(self, improvements, best_improvements, time_series_improvements): + """ + Generate visualization of time-based improvements + """ + try: + # Distribution of improvements + plt.figure(figsize=(15, 10)) + + plt.subplot(2, 3, 1) + sns.histplot(improvements, bins=30, kde=True) + plt.title('Distribution of Performance Improvements') + plt.xlabel('Improvement (Score - Baseline)') + plt.ylabel('Count') + plt.axvline(x=0, color='red', linestyle='--', alpha=0.7) + + # Time period performance + plt.subplot(2, 3, 2) + time_period_data = {} + for key, result in time_series_improvements.items(): + period = result['time_period'] + if period not in time_period_data: + time_period_data[period] = [] + time_period_data[period].append(result['improvement']) + + periods = list(time_period_data.keys()) + avg_improvements = [np.mean(time_period_data[period]) for period in periods] + + plt.bar(periods, avg_improvements) + plt.title('Average Improvement by Time Period') + plt.xlabel('Time Period') + plt.ylabel('Average Improvement') + plt.xticks(rotation=45) + plt.axhline(y=0, color='red', linestyle='--', alpha=0.7) + + # Best improvements by dataset + plt.subplot(2, 3, 3) + datasets_tasks = [f"{r['dataset']}_{r['config'][:15]}" for r in best_improvements.values()] + scores = [r['improvement'] for r in best_improvements.values()] + plt.barh(datasets_tasks, scores) + plt.title('Best Improvements by Dataset') + plt.xlabel('Improvement (Score - Baseline)') + plt.axvline(x=0, color='red', linestyle='--', alpha=0.7) + + # Time series operations usage + plt.subplot(2, 3, 4) + ts_ops_counts = [r.get('ts_ops', 0) for r in best_improvements.values() if r.get('ts_ops', 0) > 0] + improvements_with_ts = [r['improvement'] for r in best_improvements.values() if r.get('ts_ops', 0) > 0] + + if ts_ops_counts and improvements_with_ts: + plt.scatter(ts_ops_counts, improvements_with_ts, alpha=0.7) + plt.xlabel('Number of Time Series Operations') + plt.ylabel('Improvement') + plt.title('TS Operations vs Improvement') + + # Add trend line + if len(ts_ops_counts) > 1: + z = np.polyfit(ts_ops_counts, improvements_with_ts, 1) + p = np.poly1d(z) + plt.plot(ts_ops_counts, p(ts_ops_counts), "r--", alpha=0.8) + + # Performance comparison + plt.subplot(2, 3, 5) + method_performance = {} + for key, results in best_improvements.items(): + method = results['method'] + if 'Time Series' in method: + method_key = 'Time Series' + else: + method_key = 'Baseline' + + if method_key not in method_performance: + method_performance[method_key] = [] + method_performance[method_key].append(results['improvement']) + + methods = list(method_performance.keys()) + method_data = [method_performance[method] for method in methods] + + plt.boxplot(method_data, labels=methods) + plt.title('Improvement Distribution by Method Type') + plt.ylabel('Improvement') + plt.axhline(y=0, color='red', linestyle='--', alpha=0.7) + + # Summary statistics + plt.subplot(2, 3, 6) + plt.axis('off') + stats_text = f""" + Time-Based Series Analysis Summary: + + Total Tests: {len(improvements)} + Positive Improvements: {len([x for x in improvements if x > 0])} + Success Rate: {len([x for x in improvements if x > 0]) / len(improvements) * 100:.1f}% + + Average Improvement: {np.mean(improvements):+.4f} + Best Improvement: {np.max(improvements):+.4f} + Std Dev: {np.std(improvements):.4f} + + Time Series Operations: + Avg TS Ops per Test: {np.mean([r.get('ts_ops', 0) for r in best_improvements.values()]):.1f} + Max TS Ops Used: {max([r.get('ts_ops', 0) for r in best_improvements.values()])} + """ + plt.text(0.1, 0.9, stats_text, transform=plt.gca().transAxes, + verticalalignment='top', fontsize=10, fontfamily='monospace') + + plt.tight_layout() + plt.savefig('results/time_based_analysis.png', dpi=300, bbox_inches='tight') + plt.close() + + print(f"\nTime-based analysis visualization saved to 'results/time_based_analysis.png'") + + except Exception as e: + print(f"Error generating time-based plots: {e}") + + def save_test_results(self, all_results): + """ + Save test results to JSON file with time-based analysis details + """ + try: + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + output_file = f'results/time_based_test_results_{timestamp}.json' + + results_to_save = {} + for dataset_name, dataset_results in all_results.items(): + results_to_save[dataset_name] = {} + for config_name, config_results in dataset_results.items(): + if isinstance(config_results, dict) and 'error' not in config_results: + results_to_save[dataset_name][config_name] = { + name: {k: float(v) if isinstance(v, (np.floating, np.integer)) else v + for k, v in result.items()} + for name, result in config_results.items() + } + else: + results_to_save[dataset_name][config_name] = config_results + + with open(output_file, 'w') as f: + json.dump(results_to_save, f, indent=2) + + print(f"\nTime-based test results saved to {output_file}") + + except Exception as e: + print(f"Error saving results: {e}") + + def run_comprehensive_tests(self): + """ + Run comprehensive tests on multiple datasets with time-based window analysis + """ + self.print_section("BIGFEAT TIME-BASED SERIES COMPREHENSIVE TESTING SUITE") + print("Testing BigFeat time-based series capabilities on real-world temporal datasets") + print("This comprehensive test focuses on time-based windows (days, weeks, months)") + print("This comprehensive test may take 15-20 minutes to complete...") + + all_results = {} + + # Test 1: Stock Market Data (Daily) + try: + stock_df = self.load_stock_data(['AAPL', 'GOOGL', 'MSFT'], period='2y') + if stock_df is not None: + stock_features = ['Open', 'High', 'Low', 'Volume', 'Returns', 'Volatility', + 'HL_Pct', 'Volume_MA', 'RSI', 'MACD', 'DayOfWeek', 'Month', 'DaysFromStart'] + + stock_configs = [ + { + 'name': 'Stock_Direction_Prediction', + 'target': 'Price_Up', + 'task_type': 'classification', + 'features': stock_features, + 'groupby_cols': ['Symbol'], + 'time_step': 'D' + }, + { + 'name': 'Stock_Return_Prediction', + 'target': 'Next_Return', + 'task_type': 'regression', + 'features': stock_features, + 'groupby_cols': ['Symbol'], + 'time_step': 'D' + }, + { + 'name': 'Stock_Volatility_Prediction', + 'target': 'Volatility_High', + 'task_type': 'classification', + 'features': [f for f in stock_features if f != 'Volatility'], + 'groupby_cols': ['Symbol'], + 'time_step': 'D' + } + ] + + stock_results = self.test_dataset(stock_df, 'Stock_Market_Daily', 'Date', stock_configs) + all_results['Stock_Market_Daily'] = stock_results + except Exception as e: + print(f"Stock data test failed: {e}") + import traceback + if self.verbose: + traceback.print_exc() + + # Test 2: Cryptocurrency Data (Daily) + try: + crypto_df = self.load_crypto_data(['BTC-USD', 'ETH-USD'], period='1y') + if crypto_df is not None: + crypto_features = ['Open', 'High', 'Low', 'Volume', 'Returns', 'Volatility', + 'Price_Range', 'SMA_7', 'SMA_30', 'Price_Position', 'DayOfWeek', 'Month'] + + crypto_configs = [ + { + 'name': 'Crypto_Direction_Prediction', + 'target': 'Price_Up', + 'task_type': 'classification', + 'features': crypto_features, + 'groupby_cols': ['Symbol'], + 'time_step': 'D' + }, + { + 'name': 'Crypto_Return_Prediction', + 'target': 'Next_Return', + 'task_type': 'regression', + 'features': crypto_features, + 'groupby_cols': ['Symbol'], + 'time_step': 'D' + } + ] + + crypto_results = self.test_dataset(crypto_df, 'Cryptocurrency_Daily', 'Date', crypto_configs) + all_results['Cryptocurrency_Daily'] = crypto_results + except Exception as e: + print(f"Crypto data test failed: {e}") + import traceback + if self.verbose: + traceback.print_exc() + + # Test 3: Synthetic Sales Data (Daily) + try: + sales_df = self.create_synthetic_sales_data(n_stores=5, days=730) + sales_features = ['Customers', 'AvgTransaction', 'FootTraffic', 'HasPromo', + 'IsWeekend', 'Temperature', 'DayOfWeek', 'Month', 'Quarter', 'WeekOfYear'] + + sales_configs = [ + { + 'name': 'Sales_High_Performance', + 'target': 'HighSales', + 'task_type': 'classification', + 'features': sales_features, + 'groupby_cols': ['Store'], + 'time_step': 'D' + }, + { + 'name': 'Sales_Next_Day_Prediction', + 'target': 'NextDaySales', + 'task_type': 'regression', + 'features': sales_features, + 'groupby_cols': ['Store'], + 'time_step': 'D' + } + ] + + sales_results = self.test_dataset(sales_df, 'Retail_Sales_Daily', 'Date', sales_configs) + all_results['Retail_Sales_Daily'] = sales_results + except Exception as e: + print(f"Sales data test failed: {e}") + import traceback + if self.verbose: + traceback.print_exc() + + # Test 4: Hourly Energy Data + try: + energy_df = self.create_hourly_energy_data(days=180) + energy_features = ['Temperature', 'Hour', 'DayOfWeek', 'Month', 'Quarter', + 'IsWeekend', 'IsHoliday', 'IsBusinessHour', 'HourlyPattern', 'WeatherEffect'] + + energy_configs = [ + { + 'name': 'Energy_High_Consumption', + 'target': 'HighConsumption', + 'task_type': 'classification', + 'features': energy_features, + 'groupby_cols': [], + 'time_step': 'H' + }, + { + 'name': 'Energy_Next_Hour_Prediction', + 'target': 'NextHourConsumption', + 'task_type': 'regression', + 'features': energy_features, + 'groupby_cols': [], + 'time_step': 'H' + } + ] + + energy_results = self.test_dataset(energy_df, 'Energy_Consumption_Hourly', 'DateTime', energy_configs) + all_results['Energy_Consumption_Hourly'] = energy_results + except Exception as e: + print(f"Energy data test failed: {e}") + import traceback + if self.verbose: + traceback.print_exc() + + # Test 5: Simple Time Series Test (Weekly aggregation) + try: + # Create a simple time series dataset for weekly analysis + self.print_section("CREATING SIMPLE WEEKLY TIME SERIES DATA") + + np.random.seed(42) + dates = pd.date_range('2022-01-01', periods=520, freq='W') # Weekly data for 10 years + + # Create trend + seasonality + noise + trend = np.linspace(100, 200, len(dates)) + seasonality = 20 * np.sin(2 * np.pi * np.arange(len(dates)) / 52) # yearly seasonality + noise = np.random.normal(0, 5, len(dates)) + + values = trend + seasonality + noise + + simple_df = pd.DataFrame({ + 'Date': dates, + 'Value': values, + 'WeekOfYear': dates.isocalendar().week, + 'Month': dates.month, + 'Quarter': dates.quarter, + 'IsEndOfMonth': dates.is_month_end.astype(int), + 'Feature1': np.random.normal(10, 2, len(dates)), + 'Feature2': np.random.normal(5, 1, len(dates)), + 'Feature3': values * 0.1 + np.random.normal(0, 1, len(dates)) + }) + + # Create targets + simple_df['NextValue'] = simple_df['Value'].shift(-1) + simple_df['HighValue'] = (simple_df['Value'] > simple_df['Value'].quantile(0.7)).astype(int) + simple_df = simple_df.dropna() + + simple_features = ['WeekOfYear', 'Month', 'Quarter', 'IsEndOfMonth', 'Feature1', 'Feature2', 'Feature3'] + + simple_configs = [ + { + 'name': 'Simple_Weekly_Regression', + 'target': 'NextValue', + 'task_type': 'regression', + 'features': simple_features, + 'groupby_cols': [], + 'time_step': 'W' + }, + { + 'name': 'Simple_Weekly_Classification', + 'target': 'HighValue', + 'task_type': 'classification', + 'features': simple_features, + 'groupby_cols': [], + 'time_step': 'W' + } + ] + + simple_results = self.test_dataset(simple_df, 'Simple_Weekly_TimeSeries', 'Date', simple_configs) + all_results['Simple_Weekly_TimeSeries'] = simple_results + + except Exception as e: + print(f"Simple weekly time series test failed: {e}") + import traceback + if self.verbose: + traceback.print_exc() + + # Generate comprehensive report + self.generate_comprehensive_report(all_results) + + # Save results if requested + if self.save_results: + self.save_test_results(all_results) + + return all_results + + +def main(): + """Main function to run the comprehensive time-based tests""" + print("Starting BigFeat Time-Based Series Testing...") + print("=" * 80) + print("This enhanced test suite will:") + print("1. Test your BigFeat implementation with time-based window capabilities") + print("2. Compare performance across different time horizons (short/medium/long-term)") + print("3. Test on multiple frequencies (hourly, daily, weekly)") + print("4. Analyze effectiveness of time-based vs data-point-based windows") + print("5. Generate detailed time-based analysis reports") + print("6. Test seasonal, trend, and cyclical pattern detection") + print("=" * 80) + + tester = ComprehensiveTimeSeriesTester(verbose=True, save_results=True) + results = tester.run_comprehensive_tests() + + print("\n" + "=" * 80) + print("TIME-BASED TESTING COMPLETED SUCCESSFULLY!") + print("=" * 80) + print("Check the 'results' directory for:") + print("- Time-based feature analysis (JSON files)") + print("- Time horizon performance comparisons (PNG files)") + print("- Complete time-based test results (JSON file)") + print("- Time series operation effectiveness analysis") + print("=" * 80) + + return results + + +if __name__ == "__main__": + main() \ No newline at end of file From 799f21b5f2aacd2b87642d780d6ddae2bbaba8fb Mon Sep 17 00:00:00 2001 From: victoryst Date: Fri, 15 Aug 2025 17:00:00 +0300 Subject: [PATCH 2/2] Delete .idea directory --- .idea/.gitignore | 5 ----- .idea/BigFeat.iml | 14 -------------- .idea/inspectionProfiles/profiles_settings.xml | 6 ------ .idea/misc.xml | 7 ------- .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 6 files changed, 46 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/BigFeat.iml delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index b58b603..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/BigFeat.iml b/.idea/BigFeat.iml deleted file mode 100644 index 6609252..0000000 --- a/.idea/BigFeat.iml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2d..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 26c22e7..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 4d135fc..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file