Metadata-Version: 2.4
Name: time-anchor
Version: 0.1.2
Summary: Time-series forecasting and attribution utilities for Time-Anchor checkpoints.
Author: Time-Anchor contributors
License-Expression: Apache-2.0
Project-URL: Homepage, https://huggingface.co/K-Iwa/time-anchor-modernbert-32m
Project-URL: Repository, https://huggingface.co/K-Iwa/time-anchor
Project-URL: Issues, https://huggingface.co/K-Iwa/time-anchor/discussions
Project-URL: Documentation, https://huggingface.co/K-Iwa/time-anchor-modernbert-32m
Keywords: time-series,forecasting,transformers,huggingface,explainability
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: numpy>=1.24
Requires-Dist: pandas>=2.0
Requires-Dist: safetensors>=0.4
Requires-Dist: torch>=2.6
Requires-Dist: transformers>=4.49
Provides-Extra: examples
Requires-Dist: matplotlib>=3.8; extra == "examples"
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: ruff>=0.5; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Provides-Extra: publish
Requires-Dist: huggingface_hub[cli]>=0.24; extra == "publish"
Dynamic: license-file

---
license: apache-2.0
library_name: transformers
tags:
  - time-series
  - forecasting
  - explainability
  - modernbert
pipeline_tag: time-series-forecasting
---

# Time-Anchor

A time-series forecasting package built around three outputs from one call:

|  |  |
| --- | --- |
| 📈 **Quantile forecast** | Probabilistic forecasts at any requested quantile levels |
| 🧭 **Variable / time impact** | Normalized contribution of every input variable at every time step |
| 📌 **Anchor forecast** | Forecasts conditioned on known future points you specify |

![Quantile forecast](https://huggingface.co/K-Iwa/time-anchor-modernbert-32m/resolve/main/assets/forecast_dark.png)

*Hourly temperature in Tokyo (Open-Meteo archive), 64-hour holdout: median MAE 0.57 °C,
with every actual value inside the q10–q90 band.*

## Installation

```bash
python -m pip install -e .
```

## Quick Start

```python
import pandas as pd
from time_anchor import predict_time_anchor

url = (
    "https://archive-api.open-meteo.com/v1/archive"
    "?latitude=35.69&longitude=139.69&start_date=2024-10-01&end_date=2024-12-31"
    "&hourly=temperature_2m,relative_humidity_2m,surface_pressure,wind_speed_10m&format=csv"
)
weather = pd.read_csv(url, skiprows=3)
temperature = weather.iloc[:, 1].astype("float32")

result = predict_time_anchor(
    "models/time-anchor-modernbert-32m",
    target_context=temperature[:1440],
    prediction_length=64,
    quantile_levels=(0.1, 0.5, 0.9),
)
print(pd.DataFrame(result.forecast_rows))
```

The first argument may be a local checkpoint directory or a Hugging Face Hub model id.
For a combined code/model repository, add `subfolder="models/time-anchor-modernbert-32m"`.

### Variable / Time-Step Impact

![Normalized variable impact by time step](https://huggingface.co/K-Iwa/time-anchor-modernbert-32m/resolve/main/assets/impact_dark.png)

*Per-hour contribution of each weather variable over a one-week Tokyo context.
For each `time_index`, `impact` across all variables sums to 1.*

```python
result = predict_time_anchor(
    "models/time-anchor-modernbert-32m",
    target_context=temperature[:168],
    explanatory_contexts=[weather.iloc[:168, i].astype("float32") for i in (2, 3, 4)],
    gaf={"enabled": True, "topk_time_steps": 0},
)
print(pd.DataFrame(result.variable_impact_rows))
```

Validation: build a target with known ground truth, `target = 0.60*f1 + 0.30*f2
+ 0.10*f3` from three sine waves, and pass the waves as explanatory series —
the measured impact shares come out at 0.55 / 0.33 / 0.12, matching the true
weights. Swapping the weights swaps the shares, and when the target switches
drivers mid-context, each wave's per-time impact is higher in the half it
drives. See the
[model card](https://huggingface.co/K-Iwa/time-anchor-modernbert-32m#impact-validation)
for the full validation.

### Anchor Forecast

![Forecast with user-specified anchors](https://huggingface.co/K-Iwa/time-anchor-modernbert-32m/resolve/main/assets/anchor_forecast_dark.png)

*Monthly airline passengers (Box & Jenkins), 24-month holdout: pinning six known
months cuts the median forecast MAE from 46 to 10 thousand passengers.*

```python
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv"
passengers = pd.read_csv(url)["Passengers"].astype("float32")

result = predict_time_anchor(
    "models/time-anchor-modernbert-32m",
    target_context=passengers[:-24],
    prediction_length=24,
    anchor={
        "mode": "observed",
        "positions": [4, 8, 12, 16, 20, 24],
        "values": [396, 559, 405, 461, 606, 432],
    },
)
print(pd.DataFrame(result.forecast_rows))
```

`positions` are 1-based forecast horizon steps. Anchor forecasts use the target
history only; disable anchors when passing `explanatory_contexts`.

## CLI

```bash
time-anchor-infer                                   # forecast + impact on the bundled sample
time-anchor-infer --no-impact                       # forecast only
time-anchor-infer --no-impact --anchor-mode observed \
    --anchor-positions 12,24,36 --anchor-values 0.2,0.4,0.1
time-anchor-infer --checkpoint K-Iwa/time-anchor-modernbert-32m --input data.csv
```

Outputs are written to `output/forecast.csv`, `output/variable_impact.csv`, and
`output/result.json`. `time-anchor-sine-test` runs a sine-wave anchor evaluation
(requires `pip install -e ".[examples]"`).

## Repository Layout

- `src/time_anchor` — model, pipeline, anchor samplers, and explainability code
- `models/time-anchor-modernbert-32m` — checkpoint and model card
- `examples/sample_data.csv` — small input file for smoke tests
- `docs/publishing.md` — Hugging Face / PyPI release checklist

## Development

```bash
python -m pip install -e ".[dev]"
python -m ruff check .
python -m ruff format --check .
python -m pytest
```

## References

- Ansari et al.
  [Chronos: Learning the Language of Time Series](https://openreview.net/forum?id=gerNCVqqtR).
  TMLR 2024 — informs the forecasting/tokenization design.
- Azarkhalili and Libbrecht.
  [Generalized Attention Flow: Feature Attribution for Transformer Models via Maximum Flow](https://arxiv.org/abs/2502.15765).
  2025 — the variable/time impact method (GAF).

See [docs/references.md](docs/references.md), [NOTICE](NOTICE), and
[CITATION.cff](CITATION.cff) for attribution details.

## License

Apache-2.0. Some source files retain upstream Amazon copyright notices.

Figures use historical weather data from [Open-Meteo](https://open-meteo.com/)
(CC BY 4.0) and the classic airline passengers dataset (Box & Jenkins, 1976).
