Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,12 @@ LOG_FORMAT=json
API_HOST=0.0.0.0
API_PORT=8123

# Forecasting settings
FORECAST_RANDOM_SEED=42
FORECAST_DEFAULT_HORIZON=14
FORECAST_MAX_HORIZON=90
FORECAST_MODEL_ARTIFACTS_DIR=./artifacts/models
FORECAST_ENABLE_LIGHTGBM=false

# Frontend (Vite)
VITE_API_BASE_URL=http://localhost:8123
45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ app/
├── features/
│ ├── data_platform/ # Store, product, calendar, sales tables
│ ├── ingest/ # Batch upsert endpoints for sales data
│ └── featuresets/ # Time-safe feature engineering (lags, rolling, calendar)
│ ├── featuresets/ # Time-safe feature engineering (lags, rolling, calendar)
│ └── forecasting/ # Model training, prediction, persistence
└── main.py # FastAPI entry point

tests/ # Test fixtures and helpers
Expand All @@ -103,6 +104,7 @@ examples/
├── api/ # HTTP client examples
├── schema/ # Table documentation
├── queries/ # Example SQL queries
├── models/ # Baseline model examples (naive, seasonal_naive, moving_average)
└── compute_features_demo.py # Feature engineering demo
scripts/ # Utility scripts
```
Expand Down Expand Up @@ -184,6 +186,47 @@ curl -X POST http://localhost:8123/featuresets/compute \

See [examples/compute_features_demo.py](examples/compute_features_demo.py) for a complete demo.

### Forecasting

- `POST /forecasting/train` - Train a forecasting model for a store/product series
- `POST /forecasting/predict` - Generate forecasts using a trained model

**Example Training Request:**
```bash
curl -X POST http://localhost:8123/forecasting/train \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"product_id": 1,
"train_start_date": "2024-01-01",
"train_end_date": "2024-06-30",
"config": {
"model_type": "seasonal_naive",
"seasonal_period": 7
}
}'
```

**Example Prediction Request:**
```bash
curl -X POST http://localhost:8123/forecasting/predict \
-H "Content-Type: application/json" \
-d '{
"store_id": 1,
"product_id": 1,
"horizon": 14,
"model_path": "./artifacts/models/store_1_product_1_seasonal_naive_20240630.pkl"
}'
```

**Supported Model Types:**
- `naive` - Last observed value (simple baseline)
- `seasonal_naive` - Same period from previous season
- `moving_average` - Mean of last N observations
- `lightgbm` - LightGBM regressor (requires `forecast_enable_lightgbm=True`)

See [examples/models/](examples/models/) for baseline model examples.

## API Documentation

Once the server is running:
Expand Down
7 changes: 7 additions & 0 deletions app/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ class Settings(BaseSettings):
feature_max_lag: int = 365
feature_max_window: int = 90

# Forecasting
forecast_random_seed: int = 42
forecast_default_horizon: int = 14
forecast_max_horizon: int = 90
forecast_model_artifacts_dir: str = "./artifacts/models"
forecast_enable_lightgbm: bool = False

@property
def is_development(self) -> bool:
"""Check if running in development mode."""
Expand Down
82 changes: 82 additions & 0 deletions app/features/forecasting/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""Forecasting module for baseline and ML models.

This module provides a unified interface for training and predicting with
various forecasting models including naive, seasonal naive, and moving average.

Exports:
Models:
- BaseForecaster: Abstract base class for all forecasters
- NaiveForecaster: Predicts last observed value
- SeasonalNaiveForecaster: Predicts value from same season
- MovingAverageForecaster: Predicts mean of last N observations
- model_factory: Create forecaster from config

Schemas:
- ModelConfig: Union of all model configurations
- NaiveModelConfig, SeasonalNaiveModelConfig, MovingAverageModelConfig
- TrainRequest, TrainResponse
- PredictRequest, PredictResponse, ForecastPoint

Persistence:
- ModelBundle: Container for model + config + metadata
- save_model_bundle, load_model_bundle

Service:
- ForecastingService: Orchestration layer for training/prediction
"""

from app.features.forecasting.models import (
BaseForecaster,
FitResult,
MovingAverageForecaster,
NaiveForecaster,
SeasonalNaiveForecaster,
model_factory,
)
from app.features.forecasting.persistence import (
ModelBundle,
load_model_bundle,
save_model_bundle,
)
from app.features.forecasting.schemas import (
ForecastPoint,
LightGBMModelConfig,
ModelConfig,
ModelConfigBase,
MovingAverageModelConfig,
NaiveModelConfig,
PredictRequest,
PredictResponse,
SeasonalNaiveModelConfig,
TrainRequest,
TrainResponse,
)
from app.features.forecasting.service import ForecastingService

__all__ = [
# Models
"BaseForecaster",
"FitResult",
# Schemas
"ForecastPoint",
# Service
"ForecastingService",
"LightGBMModelConfig",
"ModelBundle",
"ModelConfig",
"ModelConfigBase",
"MovingAverageForecaster",
"MovingAverageModelConfig",
"NaiveForecaster",
"NaiveModelConfig",
"PredictRequest",
"PredictResponse",
"SeasonalNaiveForecaster",
"SeasonalNaiveModelConfig",
"TrainRequest",
"TrainResponse",
# Persistence
"load_model_bundle",
"model_factory",
"save_model_bundle",
]
Loading