Примечание
Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере через JupyterLite или Binder.
Оценивание ковариации со сжатием: LedoitWolf в сравнении с OAS и оценкой максимального правдоподобия
При оценивании ковариации обычно используют оценку максимального правдоподобия, например EmpiricalCovariance. Она является несмещённой, то есть при наличии большого числа наблюдений сходится к истинной (генеральной) ковариации. Однако также может быть полезно регуляризовать её, чтобы уменьшить дисперсию; это, в свою очередь, вносит некоторое смещение. В этом примере показана простая регуляризация, используемая в оценках ковариации со сжатием. В частности, здесь рассматривается, как задать степень регуляризации, то есть как выбрать компромисс между смещением и дисперсией.
Ссылки
# Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause
Сгенерировать выборочные данные
import numpy as np n_features, n_samples = 40, 20 np.random.seed(42) base_X_train = np.random.normal(size=(n_samples, n_features)) base_X_test = np.random.normal(size=(n_samples, n_features)) # Color samples coloring_matrix = np.random.normal(size=(n_features, n_features)) X_train = np.dot(base_X_train, coloring_matrix) X_test = np.dot(base_X_test, coloring_matrix)
Вычислить правдоподобие на тестовых данных
from scipy import linalg
from sklearn.covariance import ShrunkCovariance, empirical_covariance, log_likelihood
# spanning a range of possible shrinkage coefficient values
shrinkages = np.logspace(-2, 0, 30)
negative_logliks = [
-ShrunkCovariance(shrinkage=s).fit(X_train).score(X_test) for s in shrinkages
]
# under the ground-truth model, which we would not have access to in real
# settings
real_cov = np.dot(coloring_matrix.T, coloring_matrix)
emp_cov = empirical_covariance(X_train)
loglik_real = -log_likelihood(emp_cov, linalg.inv(real_cov))
Сравнить различные способы задания параметра регуляризации
Здесь сравниваются 3 подхода:
- Задание параметра посредством кросс-валидации правдоподобия на трёх блоках по сетке возможных параметров сжатия.
- Приближённая формула, предложенная Ledoit и Wolf для вычисления асимптотически оптимального параметра регуляризации (минимизирующего критерий MSE), которая даёт оценку ковариации
LedoitWolf. - Улучшенный вариант сжатия Ledoit-Wolf —
OAS, предложенный Chen и др. [1]. При предположении о гауссовом распределении данных он сходится значительно лучше, особенно для небольших выборок.
from sklearn.covariance import OAS, LedoitWolf
from sklearn.model_selection import GridSearchCV
# GridSearch for an optimal shrinkage coefficient
tuned_parameters = [{"shrinkage": shrinkages}]
cv = GridSearchCV(ShrunkCovariance(), tuned_parameters)
cv.fit(X_train)
# Ledoit-Wolf optimal shrinkage coefficient estimate
lw = LedoitWolf()
loglik_lw = lw.fit(X_train).score(X_test)
# OAS coefficient estimate
oa = OAS()
loglik_oa = oa.fit(X_train).score(X_test)
Построить график результатов
Чтобы количественно оценить ошибку оценивания, построим график правдоподобия для новых данных при различных значениях параметра сжатия. Также покажем значения, выбранные с помощью кросс-валидации, а также оценки LedoitWolf и OAS.
import matplotlib.pyplot as plt
fig = plt.figure()
plt.title("Regularized covariance: likelihood and shrinkage coefficient")
plt.xlabel("Regularization parameter: shrinkage coefficient")
plt.ylabel("Error: negative log-likelihood on test data")
# range shrinkage curve
plt.loglog(shrinkages, negative_logliks, label="Negative log-likelihood")
plt.plot(plt.xlim(), 2 * [loglik_real], "--r", label="Real covariance likelihood")
# adjust view
lik_max = np.amax(negative_logliks)
lik_min = np.amin(negative_logliks)
ymin = lik_min - 6.0 * np.log((plt.ylim()[1] - plt.ylim()[0]))
ymax = lik_max + 10.0 * np.log(lik_max - lik_min)
xmin = shrinkages[0]
xmax = shrinkages[-1]
# LW likelihood
plt.vlines(
lw.shrinkage_,
ymin,
-loglik_lw,
color="magenta",
linewidth=3,
label="Ledoit-Wolf estimate",
)
# OAS likelihood
plt.vlines(
oa.shrinkage_, ymin, -loglik_oa, color="purple", linewidth=3, label="OAS estimate"
)
# best CV estimator likelihood
plt.vlines(
cv.best_estimator_.shrinkage,
ymin,
-cv.best_estimator_.score(X_test),
color="cyan",
linewidth=3,
label="Cross-validation best estimate",
)
plt.ylim(ymin, ymax)
plt.xlim(xmin, xmax)
plt.legend()
plt.show()

Примечание
Оценка максимального правдоподобия соответствует отсутствию сжатия и поэтому работает плохо. Оценка Ledoit-Wolf показывает хорошие результаты, поскольку близка к оптимальной и не требует больших вычислительных затрат. В этом примере оценка OAS несколько дальше от оптимальной. Примечательно, что оба подхода превосходят кросс-валидацию, которая значительно более затратна с вычислительной точки зрения.
Общее время выполнения скрипта: (0 минут 0.532 секунды)
Связанные примеры
© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/covariance/plot_covariance_estimation.html