views-baseline
Baseline forecasting models for the VIEWS pipeline.
This package provides simple, transparent baseline models that can be used for benchmarking more complex forecasting models and sanity checks. The baselines are intentionally minimal and deterministic (or reproducibly stochastic for distributional models).
Overview
The package implements several common baseline strategies for panel time-series data with a multi-index of:
- time (e.g.
month_id) - entity (e.g.
priogrid_id,country_id)
All models follow a common interface:
model.fit(df) # df: a pandas DataFrame OR a views_frames FeatureFrame
predictions = model.predict(df, sequence_number)
fit() / predict() accept either a pandas DataFrame or a views_frames.FeatureFrame (ADR-019): the input is normalized to a FeatureFrame once at the boundary (to_feature_frame in model/frames/input.py, the only place pandas is read), and all windowing/aggregation runs on its numpy arrays. Models are fitted automatically via fit() before generating predictions. Fitted model artifacts are pickled for ensemble compatibility.
Implemented Models
All baselines operate on panel data indexed by (time t, unit i) — month_id × spatial unit (priogrid_id at pgm, country_id at cm) — and forecast one or more target columns over a horizon of output_length steps starting at test_start + sequence_number. ("unit" is the term used in a PredictionFrame's SpatioTemporalIndex; the input index calls the same axis the entity.)
Causal split (no leakage). Every model is fit using only observations strictly before the test period. The last training month is train_end = test_start − 1; no value at or after test_start enters any fitted quantity. (The point models and MixtureBaseline filter t < test_start; ConflictologyModel filters t ≤ train_end — the same boundary, written two ways.)
Two output families:
- Point forecasts — one deterministic value per (unit, time, target). Returned as
dict[str, PredictionFrame]withy_predof shape(N, 1). - Distributional forecasts —
n_samplesMonte-Carlo draws per (unit, time, target). Returned asdict[str, PredictionFrame]withy_predof shape(N, n_samples).
In all cases N = (number of units) × output_length, and each PredictionFrame carries a SpatioTemporalIndex with the time, unit, and spatial level (CM/PGM) of every row. All frames are built through a single construction seam, to_prediction_frames in model/frames/output.py (ADR-020), and the level is derived from the declared loa and validated against the input index (ADR-003).
Point Forecast Models
ZeroModel
Predicts exactly 0 for every target, unit, and forecast step. The lower-bound reference; performs no fitting.
ZeroModel(targets, partition_dict, loa)
LocfModel — Last Observation Carried Forward
For each unit and target, carries the last observed value at train_end forward unchanged across the entire horizon. A persistence baseline ("the most recent observation is the best guess"), strong for highly autocorrelated targets.
LocfModel(targets, partition_dict, loa)
AverageModel
For each unit and target, forecasts the arithmetic mean of that unit's last window_months observations before test_start, held constant across the horizon. A smoothed-persistence baseline, more robust than LOCF when individual months are noisy.
AverageModel(targets, window_months, partition_dict, loa)
- Means are computed per unit; units with no history before
test_startare skipped (logged).
Distributional Models
Both draw n_samples i.i.d. samples per cell from a fresh, seeded generator (numpy.random.default_rng(seed)), so a given (data, configuration, seed) reproduces bit-for-bit. The RNG is consumed in a fixed unit → time → target order to guarantee reproducibility.
ConflictologyModel — empirical climatology
For each unit i, collects that unit's last window_months observed values up to train_end, then draws n_samples samples with replacement from that per-unit history for every forecast cell. The predictive distribution for a cell is the recent empirical distribution of that same unit — a conflict "climatology." It uses only the unit's own recent history: no pooling across units, no older history.
ConflictologyModel(targets, window_months, partition_dict, loa, n_samples, seed=42)
MixtureBaseline — mixture of local and global empirical pools
Combines two empirical sources to avoid the zero-probability trap (a unit whose recent history is entirely zero being structurally unable to predict a nonzero outcome):
- Local pool — the unit's last
window_monthsobserved values (as inConflictologyModel). - Global pool — all strictly-positive observed values, pooled across every unit and the entire training span.
Each of the n_samples draws is taken from the global pool with probability lambda_mix, otherwise from the local pool (probability 1 − lambda_mix). At lambda_mix = 0 it reduces to a local-only empirical baseline (same source as ConflictologyModel); larger lambda_mix injects more cross-unit, full-history positive mass.
MixtureBaseline(targets, window_months, lambda_mix, n_samples, partition_dict, loa, seed=42)
ParametricConflictology — no-hurdle parametric climatology
The parametric counterpart of ConflictologyModel: instead of resampling each unit's window empirically, it fits a single native-zero distribution (family, e.g. nb) to that same window and draws n_samples per cell from the fitted law. family, transform, and seed are required, audited genome keys (ADR-021/ADR-022); transform="log1p" is illegal for count families and fails loud. In the closeness study (see reports/closeness_experiment/), nb is the family closest to conflictology on the C2ST indistinguishability metric.
ParametricConflictology(targets, window_months, partition_dict, loa, n_samples, family, transform="none", seed=42)
ParametricHurdleConflictology — hurdle parametric climatology
A two-part law per unit: a zero-spike (empirical zero-rate, Bernoulli) plus a continuous positive-part family (lognormal/gumbel/gamma) fit to the positive window values (mirrors Vesco et al. 2026's RVI mixture). transform (none/log1p) applies to the positive part and is inverted per sample; a non-negativity floor (EMIT_FLOOR) guarantees no negative magnitudes even for gumbel. Closeness study: gamma/none is closest on magnitude fidelity (Wasserstein/energy); log1p is worse on active cells. (Tweedie was evaluated and excluded — ADR-022.)
ParametricHurdleConflictology(targets, window_months, partition_dict, loa, n_samples, family, transform="none", seed=42)
Model Catalog
The BaselineModelCatalog provides a factory for instantiating models based on config:
from views_baseline.model.catalog import BaselineModelCatalog
catalog = BaselineModelCatalog(config, partition_dict, loa)
model = catalog.get_model("LocfModel")
Available models:
catalog.list_models()
# ['ZeroModel', 'LocfModel', 'AverageModel', 'ConflictologyModel', 'MixtureBaseline',
# 'ParametricConflictology', 'ParametricHurdleConflictology']
Integration with the VIEWS Pipeline
The package integrates with the core pipeline via:
BaselineForecastingModelManager
Key characteristics:
- Models are fitted automatically via
fit()and artifacts are pickled - Predictions are generated per evaluation sequence
- Supports both evaluation and forecasting modes
- Distributional models are dispatched automatically via the
DistributionalBaselineModelprotocol
Data Assumptions
Input DataFrame:
- Must be indexed by
(time, entity)as a MultiIndex - Must contain target columns specified in
config['targets']
Example index:
MultiIndex(levels=[month_id, priogrid_id])
Notes & Caveats
- Entities without sufficient history are skipped (with a warning)
- No imputation beyond what the baseline logic implies
- No clipping or post-processing is applied by default
Installation
Clone the repository and install with pip:
pip install -e .
License / Usage
Internal VIEWS package. Intended for research and forecasting pipelines, not as a general-purpose forecasting library.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file views_baseline-1.0.0.tar.gz.
File metadata
- Download URL: views_baseline-1.0.0.tar.gz
- Upload date:
- Size: 30.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
168b4e77a715d170894e2427d48af236fae319fd2613efcad7774b9da19a661e
|
|
| MD5 |
4dbb66f6760713fedaa16bd6a88f926a
|
|
| BLAKE2b-256 |
18c720ded19ae0a5646dd0c37799884c9c99f60c378f90e075100f598a60f453
|
File details
Details for the file views_baseline-1.0.0-py3-none-any.whl.
File metadata
- Download URL: views_baseline-1.0.0-py3-none-any.whl
- Upload date:
- Size: 43.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5931f26154c27df7c5d9750d453c37294ca23a96becdb1d6a7d0949862f5797
|
|
| MD5 |
993df2df19de591d380196fd99b6feba
|
|
| BLAKE2b-256 |
ea344e68bed8e9671530aaed5537869e98d0fc19f4a6ea596e73e2f22e27a9ce
|