Documentation :open_book:

April 6, 2025 · View on GitHub

Setup

ProbTS is developed with Python 3.10 and relies on PyTorch Lightning. To set up the environment:

# Create a new conda environment
conda create -n probts python=3.10
conda activate probts

# Install required packages
pip install .
pip uninstall -y probts # recommended to uninstall the root package (optional)

[Optional] For time-series foundation models, you need to install basic packages and additional dependencies:

# Create a new conda environment
conda create -n probts_fm python=3.10
conda activate probts_fm

# Git submodule
git submodule update --init --recursive

# Install additional packages for foundation models
pip install ".[tsfm]"
pip uninstall -y probts # recommended to uninstall the root package (optional)

# For MOIRAI, we fix the version of the package for better performance
cd submodules/uni2ts
git reset --hard fce6a6f57bc3bc1a57c7feb3abc6c7eb2f264301
Optional for TSFMs reproducibility
# For TimesFM, fix the version for reproducibility (optional)
cd submodules/timesfm
git reset --hard 5c7b905

# For Lag-Llama, fix the version for reproducibility (optional)
cd submodules/lag_llama
git reset --hard 4ad82d9

# For TinyTimeMixer, fix the version for reproducibility (optional)
cd submodules/tsfm
git reset --hard bb125c14a05e4231636d6b64f8951d5fe96da1dc

Configuration Parameters

  • To print the full pipeline configuration to a file:

    python run.py --print_config > config/pipeline_config.yaml
    

Trainer

Config NameTypeDescription
trainer.max_epochsintMaximum number of training epochs.
trainer.limit_train_batchesintLimits the number of training batches per epoch.
trainer.check_val_every_n_epochintPerform validation every n training epochs.
trainer.default_root_dirintDefault path for logs and weights.
trainer.accumulate_grad_batchesintNumber of batches to accumulate gradients before updating.

Model

Config NameTypeDescription
model.forecaster.class_pathstrForecaster module path (e.g., probts.model.forecaster.point_forecaster.PatchTST).
model.forecaster.init_args.{ARG}-Model-specific hyperparameters.
model.num_samplesintNumber of samples per distribution during evaluation.
model.learning_ratefloatLearning rate.
model.quantiles_numintNumber of quantiles for evaluation.
model.sampling_weight_schemestrThe scheme of training horizon reweighting. Options: ['random', 'none', 'const'].
model.optimizer_config.class_namestroptimizer module (e.g., torch.optim.Adam).
model.optimizer_config.init_args.{ARG}-optimizer hyperparameters.
model.scheduler_config.class_namestrlr_scheduler module (e.g., torch.optim.lr_scheduler.OneCycleLR).
model.scheduler_config.init_args.{ARG}-lr_scheduler hyperparameters.

Data

Config NameTypeDescription
data.data_manager.init_args.datasetstrDataset for training and evaluation.
data.data_manager.init_args.pathstrPath to the dataset folder.
data.data_manager.init_args.split_valboolWhether to split a validation set during training.
data.data_manager.init_args.scalerstrScaler type: identity, standard (z-score normalization), or temporal (scale based on average temporal absolute value).
data.data_manager.init_args.target_dimintThe number of variates.
data.data_manager.init_args.var_specific_normboolIf conduct per-variate normalization or not.
data.data_manager.init_args.timeencintTime feature type. Select from [0,1,2]. See the explaination below for details.
data.data_manager.init_args.context_lengthUnion[str, int, list]Length of observation window in inference phase.
data.data_manager.init_args.prediction_lengthUnion[str, int, list]Forecasting horizon length in inference phase.
data.data_manager.init_args.val_pred_len_listUnion[str, int, list]Forecasting horizon length for performance validation.
data.data_manager.init_args.val_ctx_lenUnion[str, int, list]Forecasting horizons for performance validation.
data.data_manager.init_args.train_pred_len_listUnion[str, int, list]Length of observation window in training phase.
data.data_manager.init_args.train_ctx_lenUnion[str, int, list]Forecasting horizons in training phase.
data.data_manager.init_args.continuous_sampleboolIf True, sampling horizons from [min(train_pred_len_list), max(train_pred_len_list)], else sampling within the set train_pred_len_list.
data.data_manager.init_args.test_rolling_lengthintint or str
data.data_manager.init_args.train_ratiofloatSpecifies proportion of the dataset used for training. Default value is 0.7.
data.data_manager.init_args.test_ratiofloatSpecifies proportion of the dataset used for training. Default value is 0.2.
data.batch_sizeintBatch size.

