<a id="skfolio-uncertainty-set-orthogonalmuuncertaintyset"></a>

# skfolio.uncertainty_set.OrthogonalMuUncertaintySet

<a id="skfolio.uncertainty_set.OrthogonalMuUncertaintySet"></a>

### *class* skfolio.uncertainty_set.OrthogonalMuUncertaintySet(confidence_level=0.95, cs_weighting=INVERSE_IDIO_VARIANCE, uncertainty_shape='identity')

Expected return uncertainty set estimator for directions outside the factor span.

This estimator builds a norm-ball uncertainty set for expected returns that are in
the subspace orthogonal to the factor-model loading matrix, under the selected
cross-sectional weighting metric.

It is intended for cases where orthogonal expected returns are considered less
reliable than spanned expected returns and is designed to reduce the tendency of
optimizers to overallocate in these directions. Rather than shrinking the orthogonal
expected returns in the prior, this estimator keeps the point estimate
$\hat{\mu}$ unchanged and adds a portfolio-dependent worst-case penalty that
grows with exposure to the orthogonal subspace [[1]](#r87c7fb2dc395-1) [[2]](#r87c7fb2dc395-2) [[3]](#r87c7fb2dc395-3).

Under this uncertainty set, the worst-case expected return for a portfolio with
weights $w$ is

$$
\inf_{\mu \in U_\mu} w^\top \mu
\;=\;
w^\top \hat{\mu}
-
\kappa \, \lVert L^\top w \rVert_2,
$$

where the low-rank geometry factor is

$$
L = G \Lambda^{1/2}.
$$

Here, $G$ is a basis for the subspace orthogonal to the factor-model span and
$\Lambda$ is a positive semidefinite scaling matrix that controls the
uncertainty assigned to each orthogonal direction.

Equivalently, the ellipsoidal shape matrix is [[4]](#r87c7fb2dc395-4):

$$
S_\mu = L L^\top = G \Lambda G^\top.
$$

If the factor model uses basket-neutral constraints, the loading matrix is first
reduced to its effective full-rank basis before the orthogonal subspace is computed.

* **Parameters:**
  **confidence_level** *float, default=0.95*
  : Confidence level $\beta$ used to set the uncertainty size
    $$
    \kappa = \sqrt{\chi^2_{\mathrm{rank}}(\beta)}.
    $$

  **cs_weighting** *CSWeighting, default=CSWeighting.INVERSE_IDIO_VARIANCE*
  : Cross-sectional weighting used to define the orthogonality metric.

  **uncertainty_shape** *{“identity”, “idio_variance”}, default=”identity”*
  : Shape used inside the orthogonal subspace.
    * `"identity"` assigns the same uncertainty to all orthogonal directions.
    * `"idio_variance"` scales uncertainty using projected idiosyncratic variance
      in the orthogonal subspace.
* **Attributes:**
  **uncertainty_set_** *UncertaintySet*
  : Fitted solver-ready uncertainty set with:
    * `uncertainty_set_.radius = kappa`
    * `uncertainty_set_.geometry = L = G Lambda^{1/2}`
    * `uncertainty_set_.norm = 2`

### Methods

| [`fit`](#skfolio.uncertainty_set.OrthogonalMuUncertaintySet.fit)(X[, y, return_distribution])                   | Fit the orthogonal mu uncertainty set.                                                   |
|-----------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------|
| [`get_metadata_routing`](#skfolio.uncertainty_set.OrthogonalMuUncertaintySet.get_metadata_routing)()                             | Get metadata routing of this object.                                                     |
| [`get_params`](#skfolio.uncertainty_set.OrthogonalMuUncertaintySet.get_params)([deep])                                 | Get parameters for this estimator.                                                       |
| [`partial_fit`](#skfolio.uncertainty_set.OrthogonalMuUncertaintySet.partial_fit)(X[, y, return_distribution])           | Update the orthogonal mu uncertainty set.                                                |
| [`set_fit_request`](#skfolio.uncertainty_set.OrthogonalMuUncertaintySet.set_fit_request)(\*[, return_distribution])         | Configure whether metadata should be requested to be passed to the `fit` method.         |
| [`set_params`](#skfolio.uncertainty_set.OrthogonalMuUncertaintySet.set_params)(\*\*params)                             | Set the parameters of this estimator.                                                    |
| [`set_partial_fit_request`](#skfolio.uncertainty_set.OrthogonalMuUncertaintySet.set_partial_fit_request)(\*[, return_distribution]) | Configure whether metadata should be requested to be passed to the `partial_fit` method. |

### Notes

This estimator requires a factor model in the fitted return distribution. When used
inside [`MeanRisk`](https://skfolio.org/generated/skfolio.optimization.MeanRisk.html.md#skfolio.optimization.MeanRisk), the `return_distribution` metadata
is passed automatically by `fit` and `partial_fit`.

### References

* <a id='r87c7fb2dc395-1'>**[1]**</a> “Robustness properties of mean-variance portfolios”, Optimization: A Journal of Mathematical Programming and Operations Research, Schöttle & Werner (2009).
* <a id='r87c7fb2dc395-2'>**[2]**</a> “Portfolio Optimization: Theory and Application”, Chapter 14, Daniel P. Palomar (2025)
* <a id='r87c7fb2dc395-3'>**[3]**</a> “Robust Portfolio Selection Problems”, Mathematics of Operations Research, Goldfarb and Iyengar (2003).
* <a id='r87c7fb2dc395-4'>**[4]**</a> “Robust Convex Optimization”, Mathematics of Operations Research, Ben-Tal and Nemirovski (1998).

<a id="skfolio.uncertainty_set.OrthogonalMuUncertaintySet.fit"></a>

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

Fit the orthogonal mu uncertainty set.

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

  **y** *array-like of shape (n_observations, n_factors), optional*
  : Price returns of factors. The default is `None`.

  **return_distribution** *ReturnDistribution, optional*
  : The fitted return distribution from the prior estimator.
    Passed internally by [`MeanRisk`](https://skfolio.org/generated/skfolio.optimization.MeanRisk.html.md#skfolio.optimization.MeanRisk). Must contain a
    `factor_model` with `loading_matrix` and `idio_covariance`.

  **\*\*fit_params** *dict*
  : Additional parameters (unused).
* **Returns:**
  **self** *OrthogonalMuUncertaintySet*
  : Fitted estimator.

<a id="skfolio.uncertainty_set.OrthogonalMuUncertaintySet.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.uncertainty_set.OrthogonalMuUncertaintySet.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.uncertainty_set.OrthogonalMuUncertaintySet.partial_fit"></a>

#### partial_fit(X, y=None, \*, return_distribution=None, \*\*fit_params)

Update the orthogonal mu uncertainty set.

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

  **y** *array-like of shape (n_observations, n_factors), optional*
  : Price returns of factors. The default is `None`.

  **return_distribution** *ReturnDistribution, optional*
  : The fitted return distribution from the prior estimator.
    Passed internally by [`MeanRisk`](https://skfolio.org/generated/skfolio.optimization.MeanRisk.html.md#skfolio.optimization.MeanRisk). Must contain a
    `factor_model` with `loading_matrix` and `idio_covariance`.

  **\*\*fit_params** *dict*
  : Additional parameters (unused).
* **Returns:**
  **self** *OrthogonalMuUncertaintySet*
  : Updated estimator.

<a id="skfolio.uncertainty_set.OrthogonalMuUncertaintySet.set_fit_request"></a>

#### set_fit_request(\*, return_distribution='$UNCHANGED$')

Configure whether metadata should be requested to be passed to the `fit` 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 `fit` 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 `fit`.
- `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:**
  **return_distribution** *str, True, False, or None,                     default=sklearn.utils.metadata_routing.UNCHANGED*
  : Metadata routing for `return_distribution` parameter in `fit`.
* **Returns:**
  **self** *object*
  : The updated object.

<a id="skfolio.uncertainty_set.OrthogonalMuUncertaintySet.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.uncertainty_set.OrthogonalMuUncertaintySet.set_partial_fit_request"></a>

#### set_partial_fit_request(\*, return_distribution='$UNCHANGED$')

Configure whether metadata should be requested to be passed to the `partial_fit` 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 `partial_fit` 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 `partial_fit`.
- `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:**
  **return_distribution** *str, True, False, or None,                     default=sklearn.utils.metadata_routing.UNCHANGED*
  : Metadata routing for `return_distribution` parameter in `partial_fit`.
* **Returns:**
  **self** *object*
  : The updated object.

