Skip to main content

Online (incremental) covariance and correlation estimation — the online complement to sklearn.covariance

Project description

precise

ci License: MIT Python 3.9+

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

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

precise-1.0.0rc1.tar.gz (31.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

precise-1.0.0rc1-py3-none-any.whl (43.4 kB view details)

Uploaded Python 3

File details

Details for the file precise-1.0.0rc1.tar.gz.

File metadata

  • Download URL: precise-1.0.0rc1.tar.gz
  • Upload date:
  • Size: 31.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for precise-1.0.0rc1.tar.gz
Algorithm Hash digest
SHA256 54e39d83a7b8a5af38147f41a39baf6913f4171f0c546f539f9a60bb17d84752
MD5 8a882c84783be76576724a38d78b4a81
BLAKE2b-256 b9ff07301a576eb56db4b95f8c3f89a9a21de7be5f2af27ae085a22ed1c0af92

See more details on using hashes here.

File details

Details for the file precise-1.0.0rc1-py3-none-any.whl.

File metadata

  • Download URL: precise-1.0.0rc1-py3-none-any.whl
  • Upload date:
  • Size: 43.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for precise-1.0.0rc1-py3-none-any.whl
Algorithm Hash digest
SHA256 e332f0709ec130337ee4715b34adfc511d0f8ac8d58ef127953c43e597bf3dab
MD5 f38dacafe0a5ebd07c2aefc652464643
BLAKE2b-256 4f74364dc98a449d42b50a4d04564cfaa40679c0449c4aac315a324b4ea489a9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page