Temporal Features

For the datasets used for long-term forecasting scenario, we support three types of time feature encoding

--data.data_manager.init_args.timeenc {the encoding type} # select from [0,1,2]
  • [timeenc 0] temporal information

    The dimension of time feature is 5, containing month, day, weekday, hour, minute.

  • [timeenc 1] time feature based on frequency Extract time feature using time_features_from_frequency_str() function. The dimensionality follows:

    freq_map = {'h': 4, 't': 5, 's': 6, 'm': 1, 'a': 1, 'w': 2, 'd': 3, 'b': 3}
    

    Note: timeenc = 0 if model.embed != 'timeF' else 1.

  • [timeenc 2] Raw date information

    The dimension of time feature is 5, using the following code to recover it to date data type:

    data_stamp = batch_data.past_time_feat.cpu().numpy().astype('datetime64[s]')
    data_stamp = batch_data.future_time_feat.cpu().numpy().astype('datetime64[s]')
    

Datasets

Datasets Overview

Short-Term Setting

DatasetDATASET_NAMEDomainFrequency#Vartime stepsDescription
Exchangeexchange_rate_nipsFinanceBusi. Day86,071Daily exchange rates of 8 countries
Solarsolar_nipsEnergyH1377,009Solar power production records
Electricityelectricity_nipsEnergyH3705,833Electricity consumption
Traffictraffic_nipsTransportH9634,001Road occupancy rates
Wikipediawiki2000_nipsWebD2,000792Page views of 2000 Wikipedia pages

Long-Term Setting

DatasetDATASET_NAMEDomainFrequency#Vartime stepsDescription
ETThetth1 / etth2EnergyH717,420Electricity transformer temperature per hour
ETTmettm1 / ettm2Energy15min769,680Electricity transformer temperature every 15 min
Electricityelectricity_lstfEnergyH32126,304Electricity consumption (Kwh)
Weatherweather_lstfClimate10min2152,696Local climatological data
Traffictraffic_ltsfTransportH86217,544Road occupancy rates
Exchangeexchange_ltsfFinanceBusi. Day87,588Daily exchange rates of 8 countries
ILIillness_ltsfEpidemiologyW7966Ratio of patients seen with influenza-like illness
CaisocaisoEnergyH1074,472Electricity load series in different zones of California
NordpoolnordpoolEnergyH1870,128Energy production volume in European countries
Turkey Powerturkey_powerEnergyH1826,304Electrical power demand in Turkey
Istanbul Trafficistanbul_trafficTransportH314,244Traffic Index data for Istanbul traffic

Data Processing Pipeline

Using Build-in Datasets

  • Short-Term Forecasting: We use datasets from GluonTS. Configure the datasets using --data.data_manager.init_args.dataset {DATASET_NAME} with available DATASET_NAME in short-term setting.

  • Long-Term Forecasting: To download the long-term forecasting datasets, please follow these steps:

    bash scripts/prepare_datasets.sh "./datasets"
    

    Configure the datasets using --data.data_manager.init_args.dataset {DATASET_NAME} with available DATASET_NAME in long-term setting.

    Note: When utilizing long-term forecasting datasets, you must explicitly specify the context_length and prediction_length parameters. For example, to set a context length of 96 and a prediction length of 192, use the following command-line arguments:

    --data.data_manager.init_args.context_length 96 \
    --data.data_manager.init_args.prediction_length 192 \
    
  • Using Datasets from Monash Time Series Forecasting Repository: To use datasets from the Monash Time Series Forecasting Repository, follow these steps:

    1. Download the Dataset:
    • Navigate to the target dataset, such as the Electricity Hourly Dataset.
    • Download the .tsf file and place it in your local datasets directory (e.g., ./datasets).
    1. Configure the Dataset:
    • Use the following configuration to specify the dataset, file path, and frequency:

      --data.data_manager.init_args.dataset {DATASET_NAME} \
      --data.data_manager.init_args.data_path /path/to/data.csv \
      --data.data_manager.init_args.freq {FREQ} 
      
    • Example Configuration:

      --data.data_manager.init_args.dataset monash_electricity_hourly \
      --data.data_manager.init_args.data_path ./datasets/electricity_hourly_dataset.tsf \
      --data.data_manager.init_args.freq H \
      --data.data_manager.init_args.context_length 96 \
      --data.data_manager.init_args.prediction_length 96 \
      --data.data_manager.init_args.multivariate true
      

    Note: Refer to the Pandas Time Series Offset Aliases for the correct frequency values ({FREQ}) to use in your configuration.

  • Using Datasets from GIFT-EVAL Benchmarking: see this page for detailed instructions.

