A Practical Approach to Time Series Forecasting with APDTFlow
Last Updated on February 10, 2025 by Editorial Team
Author(s): Yotam Braun
Originally published on Towards AI.
Introduction
Forecasting time series data is quite different from handling a typical regression or classification task. With sequential dependencies, seasonal effects, and non stationary behavior, these datasets demand a modeling approach that truly understands time. Researchers have explored a variety of approaches over the years from classical statistical methods to deep learning architectures to tackle these challenges.
We built APDTFlow specifically to address these challenges. By combining multiple cuttingβedge techniques into a modular system, you have the freedom to explore various modeling options while keeping the process transparent and flexible no rigid black boxes here.
GitHub – yotambraun/APDTFlow: APDTFlow: A Modular Forecasting Framework for Time Series Data
APDTFlow: A Modular Forecasting Framework for Time Series Data – yotambraun/APDTFlow
github.com
Why a New Approach to Time Series Forecasting?
Many standard forecasting methods assume that each feature is independent or ignore the sequential nature of the data entirely. While some methods capture longβterm trends, they often miss out on shortβterm fluctuations; others are so specialized that extending them becomes a challenge.
Hereβs how we designed APDTFlow to overcome these challenges:
- We break down the input into multiple scales, capturing both broad trends and fine details.
- We use Neural ODEs to model the smooth evolution of hidden states over time, ensuring continuity in our forecasts.
- Our process is split into clear, manageable steps from decomposition right through to prediction so you always know whatβs happening behind the scenes.
- And with built in tools for data processing, flexible crossβvalidation, evaluation metrics, and a CLI, APDTFlow is ready for both experimental and realβworld applications.
Core Components of APDTFlow
APDTFlow is constructed from several key modules that work together to produce reliable forecasts.
1. MultiβScale Decomposition
We start by decomposing the input series into multiple scales. This lets the model capture broad, slowβmoving trends as well as the quicker, seasonal fluctuations that can occur in real data:
- Global trends: Slowβchanging components that represent the overall direction.
- Local fluctuations: The shortβterm variations that might reflect seasonal patterns or sudden shifts.
2. Hierarchical Neural Dynamics
For every scale, we use Neural ODEs to capture the smooth evolution of hidden states. This approach not only handles irregular time steps gracefully but also adapts as the underlying dynamics shift over time:
- Handling Irregularities: Interpolating between observations in datasets with irregular time steps.
- Modeling NonβStationarity: Capturing gradual changes in the dynamics over time.
3. Probabilistic Scale Fusion
Once the different scales have been processed, their latent representations are combined using a probabilistic fusion mechanism. This step:
- Integrates MultiβResolution Information: Merges insights from various scales.
- Quantifies Uncertainty: Provides a measure of confidence in the predictions, which is crucial for risk-sensitive applications.
4. TimeβAware Transformer Decoder
The final step is decoding the fused latent state into forecasts. A Transformerβbased decoder is used here because:
- Temporal Order is Preserved: Positional encodings ensure that the sequential order of the data is taken into account.
- Complex Dependencies are Captured: The selfβattention mechanism in transformers effectively models longβterm dependencies.
For more details on the model components, check out the models documentation.
Additional Functionalities
But thereβs more to APDTFlow than just the forecasting engine. Weβve also integrated practical features to help you work with realβworld data from flexible crossβvalidation to a user-friendly CLI.
CrossβValidation Factory
Getting the evaluation right for time series data means you need to split your data thoughtfully this is why we built in flexible crossβvalidation tools. The TimeSeriesCVFactory in APDTFlow supports:
- Rolling Splits: Emulating a moving window over time.
- Expanding Splits: Increasing the training set gradually while keeping the validation set size fixed.
- Blocked Splits: Dividing the data into contiguous segments for training and testing.
Example Code
from apdtflow.cv_factory import TimeSeriesCVFactory
from torch.utils.data import Dataset
class SampleDataset(Dataset):
def __init__(self, length=100):
self.data = list(range(length))
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
return self.data[idx]
dataset = SampleDataset()
cv_factory = TimeSeriesCVFactory(dataset, method="rolling", train_size=40, val_size=10, step_size=10)
splits = cv_factory.get_splits()
print("Cross-Validation Splits:", splits)
Evaluation Framework
For consistent performance comparisons, APDTFlow includes tools to compute standard metrics such as:
- Mean Squared Error (MSE)
- Mean Absolute Error (MAE)
- Root Mean Squared Error (RMSE)
- Mean Absolute Percentage Error (MAPE)
Example Code for Evaluation
metrics = model.evaluate(test_loader, device, metrics=["MSE", "MAE", "RMSE", "MAPE"])
print("Evaluation Metrics:", metrics)
CommandβLine Interface (CLI)
To simplify operations, APDTFlow includes a CLI that allows you to train models and run inference directly from the terminal. This is especially useful for quick tests or for integrating forecasting into a larger workflow.
Example CLI Commands
# Train a model
apdtflow train --csv_file path/to/dataset.csv --date_col DATE --value_col VALUE --T_in 12 --T_out 3 --num_scales 3 --filter_size 5 --hidden_dim 16 --batch_size 16 --learning_rate 0.001 --num_epochs 15 --checkpoint_dir ./checkpoints
# Run inference using a saved checkpoint
apdtflow infer --csv_file path/to/dataset.csv --date_col DATE --value_col VALUE --T_in 12 --T_out 3 --checkpoint_path ./checkpoints/APDTFlow_checkpoint.pt --batch_size 16
Training and Inference Demonstration
Hereβs how you can train the APDTFlow model on your data and then use it to make predictions.
Training Example
import torch
from torch.utils.data import DataLoader
from apdtflow.data import TimeSeriesWindowDataset
from apdtflow.models.apdtflow import APDTFlow
# Prepare the dataset
dataset = TimeSeriesWindowDataset(
csv_file="path/to/dataset.csv",
date_col="DATE",
value_col="VALUE",
T_in=12, # Number of historical time steps
T_out=3 # Forecast horizon
)
train_loader = DataLoader(dataset, batch_size=16, shuffle=True)
# Initialize the APDTFlow model
model = APDTFlow(
num_scales=3,
input_channels=1,
filter_size=5,
hidden_dim=16,
output_dim=1,
forecast_horizon=3
)
# Set device and train the model
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
model.train_model(
train_loader=train_loader,
num_epochs=15,
learning_rate=0.001,
device=device
)
Inference Example
import torch
from torch.utils.data import DataLoader
from apdtflow.data import TimeSeriesWindowDataset
from apdtflow.models.apdtflow import APDTFlow
# Prepare the dataset for inference
test_dataset = TimeSeriesWindowDataset(
csv_file="path/to/dataset.csv",
date_col="DATE",
value_col="VALUE",
T_in=12,
T_out=3
)
test_loader = DataLoader(test_dataset, batch_size=16, shuffle=False)
# Initialize the model and load a checkpoint
model = APDTFlow(
num_scales=3,
input_channels=1,
filter_size=5,
hidden_dim=16,
output_dim=1,
forecast_horizon=3
)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
checkpoint_path = "path/to/checkpoint.pt"
model.load_state_dict(torch.load(checkpoint_path, map_location=device))
# Run inference
predictions, pred_logvars = model.predict(new_x, forecast_horizon=3, device=device)
print("Predictions:", predictions)
Additional Forecasting Approaches
While APDTFlow is the primary model in the framework, it also includes other forecasting approaches. Depending on your dataset and needs, you may prefer one of these alternatives.
TransformerForecaster
The TransformerForecaster leverages the Transformer architecture to capture long-range dependencies via selfβattention. It is well-suited for modeling complex temporal interactions over extended sequences.
Example Code
import torch
from torch.utils.data import DataLoader
from apdtflow.data import TimeSeriesWindowDataset
from apdtflow.models.transformer_forecaster import TransformerForecaster
dataset = TimeSeriesWindowDataset(
csv_file="path/to/dataset.csv",
date_col="DATE",
value_col="VALUE",
T_in=12,
T_out=3
)
train_loader = DataLoader(dataset, batch_size=16, shuffle=True)
model = TransformerForecaster(
input_dim=1,
model_dim=32,
num_layers=2,
nhead=4,
forecast_horizon=3
)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
TCNForecaster
The TCNForecaster employs Temporal Convolutional Networks (TCNs) to capture local temporal patterns efficiently. TCNs use dilated convolutions, which allow them to cover a large receptive field without requiring many layers.
Example Code
import torch
from torch.utils.data import DataLoader
from apdtflow.data import TimeSeriesWindowDataset
from apdtflow.models.tcn_forecaster import TCNForecaster
dataset = TimeSeriesWindowDataset(
csv_file="path/to/dataset.csv",
date_col="DATE",
value_col="VALUE",
T_in=12,
T_out=3
)
train_loader = DataLoader(dataset, batch_size=16, shuffle=True)
model = TCNForecaster(
input_channels=1,
num_channels=[32, 32],
kernel_size=5,
forecast_horizon=3
)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
EnsembleForecaster
The EnsembleForecaster combines predictions from multiple models (such as APDTFlow, TransformerForecaster, and TCNForecaster) to improve overall robustness and accuracy. This approach can be especially useful when different models capture different aspects of the time series.
Example Code
import torch
from apdtflow.models.apdtflow import APDTFlow
from apdtflow.models.transformer_forecaster import TransformerForecaster
from apdtflow.models.tcn_forecaster import TCNForecaster
from apdtflow.models.ensemble_forecaster import EnsembleForecaster
model1 = APDTFlow(num_scales=3, input_channels=1, filter_size=5, hidden_dim=16, output_dim=1, forecast_horizon=3)
model2 = TransformerForecaster(input_dim=1, model_dim=32, num_layers=2, nhead=4, forecast_horizon=3)
model3 = TCNForecaster(input_channels=1, num_channels=[32, 32], kernel_size=5, forecast_horizon=3)
ensemble_model = EnsembleForecaster(models=[model1, model2, model3])
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
ensemble_model.to(device)
Experimentation and Results
APDTFlow has been evaluated across multiple forecasting horizons using a rolling-window crossβvalidation approach. Comparative studies against models like TransformerForecaster, TCNForecaster, and various ensemble strategies have shown competitive performance in terms of validation loss.
Validation Loss Comparison
Performance vs. Forecast Horizon
Example Forecast
Getting Started with APDTFlow
APDTFlow is available on PyPI, so you can install it quickly:
pip install apdtflow
If youβd like to explore or modify the source code, the project is hosted on GitHub. To get started, clone the repository and install it in editable mode:
git clone https://github.com/yotambraun/APDTFlow.git
cd APDTFlow
pip install -e .
omprehensive documentation is available in the docs directory, covering topics from data processing and model configuration to crossβvalidation and evaluation.
Conclusion
We designed APDTFlow as a modular system that combines state-of-the-art deep learning with an emphasis on clarity and flexibility β making it easier to tailor the approach to your unique forecasting needs. By breaking down the series into multiple scales, modeling continuous dynamics, and providing practical tools for evaluation and deployment, it serves as a versatile solution for both research and production.
If youβre looking to experiment with new forecasting strategies or refine your current models, APDTFlow provides a solid foundation. If youβd like to take a closer look at the code and learn more about how APDTFlow works, check out our GitHub repository.
I hope you found this article helpful. If you know someone who might benefit from it, please feel free to pass it along.
If you enjoyed this post, please give it a clap. Feel free to follow me on Medium for more articles!
References
Time Series Forecasting Fundamentals:
- Hyndman, R.J., & Athanasopoulos, G. (2018). Forecasting: Principles and Practice.
This online textbook is a great reference for classical time series forecasting methods and provides context for why modern approaches are needed when dealing with nonβstationarity and complex patterns.
Neural ODEs and Continuous Dynamics:
- Ricky T. Q. Chen, Yulia Rubanova, Jesse Bettencourt, David Duvenaud (2018). Neural Ordinary Differential Equations.
This paper introduced Neural ODEs and has been influential in the deep learning community. Itβs considered a seminal work for understanding continuous modeling of hidden states, which is directly relevant to how APDTFlow models continuous dynamics in time series data.
Transformer Architectures for Time Series:
- Bryan Lim, Sercan O. Arik, Nicolas Loeff, Tomas Pfister (2021). Temporal Fusion Transformers for Interpretable Multi-horizon Time Series Forecasting.
This paper presents an advanced approach that combines transformers with other techniques for forecasting. Itβs highly regarded for its emphasis on interpretability and performance, making it a useful point of comparison for APDTFlowβs transformer-based decoder.
Join thousands of data leaders on the AI newsletter. Join over 80,000 subscribers and keep up to date with the latest developments in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming aΒ sponsor.
Published via Towards AI