Skip to content

Commit

Permalink
0.6.16 a59
Browse files Browse the repository at this point in the history
  • Loading branch information
winedarksea committed Oct 5, 2024
1 parent aca39df commit ec90bb2
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 14 deletions.
2 changes: 2 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
* 'round' option to Constraint
* minor change to mosaic min style ensembles to remove edge case errors
* 'mosaic-profile' and 'median' styles mosaic added
* updated profiler, and improved feature generation for horizontal generalization
* changepoint style trend as an option to GLM and GLS
* added ShiftFirstValue which is only a minor nuance on PositiveShift transformer
* added BasicLinearModel model

### Unstable Upstream Pacakges (those that are frequently broken by maintainers)
* Pytorch-Forecasting
Expand Down
15 changes: 8 additions & 7 deletions autots/models/basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
create_changepoint_features,
changepoint_fcst_from_last_row,
random_datepart,
half_yr_spacing,
)
from autots.tools.probabilistic import Point_to_Probability, historic_quantile
from autots.tools.window_functions import (
Expand Down Expand Up @@ -3434,11 +3435,11 @@ def fit(self, df, future_regressor=None):
df = self.basic_profile(df)
self.df = df
if self.changepoint_spacing is None or self.changepoint_distance_end is None:
half_yr_spacing = int(df.shape[0] / ((df.index.max().year - df.index.min().year + 1) * 2))
half_yr_space = half_yr_spacing(df)
if self.changepoint_spacing is None:
self.changepoint_spacing = half_yr_spacing
if self.changepoint_spacing is None:
self.changepoint_distance_end = int(half_yr_spacing / 2)
self.changepoint_spacing = int(half_yr_space)
if self.changepoint_distance_end is None:
self.changepoint_distance_end = int(half_yr_space / 2)
if str(self.regression_type).lower() == "user":
if future_regressor is None:
raise ValueError(
Expand All @@ -3457,7 +3458,7 @@ def fit(self, df, future_regressor=None):
else:
# Perform linear regression using the normal equation: (X.T @ X)^(-1) @ X.T @ Y
self.beta = np.linalg.pinv(X_values.T @ X_values) @ X_values.T @ Y_values

# Calculate predicted values for Y
Y_pred = X_values @ self.beta

Expand Down Expand Up @@ -3590,8 +3591,8 @@ def get_new_params(self, method: str = 'random'):
)[0]
return {
"datepart_method": random_datepart(method=method),
"changepoint_spacing": random.choices([6, 28, 60, 90, 180, 360, 5040], [0.05, 0.1, 0.1, 0.1, 0.2, 0.1, 0.2])[0],
"changepoint_distance_end": random.choices([6, 28, 60, 90, 180, 360, 5040], [0.05, 0.1, 0.1, 0.1, 0.2, 0.1, 0.2])[0],
"changepoint_spacing": random.choices([None, 6, 28, 60, 90, 180, 360, 5040], [0.1, 0.05, 0.1, 0.1, 0.1, 0.2, 0.1, 0.2])[0],
"changepoint_distance_end": random.choices([None, 6, 28, 60, 90, 180, 360, 5040], [0.1, 0.05, 0.1, 0.1, 0.1, 0.2, 0.1, 0.2])[0],
"regression_type": regression_choice,
"λ": random.choices([None, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000], [0.6, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], k=1)[0],
}
Expand Down
26 changes: 19 additions & 7 deletions autots/tools/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

import numpy as np
import pandas as pd
from autots.tools.seasonal import date_part, create_changepoint_features
from autots.tools.seasonal import date_part, create_changepoint_features, half_yr_spacing
from autots.models.basics import BasicLinearModel

def data_profile(df):
"""
"""Legacy profiler.
Input: a pd DataFrame of columns which are time series, and a datetime index
Output: a pd DataFrame of column per time series, with rows which are statistics
Expand Down Expand Up @@ -70,23 +70,35 @@ def summarize_series(df):
return df_sum


def profile_time_series(df, adi_threshold=1.3, cvar_threshold=0.5, flat_threshold=0.9, new_product_threshold=0.9, seasonal_threshold=0.5):
def profile_time_series(
df, adi_threshold=1.3, cvar_threshold=0.5, flat_threshold=0.9,
new_product_threshold='auto',
seasonal_threshold=0.5
):
"""
Profiles time series data into categories:
smooth, intermittent, erratic, lumpy, flat, new_product
Parameters:
df (pd.DataFrame): Wide format DataFrame with datetime index and each column as a time series.
Args:
df (pd.DataFrame): Wide format DataFrame with datetime index and each column as a time series.
new_product_threshold (float): one of the more finiky thresholds, percent of null or zero data from beginning to declare new product
new_product_correct (bool): use dt index to correct
Returns:
pd.DataFrame: DataFrame with 'SERIES' and 'DEMAND_PROFILE' columns.
pd.DataFrame: DataFrame with 'SERIES' and 'DEMAND_PROFILE' columns.
"""

metrics_df = summarize_series(df).transpose()

# Initialize demand profile as 'smooth'
metrics_df['PROFILE'] = 'smooth'

if new_product_threshold == "auto":
half_yr_space = half_yr_spacing(df)
new_product_threshold = 1 - (half_yr_space * 0.65 / df.shape[0])
if new_product_threshold < 0.85:
new_product_threshold = 0.85
if new_product_threshold > 0.99:
new_product_threshold = 0.99
# Apply conditions to classify the demand profiles
metrics_df.loc[(metrics_df['adi'] >= adi_threshold) & (metrics_df['cv_squared'] < cvar_threshold), 'PROFILE'] = 'intermittent'
metrics_df.loc[(metrics_df['adi'] < adi_threshold) & (metrics_df['cv_squared'] >= cvar_threshold), 'PROFILE'] = 'erratic'
Expand Down
3 changes: 3 additions & 0 deletions autots/tools/seasonal.py
Original file line number Diff line number Diff line change
Expand Up @@ -935,3 +935,6 @@ def changepoint_fcst_from_last_row(x_t_last_row, n_forecast=10):
forecast_steps = np.arange(n_forecast).reshape(-1, 1) # Shape it as multiple rows, 1 column
extended_features = np.maximum(0, last_values + forecast_steps)
return pd.DataFrame(extended_features, columns=x_t_last_row.index)

def half_yr_spacing(df):
return int(df.shape[0] / ((df.index.max().year - df.index.min().year + 1) * 2))

0 comments on commit ec90bb2

Please sign in to comment.