Using Customized Dataset

  1. Prepare the Data:
  • Format your dataset as a .csv file with the following structure:

    dateVAR1VAR2...
    2013-01-01 00:00:002611.01539.0...
    2013-01-01 01:00:002132.01535.0...

    Note1: The date column represents timestamps.

    Note2: VAR1, VAR2, etc., represent different variables (features) for each timestamp.

  • Place the csv file in your local datasets directory (e.g., ./datasets).

  1. Configure the Dataset:
  • Use the following configuration to specify the dataset, file path, and frequency:

    --data.data_manager.init_args.dataset {DATASET_NAME} \
    --data.data_manager.init_args.data_path /path/to/data_file.tsf \
    --data.data_manager.init_args.freq {FREQ} 
    
  • Example Configuration:

    --data.data_manager.init_args.dataset my_data \
    --data.data_manager.init_args.data_path ./datasets/my_data.csv \
    --data.data_manager.init_args.freq H \
    --data.data_manager.init_args.context_length 96 \
    --data.data_manager.init_args.prediction_length 96 \
    --data.data_manager.init_args.multivariate true
    

Note: You can adjust the test instance sampling using the --data.data_manager.init_args.test_rolling_length parameter.

Model

Available Models

ProbTS includes both classical time-series models, specializing in long-term point forecasting or short-term distributional forecasting, and recent time-series foundation models that offer zero-shot and arbitrary-horizon forecasting capabilities for new time series.

Classical Time-series Models

ModelOriginal Eval. HorizonEstimationDecoding SchemeClass Path
Linear-PointAuto / Non-autoprobts.model.forecaster.point_forecaster.LinearForecaster
GRU-PointAuto / Non-autoprobts.model.forecaster.point_forecaster.GRUForecaster
Transformer-PointAuto / Non-autoprobts.model.forecaster.point_forecaster.TransformerForecaster
AutoformerLong-tremPointNon-autoprobts.model.forecaster.point_forecaster.Autoformer
N-HiTSLong-tremPointNon-autoprobts.model.forecaster.point_forecaster.NHiTS
NLinearLong-tremPointNon-autoprobts.model.forecaster.point_forecaster.NLinear
DLinearLong-tremPointNon-autoprobts.model.forecaster.point_forecaster.DLinear
TSMixerLong-tremPointNon-autoprobts.model.forecaster.point_forecaster.TSMixer
TimesNetShort- / Long-termPointNon-autoprobts.model.forecaster.point_forecaster.TimesNet
PatchTSTLong-tremPointNon-autoprobts.model.forecaster.point_forecaster.PatchTST
iTransformerLong-tremPointNon-autoprobts.model.forecaster.point_forecaster.iTransformer
ElasTSTLong-tremPointNon-autoprobts.model.forecaster.point_forecaster.ElasTST
GRU NVPShort-termProbabilisticAutoprobts.model.forecaster.prob_forecaster.GRU_NVP
GRU MAFShort-termProbabilisticAutoprobts.model.forecaster.prob_forecaster.GRU_MAF
Trans MAFShort-termProbabilisticAutoprobts.model.forecaster.prob_forecaster.Trans_MAF
TimeGradShort-termProbabilisticAutoprobts.model.forecaster.prob_forecaster.TimeGrad
CSDIShort-termProbabilisticNon-autoprobts.model.forecaster.prob_forecaster.CSDI
TSDiffShort-termProbabilisticNon-autoprobts.model.forecaster.prob_forecaster.TSDiffCond

Fundation Models

ModelAny HorizonEstimationDecoding SchemeClass PathModel Size
Lag-LlamaProbabilisticARprobts.model.forecaster.prob_forecaster.LagLlama-
ForecastPFNPointNARprobts.model.forecaster.point_forecaster.ForecastPFN-
TimesFMPointARprobts.model.forecaster.point_forecaster.TimesFM200m, 500m
TTMPointNARprobts.model.forecaster.point_forecaster.TinyTimeMixer-
TimerPointARprobts.model.forecaster.point_forecaster.Timer-
MOIRAIProbabilisticNARprobts.model.forecaster.prob_forecaster.Moiraismall, base, large
UniTSPointNARprobts.model.forecaster.point_forecaster.UniTS-
ChronosProbabilisticARprobts.model.forecaster.prob_forecaster.Chronostiny, mini, small, base, large
Time-MoEPointARprobts.model.forecaster.point_forecaster.TimeMoE50M, 200M

