Covariance estimators based on spectral regularization (PM, ridge, clipping, shrinkage).
Project description
psd-covariance: Positive Definite Covariance Matrix Estimation
Introduction
psd-covariance` provides tools for covariance matrix estimation and regularization in settings where the sample covariance matrix may be ill-conditioned or fail to be positive definite. The package implements spectral methods that improve numerical stability while preserving a clear eigenvalue-based interpretation.
Its main component is the PosteriorMeanEstimator, which implements Bayesian eigenvalue regularization. The package also includes eigenvalue clipping, ridge regularization, and classical shrinkage estimators.
The package contains four main modules:
PosteriorMeanEstimator: posterior mean covariance estimation (PM and PM-FT)EigenvalueClippingEstimator: eigenvalue thresholdingRidgeEstimator: ridge-type covariance regularizationShrinkageMethods: linear shrinkage and quadratic inverse shrinkage (QIS)
Installation
pip install psd-covariance
Imports
import numpy as np
import pandas as pd
from psd_covariance.posterior_mean import PosteriorMeanEstimator
from psd_covariance.eigenvalue_clipping import EigenvalueClippingEstimator
from psd_covariance.ridge_regularization import RidgeEstimator
from psd_covariance.shrinkage_methods import ShrinkageMethods
from psd_covariance.utils import sample_cov
Quick Start
Example 1: Transforming a non-PSD matrix
import numpy as np
from psd_covariance.posterior_mean import PosteriorMeanEstimator
eigvals = np.array([-0.50, -0.48, 0.59, 0.70, 0.83,
0.89, 1.01, 1.39, 1.67, 1.96])
d = len(eigvals)
A = np.random.randn(d, d)
Q, _ = np.linalg.qr(A)
Sigma_tilde = Q @ np.diag(eigvals) @ Q.T
pm = PosteriorMeanEstimator(fixed_trace=False)
pm_result = pm.fit(Sigma_tilde, sigma=0.5)
pmft = PosteriorMeanEstimator(fixed_trace=True)
pmft_result = pmft.fit(Sigma_tilde, sigma=0.5)
print("PM eigenvalues:", np.linalg.eigvalsh(pm_result.cov))
print("PM-FT eigenvalues:", np.linalg.eigvalsh(pmft_result.cov))
Example 2: Cross-validation
import numpy as np
from psd_covariance.posterior_mean import PosteriorMeanEstimator
from psd_covariance.utils import sample_cov
np.random.seed(0)
d, n = 10, 20
rho = 0.8
cov = np.fromfunction(lambda i, j: rho ** np.abs(i - j), (d, d))
X = np.random.multivariate_normal(np.zeros(d), cov, size=n)
S = sample_cov(X)
sigma_range = np.linspace(0.01, 2.0, 150)
pm = PosteriorMeanEstimator()
sigma_pm = pm.cross_validate_sigma(X, sigma_range)
pmft = PosteriorMeanEstimator(fixed_trace=True)
sigma_pmft = pmft.cross_validate_sigma(X, sigma_range)
print("PM sigma:", sigma_pm)
print("PM-FT sigma:", sigma_pmft)
Example 3: Clipping and Ridge
import numpy as np
from psd_covariance.eigenvalue_clipping import EigenvalueClippingEstimator
from psd_covariance.ridge_regularization import RidgeEstimator
Sigma_tilde = np.array([
[1.0, 0.4, 0.3],
[0.4, 0.2, 0.5],
[0.3, 0.5, -0.1]
])
clip = EigenvalueClippingEstimator()
tau = clip.threshold_for_min_eigenvalue(Sigma_tilde, target_min=0.1)
clip_result = clip.fit(Sigma_tilde, tau)
ridge = RidgeEstimator()
alpha = ridge.alpha_for_min_eigenvalue(Sigma_tilde, target_min=0.1)
ridge_result = ridge.fit(Sigma_tilde, alpha)
print("Clipping threshold:", tau)
print("Ridge alpha:", alpha)
Example 4: Shrinkage
import numpy as np
import pandas as pd
from psd_covariance.shrinkage_methods import ShrinkageMethods
np.random.seed(1)
X = pd.DataFrame(np.random.randn(100, 5))
linear = ShrinkageMethods.linear_shrinkage(X)
qis = ShrinkageMethods.quadratic_inverse_shrinkage(X)
print("Shrinkage intensity:", linear.shrinkage)
print("QIS covariance shape:", qis.cov.shape)
Main Classes
PosteriorMeanEstimator
fit(Sigma_tilde, sigma)cross_validate_sigma(X, sigma_range)sigma_for_min_eigenvalue(Sigma_tilde, target_min)
EigenvalueClippingEstimator
fit(Sigma_tilde, threshold)cross_validate_threshold(X, threshold_range)threshold_for_min_eigenvalue(Sigma_tilde, target_min)
RidgeEstimator
fit(Sigma_tilde, alpha)cross_validate_alpha(X, alpha_range)alpha_for_min_eigenvalue(Sigma_tilde, target_min)
ShrinkageMethods
linear_shrinkage(X)quadratic_inverse_shrinkage(X)
Authors
Based on:
Boudt, K., J. Cremers, K. Dragun, and S. Vanduffel (2025). Well-conditioned covariance estimation via bayesian eigenvalue regularization. Working paper.
Maintained by Jesper Cremers.
References
- Boudt, K., J. Cremers, K. Dragun, and S. Vanduffel (2025). Well-conditioned covariance estimation via bayesian eigenvalue regularization. Working paper.
- Ledoit, O. and M. Wolf (2004). Honey, I shrunk the sample covariance matrix. The Journal of Portfolio Management 30 (4), 110-119.
- Ledoit, O. and M. Wolf (2022). Quadratic shrinkage for large covariance matrices. Bernoulli 28 (3), 1519-1547.
- Rousseeuw, P. J. and G. Molenberghs (1993). Transformation of non positive semidefinite correlation matrices. Communications in Statistics - Theory and Methods 22 (4), 965-984.
Notes
Parts of the shrinkage implementation are adapted from: https://github.com/pald22/covShrinkage
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 psd_covariance-1.1.0.tar.gz.
File metadata
- Download URL: psd_covariance-1.1.0.tar.gz
- Upload date:
- Size: 8.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a02afadb54f3c5be8235a11edbbabca4ca89e207c3f24c8a91d16b4aa414c437
|
|
| MD5 |
d3fb1de034e6d88bc6952e203c61d42a
|
|
| BLAKE2b-256 |
365a75da94b7da43c16f2979e369148b8f42b6b3659c9b11ac76401eb4527573
|
File details
Details for the file psd_covariance-1.1.0-py3-none-any.whl.
File metadata
- Download URL: psd_covariance-1.1.0-py3-none-any.whl
- Upload date:
- Size: 10.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3b1ff96af80736df4b6bfe3ccfec4da505e4dbedb3020cdd6fe2d73fcc7c9f7
|
|
| MD5 |
3a6d1c58fe66a004bdeed97ad083bda8
|
|
| BLAKE2b-256 |
5dbdf1e72c8749db07c03ae6697c0ebb17087a1d878424e8925c20206d438498
|