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.0.tar.gz (31.8 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.0-py3-none-any.whl (44.2 kB view details)

Uploaded Python 3

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

Hashes for precise-1.0.0.tar.gz
Algorithm Hash digest
SHA256 411ae122c4513866e68428f6c8c5db47e39ab2331595d7f7b14427e01b2ca279
MD5 27f21a46706794882f9f3ed179e34b60
BLAKE2b-256 39d12f79dbca512797a0d0d9f950a431e7ec1698755c03d9c93758075013abe7

See more details on using hashes here.

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

Hashes for precise-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3f079f9b6ba2147be7008faadf6d2477464ac5c906ebd55b929846f9a781a718
MD5 a17ea93123381157e4eac5f376963ee4
BLAKE2b-256 83ddf1308dd8d3f45c8ee3c5b750f02db52cfc8918b87616a8e6904742c6b644

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