See the tsfm configuration directory for more details. More models will be added soon—stay tuned!

Using Customized Model

With our platform, you can easily evaluate customized models across various datasets. Follow the steps below to create and evaluate your model.

Step 1: Create a New Python File

Create a new Python file and follow the structure below to define your custom model:

from probts.model.forecaster import Forecaster

class ModelName(Forecaster):
    def __init__(
        self,
        **kwargs
    ):
        """
        Initialize the model with parameters.
        """
        super().__init__(**kwargs)
        # Initialize model parameters here

    def forward(self, inputs):
        """
        Forward pass for the model.

        Parameters:
        inputs [Tensor]: Input tensor for the model.

        Returns:
        Tensor: Output tensor.
        """
        # Perform the forward pass of the model
        return outputs

    def loss(self, batch_data):
        """
        Compute the loss for the given batch data.

        Parameters:
        batch_data [dict]: Dictionary containing input data and possibly target data.

        Returns:
        Tensor: Computed loss.
        """
        # Extract inputs and targets from batch_data
        inputs = batch_data.past_target_cdf[:, -self.context_length:, :] # [batch_size, context_length, var_num]
        target = batch_data.future_target_cdf # [batch_size, prediction_length, var_num]

        # Forward pass
        outputs = self.forward(inputs)
        
        # Calculate loss using a loss function, e.g., Mean Squared Error
        loss = self.loss_function(outputs, future_target_cdf)

        return loss

    def forecast(self, batch_data, num_samples=None):
        """
        Generate forecasts for the given batch data.

        Parameters:
        batch_data [dict]: Dictionary containing input data.
        num_samples [int, optional]: Number of samples per distribution during evaluation. Defaults to None.

        Returns:
        Tensor: Forecasted outputs.
        """
        # Perform the forward pass to get the outputs
        outputs = self(batch_data.past_target_cdf[:, -self.context_length:, :])

        if num_samples is not None:
            # If num_samples is specified, use it to sample from the distribution
            outputs = self.sample_from_distribution(outputs, num_samples)
        else: 
            # If perform point estimation, the num_samples is equal to 1
            outputs = outputs.unsqueeze(1)
        return outputs # [batch_size, num_samples, prediction_length, var_num]

Input Data Format

The batch_data dictionary contains several fields that provide necessary information for the model's operation. Each field is described below:

  • target_dimension_indicator:

    • Shape: [var_num]
    • Description: Indicator that specifies which dimension or feature of the target is being referenced.
  • {past|future}_time_feat:

    • Shape: [batch_size,length,time_feature_dim]
    • Description: Time features associated with each time step in the past or future. This can include various time-related information such as timestamps, seasonal indicators (e.g., month, day of the week), or other temporal features that provide context to the observations.
  • {past|future}_target_cdf:

    • Shape: [batch_size,length,var_num]
    • Description: The observation values of the target variable(s) for past or future time steps.
  • {past|future}_observed_values:

    • Shape: [batch_size,length,var_num]
    • Description: Binary masks indicating which values in the past or future target data are observed (1) and which are missing or unobserved (0).

Step 2: Create YAML Configuration File

Create a YAML configuration file (model.yaml) for the customized model:

seed_everything: 1 # random seed
trainer:
  accelerator: gpu
  devices: 1
  strategy: auto
  max_epochs: 50
  use_distributed_sampler: false
  limit_train_batches: 100
  log_every_n_steps: 1
  default_root_dir: ./results # path to the log folder
model:
  forecaster:
    class_path: class.path.to.ModelName
    init_args:
      # init your hyperparameter here
  learning_rate: 0.001 # learning rate
data:
  data_manager:
    class_path: probts.data.data_manager.DataManager
    init_args:
      dataset: solar_nips # dataset name
      split_val: true
      scaler: standard # identity, standard, temporal
  batch_size: 32
  test_batch_size: 32
  num_workers: 8

Step 3: Run the Customized Model

Run the customized model using the configuration file:

python run.py --config config/path/to/model.yaml

Training

Configuring Optimizers and Learning Rate Schedulers

ProbTS supports customizable optimizers and learning rate schedulers. You can specify them directly in the YAML configuration file.

Example Configuration

model:
  forecaster:
    class_path: probts.model.forecaster.point_forecaster.PatchTST
    init_args:
      # Add forecaster-specific parameters here

  optimizer_config:
    class_name: torch.optim.Adam
    init_args:
      weight_decay: 0  # Add optimizer-specific parameters here

  lr_scheduler_config:
    class_name: torch.optim.lr_scheduler.OneCycleLR
    init_args:
      max_lr: 0.0001
      steps_per_epoch: 100
      pct_start: 0.3
      epochs: 50  # Add scheduler-specific parameters here

