Online (incremental) covariance and correlation estimation — the online complement to sklearn.covariance
Project description
precise
Online (incremental) covariance and correlation estimation — the streaming complement to
sklearn.covariance, whose estimators
are batch-only and have no partial_fit. Pure Python + numpy; no other required dependencies.
pip install precise
Use
from precise import EwaCovariance
est = EwaCovariance(r=0.05)
for y in stream: # y is a 1d observation; pass a 2d array for a batch
est.partial_fit(y)
est.covariance_ # (n, n) ndarray
est.correlation_ # unit-diagonal correlation
est.precision_ # inverse covariance
est.location_ # running mean
est.fit(X) # sklearn-style batch drop-in (X is 2d)
Every estimator is truly online — a constant amount of work per observation, no growing
buffers. State is a plain dict, so you can checkpoint mid-stream with get_state() / set_state().
Estimators
| Class | What it does |
|---|---|
EmpiricalCovariance |
running sample covariance (Welford) |
EwaCovariance |
exponentially weighted (recency-biased) |
AdaptiveEwaCovariance |
EWMA whose forgetting rate speeds up on regime change |
LedoitWolfCovariance |
online Ledoit-Wolf shrinkage towards a scaled identity |
OASCovariance |
online Oracle Approximating Shrinkage (often better-conditioned than LW) |
ShrunkCovariance |
fixed-intensity shrinkage to identity or a constant-correlation target |
PartialMomentsCovariance |
exponentially weighted partial-moment (semi-)covariance |
HuberCovariance |
online robust estimator that downweights outliers |
TylerCovariance |
recursive Tyler M-estimator — robust correlation/shape for elliptical data |
GeodesicEwaCovariance |
recency-weighted update along the affine-invariant SPD geodesic |
DCCCovariance |
dynamic conditional correlation — decouples volatility from correlation |
FactorCovariance |
online low-rank + diagonal (approximate factor model); O(d·k) per step |
from precise import all_estimators, estimator_from_name
all_estimators() # the list of classes (a bake-off in one loop)
estimator_from_name("LedoitWolfCovariance")
Keyed / dynamic universes (river-style)
In streaming/finance settings observations arrive as dicts keyed by name, and the set of names
can change over time. keyed(...) decorates any of the estimators above to consume keyed dicts
(river-style update / learn_one) and emit keyed output:
from precise import keyed, EwaCovariance
d = keyed(EwaCovariance(r=0.05), dynamic=True) # changing universe (DynamicUniverse)
d.update({"AAPL": 0.01, "MSFT": -0.02})
d.update({"MSFT": 0.00, "NVDA": 0.03}) # AAPL leaves, NVDA enters
d.covariance_ # dict-of-dicts over the live universe
d.to_frame() # pandas DataFrame (pip install precise[pandas])
k = keyed(EwaCovariance(r=0.05)) # fixed universe, imputes missing keys (FixedUniverse)
dynamic=False (the default) gives a FixedUniverse (one wrapped estimator, missing keys imputed);
dynamic=True gives a DynamicUniverse (a wrapped estimator per live key-set). Both work with any
positional estimator — the adapter adds no covariance math of its own.
Composing volatility × correlation
H = D R D is a composition, not a fixed algorithm. ConditionalCovariance lets you pick the
per-series volatility model and the correlation estimator independently — DCCCovariance is
just the EWMA/EWMA special case:
from precise import ConditionalCovariance, EwaCovariance, LedoitWolfCovariance
est = ConditionalCovariance(vol=EwaCovariance(r=0.02), # any estimator, used per series in 1-D
corr=LedoitWolfCovariance(r=0.05)) # correlation from any estimator
The volatility model can also be any univariate model from
microprediction/skaters (Holt, Hosking, …) via
from_skater — precise doesn't depend on it; the adapter is duck-typed:
import skaters
from precise import ConditionalCovariance, from_skater
est = ConditionalCovariance(vol=from_skater(skaters.holt), corr=EwaCovariance(r=0.05))
Related
- Generating random covariance/correlation matrices to test against:
randomcov. - Portfolio construction (Schur-complementary allocation, HRP) moved to
schur; for production use the skfolio implementation is recommended. - A Robust Portfolio Literature Reading List lives in this repo.
- Part of the microprediction project.
Migrating from precise < 1.0 (the functional "skater" API)? See MIGRATING.md.
Disclaimer
Not investment advice. Just code, subject to the MIT License.
Project details
Release history Release notifications | RSS feed
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 precise-1.0.0.tar.gz.
File metadata
- Download URL: precise-1.0.0.tar.gz
- Upload date:
- Size: 31.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
411ae122c4513866e68428f6c8c5db47e39ab2331595d7f7b14427e01b2ca279
|
|
| MD5 |
27f21a46706794882f9f3ed179e34b60
|
|
| BLAKE2b-256 |
39d12f79dbca512797a0d0d9f950a431e7ec1698755c03d9c93758075013abe7
|
File details
Details for the file precise-1.0.0-py3-none-any.whl.
File metadata
- Download URL: precise-1.0.0-py3-none-any.whl
- Upload date:
- Size: 44.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f079f9b6ba2147be7008faadf6d2477464ac5c906ebd55b929846f9a781a718
|
|
| MD5 |
a17ea93123381157e4eac5f376963ee4
|
|
| BLAKE2b-256 |
83ddf1308dd8d3f45c8ee3c5b750f02db52cfc8918b87616a8e6904742c6b644
|