Skip to content

Commit

Permalink
feat: use new endpoints and rename models (#263)
Browse files Browse the repository at this point in the history
  • Loading branch information
AzulGarza authored Mar 22, 2024
1 parent fe224d5 commit 0e56620
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 72 deletions.
16 changes: 8 additions & 8 deletions nbs/distributed.timegpt.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
" add_history: bool = False,\n",
" date_features: Union[bool, List[str]] = False,\n",
" date_features_to_one_hot: Union[bool, List[str]] = True,\n",
" model: str = 'timegpt-1',\n",
" model: str = 'short-horizon',\n",
" num_partitions: Optional[int] = None,\n",
" ) -> fugue.AnyDataFrame:\n",
" kwargs = dict(\n",
Expand Down Expand Up @@ -217,7 +217,7 @@
" validate_token: bool = False,\n",
" date_features: Union[bool, List[str]] = False,\n",
" date_features_to_one_hot: Union[bool, List[str]] = True,\n",
" model: str = 'timegpt-1',\n",
" model: str = 'short-horizon',\n",
" num_partitions: Optional[int] = None,\n",
" ) -> fugue.AnyDataFrame:\n",
" kwargs = dict(\n",
Expand Down Expand Up @@ -260,7 +260,7 @@
" validate_token: bool = False,\n",
" date_features: Union[bool, List[str]] = False,\n",
" date_features_to_one_hot: Union[bool, List[str]] = True,\n",
" model: str = 'timegpt-1',\n",
" model: str = 'short-horizon',\n",
" n_windows: int = 1,\n",
" step_size: Optional[int] = None,\n",
" num_partitions: Optional[int] = None,\n",
Expand Down Expand Up @@ -448,7 +448,7 @@
" num_partitions=1,\n",
" id_col=id_col,\n",
" time_col=time_col,\n",
" model='timegpt-1',\n",
" model='short-horizon',\n",
" **fcst_kwargs\n",
" )\n",
" fcst_df = fa.as_pandas(fcst_df)\n",
Expand All @@ -458,7 +458,7 @@
" num_partitions=1,\n",
" id_col=id_col,\n",
" time_col=time_col,\n",
" model='timegpt-1-long-horizon',\n",
" model='long-horizon',\n",
" **fcst_kwargs\n",
" )\n",
" fcst_df_2 = fa.as_pandas(fcst_df_2)\n",
Expand Down Expand Up @@ -557,7 +557,7 @@
"def test_forecast_dataframe(df: fugue.AnyDataFrame):\n",
" test_cv_same_results_num_partitions(df, n_windows=2, step_size=1)\n",
" test_cv_same_results_num_partitions(df, n_windows=3, step_size=None, horizon=1)\n",
" test_cv_same_results_num_partitions(df, model='timegpt-1-long-horizon', horizon=1)\n",
" test_cv_same_results_num_partitions(df, model='long-horizon', horizon=1)\n",
" test_forecast_diff_results_diff_models(df)\n",
" test_forecast(df, num_partitions=1)\n",
" test_forecast(df, level=[90, 80], num_partitions=1)\n",
Expand Down Expand Up @@ -771,7 +771,7 @@
" num_partitions=1,\n",
" id_col=id_col,\n",
" time_col=time_col,\n",
" model='timegpt-1',\n",
" model='short-horizon',\n",
" **anomalies_kwargs\n",
" )\n",
" anomalies_df = fa.as_pandas(anomalies_df)\n",
Expand All @@ -780,7 +780,7 @@
" num_partitions=1,\n",
" id_col=id_col,\n",
" time_col=time_col,\n",
" model='timegpt-1-long-horizon',\n",
" model='long-horizon',\n",
" **anomalies_kwargs\n",
" )\n",
" anomalies_df_2 = fa.as_pandas(anomalies_df_2)\n",
Expand Down
111 changes: 76 additions & 35 deletions nbs/timegpt.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@
" clean_ex_first: bool = True,\n",
" date_features: Union[bool, List[str]] = False,\n",
" date_features_to_one_hot: Union[bool, List[str]] = True,\n",
" model: str = 'timegpt-1',\n",
" model: str = 'short-horizon',\n",
" max_retries: int = 6,\n",
" retry_interval: int = 10,\n",
" max_wait_time: int = 6 * 60,\n",
Expand Down Expand Up @@ -525,7 +525,7 @@
" \n",
" def set_model_params(self):\n",
" model_params = self._call_api(\n",
" self.client.timegpt_model_params,\n",
" self.client.model_params,\n",
" SingleSeriesForecast(freq=self.freq, model=self.model),\n",
" )\n",
" model_params = model_params['detail']\n",
Expand Down Expand Up @@ -589,7 +589,7 @@
" model=self.model,\n",
" )\n",
" response_timegpt = self._call_api(\n",
" self.client.timegpt_multi_series,\n",
" self.client.forecast_multi_series,\n",
" payload,\n",
" )\n",
" if 'weights_x' in response_timegpt:\n",
Expand All @@ -602,7 +602,7 @@
" main_logger.info('Calling Historical Forecast Endpoint...')\n",
" self.validate_input_size(Y_df=Y_df)\n",
" response_timegpt = self._call_api(\n",
" self.client.timegpt_multi_series_historic,\n",
" self.client.historic_forecast_multi_series,\n",
" MultiSeriesInsampleForecast(\n",
" y=y,\n",
" x=x,\n",
Expand Down Expand Up @@ -632,7 +632,7 @@
" main_logger.info('Calling Anomaly Detector Endpoint...')\n",
" y, x = self.dataframes_to_dict(Y_df, X_df)\n",
" response_timegpt = self._call_api(\n",
" self.client.timegpt_multi_series_anomalies,\n",
" self.client.anomaly_detection_multi_series,\n",
" MultiSeriesAnomaly(\n",
" y=y,\n",
" x=x,\n",
Expand Down Expand Up @@ -722,11 +722,21 @@
"#| exporti\n",
"def validate_model_parameter(func):\n",
" def wrapper(self, *args, **kwargs):\n",
" if 'model' in kwargs and kwargs['model'] not in self.supported_models:\n",
" raise ValueError(\n",
" f'unsupported model: {kwargs[\"model\"]} '\n",
" f'supported models: {\", \".join(self.supported_models)}'\n",
" )\n",
" if 'model' in kwargs:\n",
" model = kwargs['model']\n",
" rename_models_dict = {\n",
" 'timegpt-1': 'short-horizon',\n",
" 'timegpt-1-long-horizon': 'long-horizon',\n",
" }\n",
" if model in rename_models_dict.keys():\n",
" new_model = rename_models_dict[model]\n",
" warnings.warn(f\"'{model}' is deprecated; use '{new_model}' instead.\", FutureWarning)\n",
" model = new_model\n",
" if model not in self.supported_models:\n",
" raise ValueError(\n",
" f'unsupported model: {kwargs[\"model\"]} '\n",
" f'supported models: {\", \".join(self.supported_models)}'\n",
" )\n",
" return func(self, *args, **kwargs)\n",
" return wrapper"
]
Expand Down Expand Up @@ -842,7 +852,7 @@
" self.max_retries = max_retries\n",
" self.retry_interval = retry_interval\n",
" self.max_wait_time = max_wait_time\n",
" self.supported_models = ['timegpt-1', 'timegpt-1-long-horizon']\n",
" self.supported_models = ['short-horizon', 'long-horizon'] \n",
" # custom attr\n",
" self.weights_x: pd.DataFrame = None\n",
"\n",
Expand Down Expand Up @@ -880,7 +890,7 @@
" add_history: bool = False,\n",
" date_features: Union[bool, List[str]] = False,\n",
" date_features_to_one_hot: Union[bool, List[str]] = True,\n",
" model: str = 'timegpt-1',\n",
" model: str = 'short-horizon',\n",
" num_partitions: int = 1,\n",
" ):\n",
" if validate_token and not self.validate_token(log=False):\n",
Expand Down Expand Up @@ -924,7 +934,7 @@
" validate_token: bool = False,\n",
" date_features: Union[bool, List[str]] = False,\n",
" date_features_to_one_hot: Union[bool, List[str]] = True,\n",
" model: str = 'timegpt-1',\n",
" model: str = 'short-horizon',\n",
" num_partitions: int = 1,\n",
" ):\n",
" if validate_token and not self.validate_token(log=False):\n",
Expand Down Expand Up @@ -971,7 +981,7 @@
" clean_ex_first: bool = True,\n",
" date_features: Union[bool, List[str]] = False,\n",
" date_features_to_one_hot: Union[bool, List[str]] = True,\n",
" model: str = 'timegpt-1',\n",
" model: str = 'short-horizon',\n",
" num_partitions: int = 1,\n",
" ):\n",
" if validate_token and not self.validate_token(log=False):\n",
Expand Down Expand Up @@ -1151,7 +1161,7 @@
" add_history: bool = False,\n",
" date_features: Union[bool, List[str]] = False,\n",
" date_features_to_one_hot: Union[bool, List[str]] = True,\n",
" model: str = 'timegpt-1',\n",
" model: str = 'short-horizon',\n",
" num_partitions: Optional[int] = None,\n",
" ):\n",
" \"\"\"Forecast your time series using TimeGPT.\n",
Expand Down Expand Up @@ -1214,9 +1224,9 @@
" Apply one-hot encoding to these date features.\n",
" If `date_features=True`, then all date features are\n",
" one-hot encoded by default.\n",
" model : str (default='timegpt=1')\n",
" Model to use as a string. Options are: `timegpt-1`, and `timegpt-1-long-horizon`. \n",
" We recommend using `timegpt-1-long-horizon` for forecasting \n",
" model : str (default='short-horizon')\n",
" Model to use as a string. Options are: `short-horizon`, and `long-horizon`. \n",
" We recommend using `long-horizon` for forecasting \n",
" if you want to predict more than one seasonal \n",
" period given the frequency of your data.\n",
" num_partitions : int (default=None)\n",
Expand Down Expand Up @@ -1286,7 +1296,7 @@
" validate_token: bool = False,\n",
" date_features: Union[bool, List[str]] = False,\n",
" date_features_to_one_hot: Union[bool, List[str]] = True,\n",
" model: str = 'timegpt-1',\n",
" model: str = 'short-horizon',\n",
" num_partitions: Optional[int] = None,\n",
" ):\n",
" \"\"\"Detect anomalies in your time series using TimeGPT.\n",
Expand Down Expand Up @@ -1331,9 +1341,9 @@
" Apply one-hot encoding to these date features.\n",
" If `date_features=True`, then all date features are\n",
" one-hot encoded by default.\n",
" model : str (default='timegpt=1')\n",
" Model to use as a string. Options are: `timegpt-1`, and `timegpt-1-long-horizon`. \n",
" We recommend using `timegpt-1-long-horizon` for forecasting \n",
" model : str (default='short-horizon')\n",
" Model to use as a string. Options are: `short-horizon`, and `long-horizon`. \n",
" We recommend using `long-horizon` for forecasting \n",
" if you want to predict more than one seasonal \n",
" period given the frequency of your data.\n",
" num_partitions : int (default=None)\n",
Expand Down Expand Up @@ -1398,7 +1408,7 @@
" clean_ex_first: bool = True,\n",
" date_features: Union[bool, List[str]] = False,\n",
" date_features_to_one_hot: Union[bool, List[str]] = True,\n",
" model: str = 'timegpt-1',\n",
" model: str = 'short-horizon',\n",
" num_partitions: Optional[int] = None,\n",
" ):\n",
" \"\"\"Perform cross validation in your time series using TimeGPT.\n",
Expand Down Expand Up @@ -1461,9 +1471,9 @@
" Apply one-hot encoding to these date features.\n",
" If `date_features=True`, then all date features are\n",
" one-hot encoded by default.\n",
" model : str (default='timegpt=1')\n",
" Model to use as a string. Options are: `timegpt-1`, and `timegpt-1-long-horizon`. \n",
" We recommend using `timegpt-1-long-horizon` for forecasting \n",
" model : str (default='short-horizon')\n",
" Model to use as a string. Options are: `short-horizon`, and `long-horizon`. \n",
" We recommend using `long-horizon` for forecasting \n",
" if you want to predict more than one seasonal \n",
" period given the frequency of your data.\n",
" num_partitions : int (default=None)\n",
Expand Down Expand Up @@ -1629,7 +1639,7 @@
"#| hide\n",
"# test input_size\n",
"test_eq(\n",
" timegpt.client.timegpt_model_params(request=SingleSeriesForecast(freq='D'))['data']['detail'],\n",
" timegpt.client.model_params(request=SingleSeriesForecast(freq='D'))['data']['detail'],\n",
" {'input_size': 28, 'horizon': 7},\n",
")"
]
Expand Down Expand Up @@ -1659,10 +1669,34 @@
"outputs": [],
"source": [
"#| hide\n",
"# test finetune deprecation\n",
"# test model change\n",
"df_test = df.copy()\n",
"df_test.columns = [\"ds\", \"y\"]\n",
"test_warns(\n",
" lambda: timegpt.forecast(df_test, finetune_steps=2, h=12, model=\"timegpt-1\"),\n",
")\n",
"test_warns(\n",
" lambda: timegpt.forecast(df_test, finetune_steps=2, h=12, model=\"timegpt-1-long-horizon\"),\n",
")\n",
"test_eq(\n",
" timegpt.forecast(df_test, h=12, model=\"timegpt-1\"),\n",
" timegpt.forecast(df_test, h=12),\n",
")\n",
"test_eq(\n",
" timegpt.forecast(df_test, h=12, model=\"timegpt-1-long-horizon\"),\n",
" timegpt.forecast(df_test, h=12, model=\"long-horizon\"),\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test finetune deprecation\n",
"test_warns(\n",
" lambda: timegpt.forecast(df_test, finetune_steps=2, h=12),\n",
")\n",
"test_warns(\n",
Expand Down Expand Up @@ -1848,7 +1882,7 @@
" max_wait_time=max_wait_time,\n",
" )\n",
" init_time = time()\n",
" with patch('nixtlats.client.Nixtla.timegpt_multi_series', side_effect=side_effect):\n",
" with patch('nixtlats.client.Nixtla.forecast_multi_series', side_effect=side_effect):\n",
" test_fail(\n",
" lambda: mock_timegpt.forecast(df=df, h=12, time_col='timestamp', target_col='value'),\n",
" )\n",
Expand Down Expand Up @@ -2028,8 +2062,8 @@
" df=df_freq,\n",
" h=h,\n",
" )\n",
" fcst_1_df = test_equal_fcsts_add_history(**{**kwargs, 'model': 'timegpt-1'})\n",
" fcst_2_df = test_equal_fcsts_add_history(**{**kwargs, 'model': 'timegpt-1-long-horizon'})\n",
" fcst_1_df = test_equal_fcsts_add_history(**{**kwargs, 'model': 'short-horizon'})\n",
" fcst_2_df = test_equal_fcsts_add_history(**{**kwargs, 'model': 'long-horizon'})\n",
" test_fail(\n",
" lambda: pd.testing.assert_frame_equal(fcst_1_df, fcst_2_df),\n",
" contains='(column name=\"TimeGPT\") are different',\n",
Expand Down Expand Up @@ -2088,9 +2122,9 @@
"source": [
"#| hide\n",
"# test different results for different models\n",
"fcst_kwargs['model'] = 'timegpt-1'\n",
"fcst_kwargs['model'] = 'short-horizon'\n",
"fcst_timegpt_1 = timegpt.forecast(**fcst_kwargs)\n",
"fcst_kwargs['model'] = 'timegpt-1-long-horizon'\n",
"fcst_kwargs['model'] = 'long-horizon'\n",
"fcst_timegpt_long = timegpt.forecast(**fcst_kwargs)\n",
"test_fail(\n",
" lambda: pd.testing.assert_frame_equal(fcst_timegpt_1[['TimeGPT']], fcst_timegpt_long[['TimeGPT']]),\n",
Expand All @@ -2107,9 +2141,9 @@
"#| hide\n",
"# test different results for different models\n",
"# anomalies\n",
"anomalies_kwargs['model'] = 'timegpt-1'\n",
"anomalies_kwargs['model'] = 'short-horizon'\n",
"anomalies_timegpt_1 = timegpt.detect_anomalies(**anomalies_kwargs)\n",
"anomalies_kwargs['model'] = 'timegpt-1-long-horizon'\n",
"anomalies_kwargs['model'] = 'long-horizon'\n",
"anomalies_timegpt_long = timegpt.detect_anomalies(**anomalies_kwargs)\n",
"test_fail(\n",
" lambda: pd.testing.assert_frame_equal(anomalies_timegpt_1[['TimeGPT']], anomalies_timegpt_long[['TimeGPT']]),\n",
Expand Down Expand Up @@ -2548,6 +2582,13 @@
"source": [
"show_doc(TimeGPT.detect_anomalies, title_level=2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down
6 changes: 3 additions & 3 deletions nixtlats/distributed/timegpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def forecast(
add_history: bool = False,
date_features: Union[bool, List[str]] = False,
date_features_to_one_hot: Union[bool, List[str]] = True,
model: str = "timegpt-1",
model: str = "short-horizon",
num_partitions: Optional[int] = None,
) -> fugue.AnyDataFrame:
kwargs = dict(
Expand Down Expand Up @@ -182,7 +182,7 @@ def detect_anomalies(
validate_token: bool = False,
date_features: Union[bool, List[str]] = False,
date_features_to_one_hot: Union[bool, List[str]] = True,
model: str = "timegpt-1",
model: str = "short-horizon",
num_partitions: Optional[int] = None,
) -> fugue.AnyDataFrame:
kwargs = dict(
Expand Down Expand Up @@ -225,7 +225,7 @@ def cross_validation(
validate_token: bool = False,
date_features: Union[bool, List[str]] = False,
date_features_to_one_hot: Union[bool, List[str]] = True,
model: str = "timegpt-1",
model: str = "short-horizon",
n_windows: int = 1,
step_size: Optional[int] = None,
num_partitions: Optional[int] = None,
Expand Down
Loading

0 comments on commit 0e56620

Please sign in to comment.