<a id="skfolio-moments-detonecovariance"></a>

# skfolio.moments.DetoneCovariance

<a id="skfolio.moments.DetoneCovariance"></a>

### *class* skfolio.moments.DetoneCovariance(covariance_estimator=None, n_markets=1, nearest=True, higham=False, higham_max_iteration=100)

Covariance Detoning estimator.

Financial covariance matrices usually incorporate a market component corresponding
to the first eigenvectors [[1]](#r84b9a959864f-1).
For some applications like clustering, removing the market component (loud tone)
allow a greater portion of the covariance to be explained by components that affect
specific subsets of the securities.

* **Parameters:**
  **covariance_estimator** *BaseCovariance, optional*
  : [Covariance estimator](https://skfolio.org/user_guide/covariance.html.md#covariance-estimator) to estimate the covariance
    matrix prior detoning.
    The default (`None`) is to use [`EmpiricalCovariance`](https://skfolio.org/generated/skfolio.moments.EmpiricalCovariance.html.md#skfolio.moments.EmpiricalCovariance).

  **n_markets** *int, default=1*
  : Number of eigenvectors related to the market.
    The default value is `1`.

  **nearest** *bool, default=True*
  : If this is set to True, the covariance is replaced by the nearest covariance
    matrix that is positive definite and with a Cholesky decomposition that can be
    computed. The variance is left unchanged.
    A covariance matrix that is not positive definite often occurs in high
    dimensional problems. It can be due to multicollinearity, floating-point
    inaccuracies, or when the number of observations is smaller than the number of
    assets. For more details, see [`cov_nearest`](https://skfolio.org/generated/skfolio.utils.stats.cov_nearest.html.md#skfolio.utils.stats.cov_nearest).
    The default is `True`.

  **higham** *bool, default=False*
  : If this is set to True, the Higham (2002) algorithm is used to find the
    nearest PD covariance, otherwise the eigenvalues are clipped to a threshold
    above zeros (1e-13). The default is `False` and uses the clipping method as the
    Higham algorithm can be slow for large datasets.

  **higham_max_iteration** *int, default=100*
  : Maximum number of iterations of the Higham (2002) algorithm.
    The default value is `100`.
* **Attributes:**
  **covariance_** *ndarray of shape (n_assets, n_assets)*
  : Estimated covariance.

  **covariance_estimator_** *BaseCovariance*
  : Fitted `covariance_estimator`.

  **n_features_in_** *int*
  : Number of assets seen during `fit`.

  **feature_names_in_** *ndarray of shape (`n_features_in_`,)*
  : Names of assets seen during `fit`. Defined only when `X`
    has assets names that are all strings.

### Methods

| [`fit`](#skfolio.moments.DetoneCovariance.fit)(X[, y])                     | Fit the Covariance Detoning estimator.                                             |
|----------------------------------------------------------------------------------|------------------------------------------------------------------------------------|
| [`get_metadata_routing`](#skfolio.moments.DetoneCovariance.get_metadata_routing)()          | Get metadata routing of this object.                                               |
| [`get_params`](#skfolio.moments.DetoneCovariance.get_params)([deep])              | Get parameters for this estimator.                                                 |
| [`mahalanobis`](#skfolio.moments.DetoneCovariance.mahalanobis)(X_test)             | Compute the squared Mahalanobis distance of observations.                          |
| [`score`](#skfolio.moments.DetoneCovariance.score)(X_test[, y])              | Compute the mean log-likelihood of observations under the estimated model.         |
| [`set_params`](#skfolio.moments.DetoneCovariance.set_params)(\*\*params)          | Set the parameters of this estimator.                                              |
| [`set_score_request`](#skfolio.moments.DetoneCovariance.set_score_request)(\*[, X_test]) | Configure whether metadata should be requested to be passed to the `score` method. |

### References

* <a id='r84b9a959864f-1'>**[1]**</a> “Machine Learning for Asset Managers”. Elements in Quantitative Finance. Lòpez de Prado (2020).

<a id="skfolio.moments.DetoneCovariance.fit"></a>

#### fit(X, y=None, \*\*fit_params)

Fit the Covariance Detoning estimator.

* **Parameters:**
  **X** *array-like of shape (n_observations, n_assets)*
  : Price returns of the assets.

  **y** *Ignored*
  : Not used, present for API consistency by convention.

  **\*\*fit_params** *dict*
  : Parameters to pass to the underlying estimators.
    Only available if `enable_metadata_routing=True`, which can be
    set by using `sklearn.set_config(enable_metadata_routing=True)`.
    See [Metadata Routing User Guide](https://skfolio.org/user_guide/metadata_routing.html.md#metadata-routing) for
    more details.
* **Returns:**
  **self** *DetoneCovariance*
  : Fitted estimator.

<a id="skfolio.moments.DetoneCovariance.get_metadata_routing"></a>

#### get_metadata_routing()

Get metadata routing of this object.

Please check [User Guide](https://skfolio.org/user_guide/metadata_routing.html.md#metadata-routing) on how the routing
mechanism works.

* **Returns:**
  **routing** *MetadataRequest*
  : A `MetadataRequest` encapsulating
    routing information.

<a id="skfolio.moments.DetoneCovariance.get_params"></a>

#### get_params(deep=True)

Get parameters for this estimator.

* **Parameters:**
  **deep** *bool, default=True*
  : If True, will return the parameters for this estimator and
    contained subobjects that are estimators.
* **Returns:**
  **params** *dict*
  : Parameter names mapped to their values.

<a id="skfolio.moments.DetoneCovariance.mahalanobis"></a>

#### mahalanobis(X_test)

Compute the squared Mahalanobis distance of observations.

The squared Mahalanobis distance of an observation $r$ is defined as:

$$
d^2 = (r - \mu)^T \Sigma^{-1} (r - \mu)

$$

where $\Sigma$ is the estimated covariance matrix (`self.covariance_`)
and $\mu$ is the estimated mean (`self.location_` if available, otherwise
zero).

This distance measure accounts for correlations between assets and is useful
for:

* Outlier detection in portfolio returns
* Risk-adjusted distance calculations
* Identifying unusual market regimes

* **Parameters:**
  **X_test** *array-like of shape (n_observations, n_assets) or (n_assets,)*
  : Observations for which to compute the squared Mahalanobis distance.
    Each row represents one observation. If 1D, treated as a single
    observation. Assets with non-finite fitted variance are excluded from
    inference. After this asset-level filtering, each row is evaluated
    using the remaining available values only, covering row-level missing
    values such as market holidays or pre/post-listing. When rows have
    different observation patterns, the returned distances follow
    $\chi^2$ distributions with different degrees of freedom.
    Rows with no finite retained observation return NaN.
* **Returns:**
  **distances** *ndarray of shape (n_observations,) or float*
  : Squared Mahalanobis distance for each observation. Returns a scalar
    if input is 1D.

### Examples

```pycon
>>> import numpy as np
>>> from skfolio.moments import EmpiricalCovariance
>>> rng = np.random.default_rng(0)
>>> X = rng.standard_normal((100, 3))
>>> model = EmpiricalCovariance()
>>> model.fit(X)
EmpiricalCovariance()
>>> distances = model.mahalanobis(X)
>>> # The mean squared distance should be close to the number of assets (3).
>>> print(distances.mean())
2.9...
```

<a id="skfolio.moments.DetoneCovariance.score"></a>

#### score(X_test, y=None)

Compute the mean log-likelihood of observations under the estimated model.

Evaluates how well the fitted covariance matrix explains new observations,
assuming a multivariate Gaussian distribution. This is useful for:

* Model selection (comparing different covariance estimators)
* Cross-validation of covariance estimation methods
* Assessing goodness-of-fit

The log-likelihood for a single observation $r$ is:

$$
\log p(r | \mu, \Sigma) = -\frac{1}{2} \left[
    n \log(2\pi) + \log|\Sigma| + (r - \mu)^T \Sigma^{-1} (r - \mu)
\right]

$$

where $n$ is the number of assets, $\Sigma$ is the estimated
covariance matrix (`self.covariance_`), and $\mu$ is the estimated
mean (`self.location_` if available, otherwise zero).

* **Parameters:**
  **X_test** *array-like of shape (n_observations, n_assets)*
  : Observations for which to compute the log-likelihood.
    Typically held-out test data not used during fitting.
    Assets with non-finite fitted variance are excluded from inference. This
    typically happens when the fitted covariance cannot be estimated for an
    asset, for example before listing, after delisting, or during a warmup
    period. After this asset-level filtering, each row of `X_test` is scored
    using the remaining available values only. This covers row-level missing
    values in `X_test`, such as market holidays or pre/post-listing.

  **y** *Ignored*
  : Not used, present for scikit-learn API consistency.
* **Returns:**
  **score** *float*
  : Mean log-likelihood of the observations. Higher values indicate better fit.
    The score is averaged over all observations.

### Examples

```pycon
>>> import numpy as np
>>> from skfolio.moments import EmpiricalCovariance, LedoitWolf
>>> rng = np.random.default_rng(0)
>>> X_train = rng.standard_normal((100, 5))
>>> X_test = rng.standard_normal((50, 5))
>>> emp = EmpiricalCovariance().fit(X_train)
>>> lw = LedoitWolf().fit(X_train)
>>> # Compare models on held-out data
>>> print("Empirical:", emp.score(X_test))
Empirical: -6.97...
>>> print("LedoitWolf:", lw.score(X_test))
LedoitWolf: -6.88...
```

<a id="skfolio.moments.DetoneCovariance.set_params"></a>

#### set_params(\*\*params)

Set the parameters of this estimator.

The method works on simple estimators as well as on nested objects
(such as `Pipeline`). The latter have
parameters of the form `<component>__<parameter>` so that it’s
possible to update each component of a nested object.

* **Parameters:**
  **\*\*params** *dict*
  : Estimator parameters.
* **Returns:**
  **self** *estimator instance*
  : Estimator instance.

<a id="skfolio.moments.DetoneCovariance.set_score_request"></a>

#### set_score_request(\*, X_test='$UNCHANGED$')

Configure whether metadata should be requested to be passed to the `score` method.

Note that this method is only relevant when this estimator is used as a
sub-estimator within a meta-estimator and metadata routing is enabled
with `enable_metadata_routing=True` (see `sklearn.set_config`).
Please check the [User Guide](https://skfolio.org/user_guide/metadata_routing.html.md#metadata-routing) on how the routing
mechanism works.

The options for each parameter are:

- `True`: metadata is requested, and passed to `score` if provided. The request is ignored if metadata is not provided.
- `False`: metadata is not requested and the meta-estimator will not pass it to `score`.
- `None`: metadata is not requested, and the meta-estimator will raise an error if the user provides it.
- `str`: metadata should be passed to the meta-estimator with this given alias instead of the original name.

The default (`sklearn.utils.metadata_routing.UNCHANGED`) retains the
existing request. This allows you to change the request for some
parameters and not others.

#### Versionadded
Added in version 1.3.

* **Parameters:**
  **X_test** *str, True, False, or None,                     default=sklearn.utils.metadata_routing.UNCHANGED*
  : Metadata routing for `X_test` parameter in `score`.
* **Returns:**
  **self** *object*
  : The updated object.