Example configurations can be found in config/default/patchtst.yaml.

Notes

  • If no configuration is provided, ProbTS defaults to the Adam optimizer with a constant learning rate.
  • Adjust init_args for both the optimizer and scheduler to suit your specific use case.

Forecasting with Varied Prediction Lengths

Example:

python run.py --config config/multi_hor/elastst.yaml \
                --data.data_manager.init_args.path ./datasets \
                --trainer.default_root_dir /path/to/log_dir/ \
                --data.data_manager.init_args.dataset {DATASET_NAME} \
                --data.data_manager.init_args.context_length ${TEST_CTX_LEN} \
                --data.data_manager.init_args.prediction_length ${TEST_PRED_LEN} \
                --data.data_manager.init_args.train_ctx_len ${TRAIN_CTX_LEN} \
                --data.data_manager.init_args.train_pred_len_list ${TRAIN_PRED_LEN} \
                --data.data_manager.init_args.val_ctx_len ${VAL_CTX_LEN} \
                --data.data_manager.init_args.val_pred_len_list ${VAL_PRED_LEN} 
  • DATASET_NAME: Select from datasets used in long-term forecasting scenerios.
  • TEST_CTX_LEN: Context length in the testing phase.
  • VAL_CTX_LEN (Default: TEST_CTX_LEN): Context length in the validation phase.
  • TRAIN_CTX_LEN (Default: TEST_CTX_LEN): Context length in the training phase.
  • TEST_PRED_LEN: Forecasting horizons in the testing phase.
  • VAL_PRED_LEN (Default: TEST_PRED_LEN): Forecasting horizons for performance validation.
  • TRAIN_PRED_LEN (Default: TEST_PRED_LEN): Forecasting horizons in the training phase.

The results across multiple horizons will be saved to:

/path/to/log_dir/{DATASET_NAME}_{MODEL}_{seed}_TrainCTX_{TRAIN_CTX_LEN}_TrainPRED_{TRAIN_PRED_LEN}_ValCTX_{CTX_LEN}_ValPRED_{VAL_PRED_LEN}/horizons_results.csv

Example 1: Varied-Horizon Training

Mode 1: Random sampling from a set of horizons

python run.py --config config/multi_hor/elastst.yaml \
                --data.data_manager.init_args.path ./datasets \
                --trainer.default_root_dir /path/to/log_dir/ \
                --data.data_manager.init_args.dataset ${DATASET} \
                --data.data_manager.init_args.context_length 96 \
                --data.data_manager.init_args.prediction_length 720 \
                --data.data_manager.init_args.train_ctx_len 96 \
                --data.data_manager.init_args.val_pred_len_list 720 \
                # random selection from {96, 192, 336, 720}
                --data.data_manager.init_args.train_pred_len_list 96-192-336-720 \
                --data.data_manager.init_args.continuous_sample false 

Mode 2: Random sampling from a horizon range

python run.py --config config/multi_hor/elastst.yaml \
                --data.data_manager.init_args.path ./datasets \
                --trainer.default_root_dir /path/to/log_dir/ \
                --data.data_manager.init_args.dataset ${DATASET} \
                --data.data_manager.init_args.context_length 96 \
                --data.data_manager.init_args.prediction_length 720 \
                --data.data_manager.init_args.train_ctx_len 96 \
                --data.data_manager.init_args.val_pred_len_list 720 \
                # random sampling from [1, 720]
                --data.data_manager.init_args.train_pred_len_list 1-720 \ 
                --data.data_manager.init_args.continuous_sample true 

Example 2: Validation and Testing with Multiple Horizons

python run.py --config config/multi_hor/elastst.yaml \
                --data.data_manager.init_args.path ./datasets \
                --trainer.default_root_dir /path/to/log_dir/ \
                --data.data_manager.init_args.dataset ${DATASET} \
                --data.data_manager.init_args.context_length 96 \
                --data.data_manager.init_args.train_pred_len_list 720 \ 
                --data.data_manager.init_args.train_ctx_len 96 \
                # validation on {96, 192, 336, 720}
                --data.data_manager.init_args.val_pred_len_list 96-192-336-720 \
                # testing on {24, 96, 192, 336, 720, 1024}
                --data.data_manager.init_args.prediction_length 24-96-192-336-720-1024