<a id="skfolio-prior-factormodel"></a>

# skfolio.prior.FactorModel

<a id="skfolio.prior.FactorModel"></a>

### *class* skfolio.prior.FactorModel(observations, asset_names, factor_names, factor_families, loading_matrix, exposures, factor_covariance, factor_mu, factor_returns, idio_covariance, idio_mu, idio_returns, idio_variances, exposure_lag=1, regression_weights=None, benchmark_weights=None, family_constraint_basis=None)

Factor model decomposition of asset returns.

Holds the loading matrix, factor moments and idiosyncratic covariance, together with
the optional time series of exposures, factor returns and idiosyncratic returns.
Exposes a factor-structured covariance square root, plus cross-sectional regression
diagnostics, idiosyncratic-calibration metrics and factor attribution when the
relevant fields are populated.

Produced by factor-model prior estimators:

> * [`TimeSeriesFactorModel`](https://skfolio.org/generated/skfolio.prior.TimeSeriesFactorModel.html.md#skfolio.prior.TimeSeriesFactorModel),
> * [`CharacteristicsFactorModel`](https://skfolio.org/generated/skfolio.prior.CharacteristicsFactorModel.html.md#skfolio.prior.CharacteristicsFactorModel)

and consumed downstream via `factor_model`.

* **Attributes:**
  **observations** *ndarray of shape (n_observations,)*
  : Time index labels.

  **asset_names** *ndarray of shape (n_assets,)*
  : Asset names.

  **factor_names** *ndarray of shape (n_factors,)*
  : Factor names (e.g. `"value"`, `"momentum"`).

  **factor_families** *ndarray of shape (n_factors,) or None*
  : Family label for each factor (e.g. `"style"`, `"industry"`).
    Populated by cross-sectional factor models.

  **loading_matrix** *ndarray of shape (n_assets, n_factors)*
  : Asset-by-factor loading (exposure) matrix. Time-invariant for time-series factor
    models; the most recent point-in-time loadings for cross-sectional factor models
    (full history in `exposures`).

  **exposures** *ndarray of shape (n_observations, n_assets, n_factors) or None*
  : Full historical time series of asset-by-factor exposure (loading) matrices
    following the as-of time-indexing convention. Populated for cross-sectional
    factor models. `None` for time-series factor models, which use the single
    time-invariant `loading_matrix`.

  **factor_covariance** *ndarray of shape (n_factors, n_factors)*
  : Factor return covariance matrix. Under family constraints this full-basis
    matrix is rank-deficient; use [`effective_factor_covariance`](#skfolio.prior.FactorModel.effective_factor_covariance) (paired with
    [`effective_loading_matrix`](#skfolio.prior.FactorModel.effective_loading_matrix)) for decompositions such as Cholesky.

  **factor_mu** *ndarray of shape (n_factors,)*
  : Expected factor returns.

  **factor_returns** *ndarray of shape (n_observations, n_factors) or None*
  : Per-period factor returns. For time-series factor models, this is the input
    factor return series; for cross-sectional factor models, this is the per-period
    factor returns estimated from the cross-sectional regression.

  **idio_covariance** *ndarray of shape (n_assets, n_assets) or (n_assets,)*
  : Idiosyncratic covariance (diagonal vector or full matrix).

  **idio_mu** *ndarray of shape (n_assets,) or None*
  : Factor-orthogonal expected return for each asset, also called orthogonal alpha.
    With the default weighted least-squares projection, it satisfies
    $B^\top W\,\text{idio\_mu}=0$. Custom robust or regularized
    cross-sectional regressors may produce a component that is only approximately
    orthogonal. Distinct from the time-series mean of `idio_returns`, which is not
    enforced to be factor-orthogonal. Populated by cross-sectional factor models.

  **idio_returns** *ndarray of shape (n_observations, n_assets) or None*
  : Per-period idiosyncratic returns, obtained from the corresponding factor
    regression. For time-series factor models, these are
    $r - a - Bf$, where $a$ is the vector of time-series regression
    intercepts. For cross-sectional factor models, these are
    $R(t) - B(t-\ell)f(t)$.

  **idio_variances** *ndarray of shape (n_observations, n_assets) or None*
  : Time-varying per-asset predicted idiosyncratic variances
    $\hat\sigma^2_{i,t}$. Populated by cross-sectional factor models.

  **exposure_lag** *int, default=1*
  : Lag applied to time-varying exposures under the as-of time-indexing convention.
    The default value of `1` aligns exposures at $t-1$ with returns over
    $(t-1, t]$. Meaningful only when `exposures` is populated; ignored by
    time-series factor models, where the loading matrix is constant.

  **regression_weights** *ndarray of shape (n_observations, n_assets) or None*
  : Cross-sectional WLS regression weights. Non-negative. Assets with zero weight
    are excluded from the estimation universe. Row $t$ holds the weights
    used by the regression at date $t$; like the lagged exposures, they are
    built from market caps at $t - \text{lag}$ and idiosyncratic variances
    estimated up to $t - 1$. `None` for time-series factor models.

  **benchmark_weights** *ndarray of shape (n_observations, n_assets) or None*
  : Benchmark weights used for weighted cross-sectional diagnostics. Non-negative.
    `None` for time-series factor models.

  **family_constraint_basis** *FamilyConstraintBasis or None*
  : Compact basis encoding the family-constraint change of coordinates. Used by
    cross-sectional factor models with linear constraints across factor families
    (e.g. industry sum-to-zero). When present, diagnostics (t-statistics, VIF,
    condition number) and adjusted $R^2$ are computed in the reduced basis
    where constrained families are full-rank.

### Methods

| [`cs_regression_t_stat_exceedance_rate`](#skfolio.prior.FactorModel.cs_regression_t_stat_exceedance_rate)([threshold])   | Fraction of observations with significant cross-sectional regression t-statistics.                                       |
|------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------|
| [`enrich_asset_panel`](#skfolio.prior.FactorModel.enrich_asset_panel)(panel[, copy])                   | Add factor-model fields to an [`AssetPanel`](https://skfolio.org/generated/skfolio.containers.AssetPanel.html.md#skfolio.containers.AssetPanel). |
| [`exposure_correlation`](#skfolio.prior.FactorModel.exposure_correlation)([factors, families, ...])      | Time-average pairwise correlation matrix of factor exposures.                                                            |
| [`exposure_ic_summary`](#skfolio.prior.FactorModel.exposure_ic_summary)([correlation_method, ...])      | Summary statistics for exposure Information Coefficients (ICs).                                                          |
| [`factor_forecast_correlation`](#skfolio.prior.FactorModel.factor_forecast_correlation)([factors, families])    | Factor return correlation forecast from `factor_covariance`.                                                             |
| [`idio_calibration_summary`](#skfolio.prior.FactorModel.idio_calibration_summary)()                          | Summary statistics for the calibration quality of standardized idiosyncratic                                             |
| [`idio_tail_rate`](#skfolio.prior.FactorModel.idio_tail_rate)([threshold])                         | Fraction of assets with extreme standardized idiosyncratic returns.                                                      |
| [`plot_cs_regression_scores`](#skfolio.prior.FactorModel.plot_cs_regression_scores)([score, window, title])   | Plot a cross-sectional regression score over time.                                                                       |
| [`plot_cs_regression_t_stat_exceedance_rate`](#skfolio.prior.FactorModel.plot_cs_regression_t_stat_exceedance_rate)([...])    | Bar chart of the cross-sectional regression t-statistic exceedance rate.                                                 |
| [`plot_cs_regression_t_stats`](#skfolio.prior.FactorModel.plot_cs_regression_t_stats)([factors, ...])          | Plot absolute cross-sectional regression t-statistics over time per factor.                                              |
| [`plot_cumulative_exposure_ic`](#skfolio.prior.FactorModel.plot_cumulative_exposure_ic)([...])                  | Cumulative exposure Information Coefficient (IC) over time.                                                              |
| [`plot_exposure_condition_number`](#skfolio.prior.FactorModel.plot_exposure_condition_number)([window, title])     | Plot the exposure Gram-matrix condition number over time.                                                                |
| [`plot_exposure_correlation`](#skfolio.prior.FactorModel.plot_exposure_correlation)([factors, ...])           | Time-average pairwise correlation heatmap of factor exposures.                                                           |
| [`plot_exposure_dispersion`](#skfolio.prior.FactorModel.plot_exposure_dispersion)([factors, ...])            | Cross-sectional standard deviation of exposures over time.                                                               |
| [`plot_exposure_distribution`](#skfolio.prior.FactorModel.plot_exposure_distribution)(factor[, ...])           | Cross-sectional histogram of exposures for a single factor.                                                              |
| [`plot_exposure_stability`](#skfolio.prior.FactorModel.plot_exposure_stability)([factors, families, ...])   | Weighted cross-sectional correlation of exposures between observation $t$ and $t + \text{step}$ over time.               |
| [`plot_exposure_vif`](#skfolio.prior.FactorModel.plot_exposure_vif)([factors, families, ...])         | Plot exposure Variance Inflation Factors over time per factor.                                                           |
| [`plot_factor_cumulative_returns`](#skfolio.prior.FactorModel.plot_factor_cumulative_returns)([factors, ...])      | Cumulative (non-compounded) factor returns over time.                                                                    |
| [`plot_factor_forecast_correlation`](#skfolio.prior.FactorModel.plot_factor_forecast_correlation)([factors, ...])    | Factor return correlation forecast heatmap from `factor_covariance`.                                                     |
| [`plot_factor_forecast_volatilities`](#skfolio.prior.FactorModel.plot_factor_forecast_volatilities)([factors, ...])   | Bar chart of annualized factor volatility forecasts.                                                                     |
| [`plot_idio_calibration`](#skfolio.prior.FactorModel.plot_idio_calibration)([window, title])              | Cross-sectional std of standardized idiosyncratic returns over time.                                                     |
| [`plot_idio_kurtosis`](#skfolio.prior.FactorModel.plot_idio_kurtosis)([window, title])                 | Cross-sectional excess kurtosis of standardised idiosyncratic returns over time.                                         |
| [`plot_idio_skewness`](#skfolio.prior.FactorModel.plot_idio_skewness)([window, title])                 | Cross-sectional skewness of standardised idiosyncratic returns over time.                                                |
| [`plot_idio_tail_rate`](#skfolio.prior.FactorModel.plot_idio_tail_rate)([threshold, window, title])     | Plot the idiosyncratic tail exceedance rate over time.                                                                   |
| [`plot_idio_vol_ic`](#skfolio.prior.FactorModel.plot_idio_vol_ic)([window, title])                   | Information Coefficient (IC) of idiosyncratic volatility estimates.                                                      |
| [`plot_idio_vol_residual_dependence`](#skfolio.prior.FactorModel.plot_idio_vol_residual_dependence)([window, ...])    | Residual dependence of standardized idiosyncratic returns on predicted idiosyncratic volatility.                         |
| [`predicted_attribution`](#skfolio.prior.FactorModel.predicted_attribution)(weights[, ...])               | Compute ex-ante (predicted) factor volatility and return attribution.                                                    |
| [`realized_attribution`](#skfolio.prior.FactorModel.realized_attribution)(weights, portfolio_returns)    | Compute realized (ex-post) factor volatility and return attribution.                                                     |
| [`rolling_realized_attribution`](#skfolio.prior.FactorModel.rolling_realized_attribution)(weights, ...[, ...])   | Compute rolling realized (ex-post) factor attribution.                                                                   |
| [`select_assets`](#skfolio.prior.FactorModel.select_assets)([assets, slim])                       | Return a new `FactorModel` restricted to selected assets.                                                                |
| [`select_observations`](#skfolio.prior.FactorModel.select_observations)(observations)                   | Return a new `FactorModel` restricted to selected observations.                                                          |
| [`summary`](#skfolio.prior.FactorModel.summary)([factors, families, ...])                   | Summary statistics for the factor model.                                                                                 |

<a id="skfolio.prior.FactorModel.covariance_sqrt"></a>

#### *property* covariance_sqrt

Covariance square root exploiting the factor structure.

Decomposes the asset covariance $\Sigma = B\,\Sigma_f\,B^\top + D$ into a
[`CovarianceSqrt`](https://skfolio.org/generated/skfolio.prior.CovarianceSqrt.html.md#skfolio.prior.CovarianceSqrt) that separates the systematic and
idiosyncratic contributions, allowing SOC-based optimizers to work with smaller
matrices.

When idiosyncratic covariance is diagonal, the decomposition avoids an
$(n \times n)$ Cholesky entirely and represents the idiosyncratic part as
an element-wise multiply.

When family constraints are present, the full-basis factor covariance
$R\,\Sigma_f^{\mathrm{red}}\,R^\top$ is rank-deficient. The systematic
square root is then built from the full-rank [`effective_loading_matrix`](#skfolio.prior.FactorModel.effective_loading_matrix)
and [`effective_factor_covariance`](#skfolio.prior.FactorModel.effective_factor_covariance), which keeps the Cholesky exact and the
systematic component minimal.

* **Returns:**
  CovarianceSqrt

<a id="skfolio.prior.FactorModel.cs_regression_scores"></a>

#### *property* cs_regression_scores

Fit diagnostics for each cross-sectional factor regression.

This property is available when the model contains point-in-time
exposures, estimated factor returns and idiosyncratic returns, as in
characteristics-based cross-sectional factor models. It is not available
for time-series factor models without point-in-time exposures.

* `r2`: cross-sectional $R^2$,

$$
R^2_t = 1 - \frac{\sum_i w_{ti}\,\varepsilon_{ti}^2}
                 {\sum_i w_{ti}\,(r_{ti} - \bar{r}_t)^2}
$$

* `adjusted_r2`: $R^2$ adjusted for the effective number of regressors
  $k$,

$$
\bar{R}^2_t = 1 - (1 - R^2_t)\,\frac{n_t - 1}{n_t - k - 1}
$$

* `aic`: Akaike Information Criterion,

$$
\mathrm{AIC}_t = n_t \ln\!\left(\frac{\mathrm{RSS}_t}{n_t}\right) + 2k
$$

* `bic`: Bayesian Information Criterion,

$$
\mathrm{BIC}_t = n_t \ln\!\left(\frac{\mathrm{RSS}_t}{n_t}\right)
+ k \ln(n_t)
$$

Here $n_t$ is the number of valid samples at observation $t$ and
$k = \text{n\_regressors}$ is the effective number of regressors (reduced
dimension when family constraints are active). Lower AIC/BIC indicate a better
fit-complexity trade-off; BIC penalises complexity more heavily than AIC for
large cross-sections.

* **Returns:**
  **scores** *DataFrame of shape (n_observations - exposure_lag, 4)*
  : Index aligned with the lagged regression observations.
    Columns: `r2`, `adjusted_r2`, `aic`, `bic`.

<a id="skfolio.prior.FactorModel.cs_regression_t_stat_exceedance_rate"></a>

#### cs_regression_t_stat_exceedance_rate(threshold=2.0)

Fraction of observations with significant cross-sectional regression t-statistics.

The t-statistic exceedance rate measures how often a factor’s cross-sectional
t-statistic exceeds the absolute threshold: $|t| > \text{threshold}$.
With `threshold=2.0`, a factor whose true cross-sectional coefficient is zero
and whose t-statistics are approximately Gaussian would exceed the threshold
about 5 % of the time. Rates above this reference level indicate that the factor
is repeatedly significant across observations.

* **Parameters:**
  **threshold** *float, default=2.0*
  : Absolute t-statistic threshold for significance.
* **Returns:**
  **cs_regression_t_stat_exceedance_rate** *Series*
  : Shape `(n_reduced_factors,)`.
    Fraction of significant observations per factor.

<a id="skfolio.prior.FactorModel.cs_regression_t_stats"></a>

#### *property* cs_regression_t_stats

Cross-sectional regression coefficient t-statistics.

$$
t_{tj} = \frac{\hat{\beta}_{tj}}{\mathrm{SE}(\hat{\beta}_{tj})}
$$

where $\hat{\beta}_{tj}$ is the estimated coefficient of factor
$j$ at observation $t$. In a cross-sectional factor model,
this coefficient is the per-observation factor return. The standard error is
derived from $\hat\sigma^2_t (X^\top W X)^{-1}$.

A common rule of thumb is that $|t| > 2$ suggests significance at
approximately the 5 % level.

When `family_constraint_basis` is set, the design matrix and factor
returns are projected into the reduced (full-rank) basis, so the columns are the
reduced-basis factor names rather than the full `factor_names`.

* **Returns:**
  **cs_regression_t_stats** *DataFrame*
  : Time-indexed t-statistics of shape
    `(n_observations - exposure_lag, n_reduced_factors)`.

<a id="skfolio.prior.FactorModel.effective_exposures"></a>

#### *property* effective_exposures

Full-rank historical exposures, reduced when family constraints are present.

When the factor model uses family constraints, the full-basis exposure tensor is
rank-deficient because constrained factor families introduce linear dependencies
among columns. This property converts the historical exposures to the same
reduced full-rank basis as [`effective_loading_matrix`](#skfolio.prior.FactorModel.effective_loading_matrix).

When `family_constraint_basis` is `None`, the historical exposures are
returned unchanged.

* **Returns:**
  **exposures** *ndarray of shape (n_observations, n_assets, n_reduced_factors)*
  : Historical full-rank exposure tensor.

<a id="skfolio.prior.FactorModel.effective_factor_covariance"></a>

#### *property* effective_factor_covariance

Full-rank factor covariance, reduced when family constraints are present.

When the factor model uses family constraints, the full-basis factor covariance
$R\,\Sigma_f^{\mathrm{red}}\,R^\top$ is rank-deficient. This property
returns the reduced full-rank covariance aligned with
[`effective_loading_matrix`](#skfolio.prior.FactorModel.effective_loading_matrix), so that decompositions (e.g. Cholesky) and
SOC-based optimizers operate on a positive definite matrix.

When `family_constraint_basis` is `None`, the covariance is returned
unchanged.

* **Returns:**
  **factor_covariance** *ndarray of shape (n_reduced_factors, n_reduced_factors)*
  : Full-rank factor covariance.

<a id="skfolio.prior.FactorModel.effective_factor_families"></a>

#### *property* effective_factor_families

Factor families aligned with the effective reduced basis.

<a id="skfolio.prior.FactorModel.effective_factor_names"></a>

#### *property* effective_factor_names

Factor names aligned with the effective reduced basis.

<a id="skfolio.prior.FactorModel.effective_loading_matrix"></a>

#### *property* effective_loading_matrix

Full-rank loading matrix, reduced when family constraints are present.

When the factor model uses family constraints, the full-basis loading matrix is
rank-deficient because constrained factor families introduce linear dependencies
among columns. This property converts it to the reduced (full-rank) basis so
that downstream computations (e.g. orthogonal projectors) correctly identify the
factor span.

When `family_constraint_basis` is `None`, the loading matrix is returned
unchanged.

* **Returns:**
  **loading** *ndarray of shape (n_assets, n_reduced_factors)*
  : Full-rank loading matrix.

<a id="skfolio.prior.FactorModel.enrich_asset_panel"></a>

#### enrich_asset_panel(panel, copy=True)

Add factor-model fields to an [`AssetPanel`](https://skfolio.org/generated/skfolio.containers.AssetPanel.html.md#skfolio.containers.AssetPanel).

The returned panel contains the fields required by alpha estimators:
`idio_returns`, `idio_variances`, `regression_weights` and `exposures`.
Observations and assets are aligned by label. Panel observations that are not
present in the factor model are kept and filled with missing values, except
`regression_weights`, which is filled with zero. The asset set must match
exactly, although the order may differ. If `panel` is an
[`AssetPanelView`](https://skfolio.org/generated/skfolio.containers.AssetPanelView.html.md#skfolio.containers.AssetPanelView), enriched fields are added as
view-local fields.

When family constraints are present, `exposures` are added in the reduced
full-rank basis used by the cross-sectional regression and factor covariance
estimator.

* **Parameters:**
  **panel** *AssetPanel or AssetPanelView*
  : Panel or observation view to enrich.

  **copy** *bool, default=True*
  : If `True`, enrich a shallow copy of `panel`. If `False`, mutate `panel`.
* **Returns:**
  **enriched_panel** *AssetPanel or AssetPanelView*
  : Panel or view containing the factor-model fields.
* **Raises:**
  TypeError
  : If `panel` is not an [`AssetPanel`](https://skfolio.org/generated/skfolio.containers.AssetPanel.html.md#skfolio.containers.AssetPanel) or
    [`AssetPanelView`](https://skfolio.org/generated/skfolio.containers.AssetPanelView.html.md#skfolio.containers.AssetPanelView).

  ValueError
  : If required factor-model histories are unavailable, if labels cannot be
    aligned, or if any target field already exists.

<a id="skfolio.prior.FactorModel.exposure_condition_number"></a>

#### *property* exposure_condition_number

Condition number of the exposure Gram matrix per observation.

The condition number $\kappa(X^\top W X)$ is the ratio of the largest to
smallest singular value. Large values indicate near-singular design matrices
and numerically unstable coefficient estimates. When `family_constraint_basis`
is set, the Gram matrix is built in the reduced (full-rank) basis.

* **Returns:**
  **exposure_condition_number** *Series*
  : Time-indexed condition numbers of shape
    `(n_observations - exposure_lag,)`.

<a id="skfolio.prior.FactorModel.exposure_correlation"></a>

#### exposure_correlation(factors=None, families=None, cs_weighting=BENCHMARK)

Time-average pairwise correlation matrix of factor exposures.

Highly correlated exposures indicate redundant factors. They are a
cross-sectional analogue of multicollinearity diagnostics used in regression,
where redundant predictors can inflate variance inflation factors (VIFs).

Pairs involving a factor with degenerate cross-sectional variance (e.g. the
constant global factor exposure) have an undefined correlation and are
reported as zero by convention. When two factors are never finite on at
least 3 common assets at any observation, their correlation cannot be
estimated and is reported as NaN.

* **Parameters:**
  **factors** *list of str, optional*
  : Explicit subset of factor names. Takes precedence over `families` when
    specified.

  **families** *str, list of str, or None, optional*
  : Factor families to include. `None` includes all factors. Ignored when
    `factors` is given or when `factor_families` is `None`.

  **cs_weighting** *CSWeighting, default=CSWeighting.BENCHMARK*
  : Cross-sectional weights for the correlation computation. Falls back
    to `CSWeighting.IDENTITY` with a warning when unavailable.
* **Returns:**
  **corr** *ndarray of shape (n_selected_factors, n_selected_factors)*
  : Time-average correlation matrix.

<a id="skfolio.prior.FactorModel.exposure_ic_summary"></a>

#### exposure_ic_summary(correlation_method=SPEARMAN, horizon=1, factors=None, families=None)

Summary statistics for exposure Information Coefficients (ICs).

Measures the cross-sectional correlation between factor exposures at $t$
and the forward mean asset return from $t + 1$ to $t + h$, where
$h$ is the forecast *horizon*.

#### NOTE
The IC quantifies **return-predictive** power. In a **risk model**, factors
are designed to explain covariance structure, not to predict expected
returns. A factor can be an excellent risk factor even when
$\mathbb{E}[\text{IC}] \approx 0$. Do not discard a risk factor solely
because its IC is low: use exposure stability, bias statistics, and variance
contribution instead.

* **Parameters:**
  **correlation_method** *CorrelationMethod, default=CorrelationMethod.SPEARMAN*
  : Correlation method used for the exposure IC. `SPEARMAN` computes
    Spearman rank IC. `PEARSON` computes Pearson IC, weighted by
    `regression_weights` when available.

  **horizon** *int, default=1*
  : Forward window in number of observations. The mean return from
    $t + 1$ to $t + h$ is used.

  **factors** *list of str, optional*
  : Explicit subset of factor names. Takes precedence over `families` when
    specified.

  **families** *str, list of str, optional*
  : Factor families to include. `None` includes all factors.
* **Returns:**
  **summary** *DataFrame of shape (n_selected_factors, 4)*
  : Columns: `mean_ic`, `std_ic`, `ic_ir`, `hit_rate`.

<a id="skfolio.prior.FactorModel.exposure_vif"></a>

#### *property* exposure_vif

Variance Inflation Factor of the exposure design per observation.

VIF measures how much the variance of a cross-sectional regression coefficient
is inflated due to collinearity among factor exposures:

$$
\mathrm{VIF}_k = (X^\top W X)_{kk} \cdot
                 [(X^\top W X)^{-1}]_{kk}
$$

A VIF of 1 indicates no collinearity; values above 5-10 suggest problematic
multicollinearity.

When `family_constraint_basis` is set, VIFs are computed in the reduced
(full-rank) basis.

* **Returns:**
  **exposure_vif** *DataFrame*
  : Time-indexed VIF values of shape
    `(n_observations - exposure_lag, n_reduced_factors)`.

<a id="skfolio.prior.FactorModel.exposures_df"></a>

#### *property* exposures_df

Exposures as a MultiIndex DataFrame of shape
(n_observations, n_factors \* n_assets).

<a id="skfolio.prior.FactorModel.factor_forecast_correlation"></a>

#### factor_forecast_correlation(factors=None, families=None)

Factor return correlation forecast from `factor_covariance`.

* **Parameters:**
  **factors** *list of str, optional*
  : Explicit subset of factor names. Takes precedence over
    `families` when specified.

  **families** *str, list of str, optional*
  : Factor families to include. `None` includes all factors.
    Ignored when `factors` is given or when
    `factor_families` is `None`.
* **Returns:**
  **corr** *ndarray of shape (n_selected_factors, n_selected_factors)*
  : Symmetric factor return correlation matrix with diagonal entries
    fixed to 1.

<a id="skfolio.prior.FactorModel.factor_returns_df"></a>

#### *property* factor_returns_df

Factor returns DataFrame of shape (n_observations, n_factors).

<a id="skfolio.prior.FactorModel.idio_calibration"></a>

#### *property* idio_calibration

Cross-sectional std of standardized idiosyncratic returns.

<a id="skfolio.prior.FactorModel.idio_calibration_summary"></a>

#### idio_calibration_summary()

Summary statistics for the calibration quality of standardized idiosyncratic
: returns.

Computes time-aggregated statistics of the cross-sectional distribution of
standardized idiosyncratic returns
$z_{it} = \epsilon_{it} / \hat\sigma_{i,t}$.

Under a Gaussian assumption, the expected values are $\text{std}(z) = 1$,
excess kurtosis $= 0$, skewness $= 0$, and the 3-$\sigma$ tail
rate $\approx 0.27\%$. In practice, standardized idiosyncratic returns
exhibit fat tails, so the tail rate is typically well above 0.27% (values
around 1–3% are common for equity factor models).

- `mean_cs_std` close to 1.0 indicates correctly scaled specific risk.
  Values persistently above 1 suggest underestimated risk; below 1 suggests
  overestimated risk.
- `mean_tail_rate_3sigma` is expected to exceed the Gaussian reference due to
  fat tails.
- `mean_cs_excess_kurtosis` > 0 (fat tails) and moderate `mean_cs_skewness` are
  typical.

* **Returns:**
  **summary** *Series*
  : Index: `mean_cs_std`, `median_cs_std`, `mean_cs_excess_kurtosis`,
    `mean_cs_skewness`, `mean_tail_rate_3sigma`.

<a id="skfolio.prior.FactorModel.idio_kurtosis"></a>

#### *property* idio_kurtosis

Cross-sectional excess kurtosis of standardized idiosyncratic returns.

<a id="skfolio.prior.FactorModel.idio_returns_df"></a>

#### *property* idio_returns_df

Idiosyncratic returns DataFrame of shape (n_observations, n_assets).

<a id="skfolio.prior.FactorModel.idio_skewness"></a>

#### *property* idio_skewness

Cross-sectional skewness of standardized idiosyncratic returns.

<a id="skfolio.prior.FactorModel.idio_tail_rate"></a>

#### idio_tail_rate(threshold=3.0)

Fraction of assets with extreme standardized idiosyncratic returns.

For each observation, computes the cross-sectional fraction of available
standardized idiosyncratic returns whose absolute value exceeds
`threshold`:

$$
\frac{1}{n_t}\sum_i \mathbf{1}\{|z_{i,t}| > c\},
$$

where $z_{i,t}$ is the standardized idiosyncratic return, $c$
is `threshold`, and $n_t$ is the number of finite standardized
idiosyncratic returns at observation $t$.

Under a Gaussian reference model, the expected rate is
$2\Phi(-c)$. Higher realized rates indicate that the standardized
residuals have heavier tails than implied by the idiosyncratic volatility
estimates. In equity factor models, standardized idiosyncratic returns
are often fat-tailed, so rates above the Gaussian reference are common.

* **Parameters:**
  **threshold** *float, default=3.0*
  : Absolute standardized-return threshold $c$.
* **Returns:**
  **tail_rate** *Series of shape (n_observations,)*
  : Time series of cross-sectional tail exceedance rates, indexed by
    `observations`.

<a id="skfolio.prior.FactorModel.idio_vol_ic"></a>

#### *property* idio_vol_ic

Information Coefficient of idiosyncratic volatility estimates.

Computes the cross-sectional rank correlation (Spearman) between the predicted
specific volatility $\hat\sigma_{i,t}$ and the next-period absolute
idiosyncratic return $|\epsilon_{i,t+1}|$.

If the model captures the cross-sectional scale of idiosyncratic shocks, then
assets with larger $\hat\sigma_{i,t}$ should tend to realize larger
absolute moves at $t + 1$.

* High positive values indicate that the model ranks cross-sectional differences
  in idiosyncratic volatility well.
* This diagnostic can also pick up broad cross-sectional scale effects such as
  size or liquidity, so it should be read together with
  [`idio_vol_residual_dependence`](#skfolio.prior.FactorModel.idio_vol_residual_dependence) which checks whether the standardized
  idiosyncratic return magnitude $|z_{i,t+1}|$ still depends on the
  predicted volatility level.

<a id="skfolio.prior.FactorModel.idio_vol_residual_dependence"></a>

#### *property* idio_vol_residual_dependence

Residual dependence of standardized idiosyncratic returns on predicted
idiosyncratic volatility.

Computes the cross-sectional rank correlation (Spearman) between the predicted
specific volatility $\hat\sigma_{i,t}$ and the next-period standardized
absolute idiosyncratic return
$|\epsilon_{i,t+1}| / \hat\sigma_{i,t} = |z_{i,t+1}|$.
If the volatility forecast is well calibrated, this standardized magnitude
should be roughly independent of $\hat\sigma_{i,t}$, so the correlation
should be close to 0.

Read together with [`idio_vol_ic`](#skfolio.prior.FactorModel.idio_vol_ic), this diagnostic helps separate ranking
power from calibration. A desirable pattern is a high [`idio_vol_ic`](#skfolio.prior.FactorModel.idio_vol_ic)
combined with residual dependence near 0.

<a id="skfolio.prior.FactorModel.plot_cs_regression_scores"></a>

#### plot_cs_regression_scores(score='adjusted_r2', window=30, title=None)

Plot a cross-sectional regression score over time.

Draws the selected per-observation score as a faded line and overlays its
rolling mean over `window` observations to highlight changes in fit quality.
A horizontal line marks the full-sample average and is annotated with its
numerical value.

* **Parameters:**
  **score** *str, default=”adjusted_r2”*
  : Score to plot. Must be one of `"r2"`, `"adjusted_r2"`, `"aic"`, or `"bic"`.

  **window** *int, default=30*
  : Number of observations required for the rolling mean.

  **title** *str, optional*
  : Custom title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_cs_regression_t_stat_exceedance_rate"></a>

#### plot_cs_regression_t_stat_exceedance_rate(factors=None, families=None, threshold=2.0, title=None)

Bar chart of the cross-sectional regression t-statistic exceedance rate.

The t-statistic exceedance rate is the fraction of observations where
$|t| >$ `threshold`. A vertical reference line at 5% marks the
conventional null-rate benchmark used at `threshold = 2`; for other thresholds
it is only an approximate guide and the exact Gaussian null rate is
$2\,\Phi(-\text{threshold})$.

* **Parameters:**
  **factors** *list of str, optional*
  : Subset of factor names to include. Takes precedence over `families` when
    specified.

  **families** *str, list of str, optional*
  : Factor families to include. Ignored when `factors` is given.

  **threshold** *float, default=2.0*
  : Absolute t-statistic threshold.

  **title** *str, optional*
  : Custom title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_cs_regression_t_stats"></a>

#### plot_cs_regression_t_stats(factors=None, families=None, window=None, title=None)

Plot absolute cross-sectional regression t-statistics over time per factor.

When `window` is provided, plots the rolling mean of $|t|$ over
`window` observations instead of the raw values. A horizontal reference line
at $|t| = 2$ marks the conventional significance threshold.

* **Parameters:**
  **factors** *list of str, optional*
  : Subset of factor names to include.

  **families** *str, list of str, optional*
  : Factor families to include. Ignored when `factors` is given.

  **window** *int, optional*
  : If provided, plot the rolling mean of $|t|$.

  **title** *str, optional*
  : Custom title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_cumulative_exposure_ic"></a>

#### plot_cumulative_exposure_ic(correlation_method=SPEARMAN, factors=None, families=None, title=None)

Cumulative exposure Information Coefficient (IC) over time.

Plots the cumulative sum of the single-period cross-sectional correlation
between factor exposures at $t$ and asset returns at $t + 1$.

- A monotonically rising curve indicates persistent predictive power
  (positive alpha signal).
- A flat curve means the factor carries no return-predictive information.
- A declining curve indicates a contrarian signal (negative alpha).

For IC decay analysis across different holding periods, use
[`exposure_ic_summary`](#skfolio.prior.FactorModel.exposure_ic_summary) with varying `horizon` values instead.

#### NOTE
The IC quantifies **return-predictive** power. In a **risk model**, factors
are designed to explain covariance structure, not to predict expected
returns. A factor can be an excellent risk factor even when
$\mathbb{E}[\text{IC}] \approx 0$.

* **Parameters:**
  **correlation_method** *CorrelationMethod, default=CorrelationMethod.SPEARMAN*
  : Correlation method used for the exposure IC. `SPEARMAN` computes
    Spearman rank IC. `PEARSON` computes Pearson IC, weighted by
    `regression_weights` when available.

  **factors** *list of str, optional*
  : Explicit subset of factor names. Takes precedence over `families` when
    specified.

  **families** *str, list of str, optional*
  : Factor families to include. `None` includes all factors.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_exposure_condition_number"></a>

#### plot_exposure_condition_number(window=30, title=None)

Plot the exposure Gram-matrix condition number over time.

Draws the per-observation condition number as a faded line and overlays its
rolling mean over `window` observations. Large values indicate near-collinear
exposures and less stable coefficient estimates.

* **Parameters:**
  **window** *int, default=30*
  : Number of observations required for the rolling mean.

  **title** *str, optional*
  : Custom title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_exposure_correlation"></a>

#### plot_exposure_correlation(factors=None, families=None, cs_weighting=BENCHMARK, title=None)

Time-average pairwise correlation heatmap of factor exposures.

Highly correlated exposures indicate redundant factors and may
inflate VIF.

* **Parameters:**
  **factors** *list of str, optional*
  : Explicit subset of factor names. Takes precedence over `families` when
    specified.

  **families** *str, list of str, or None, default=”style”*
  : Factor families to include. `None` includes all factors. Ignored when
    `factors` is given or when `factor_families` is `None`.

  **cs_weighting** *CSWeighting, default=CSWeighting.BENCHMARK*
  : Cross-sectional weights for the correlation computation. Falls back
    to `CSWeighting.IDENTITY` with a warning when unavailable.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_exposure_dispersion"></a>

#### plot_exposure_dispersion(factors=None, families='style', cs_weighting=BENCHMARK, title=None)

Cross-sectional standard deviation of exposures over time.

The absolute level depends on how exposures were standardized upstream. When
the model uses weighted-mean centering or a different variance normalization,
the equal-weighted cross-sectional std computed here will not be 1.0. Focus on
temporal stability rather than the absolute level: a collapse may signal
data-feed issues and an explosion may indicate an outlier.

* **Parameters:**
  **factors** *list of str, optional*
  : Explicit subset of factor names. Takes precedence over `families` when
    specified.

  **families** *str, list of str, or None, default=”style”*
  : Factor families to include. `None` includes all factors. Ignored when
    `factors` is given or when `factor_families` is `None`.

  **cs_weighting** *CSWeighting, default=CSWeighting.BENCHMARK*
  : Cross-sectional weights for the std computation. Falls back to
    `CSWeighting.IDENTITY` with a warning when unavailable.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_exposure_distribution"></a>

#### plot_exposure_distribution(factor, observation_idx=None, n_bins=None, title=None)

Cross-sectional histogram of exposures for a single factor.

When `observation` is `None` (default), all observations are pooled into one
histogram showing the typical distribution. When an integer index is provided,
only the exposures at that observation are plotted.

* **Parameters:**
  **factor** *str*
  : Name of the factor to plot.

  **observation_idx** *int , optional*
  : Observation index. `None` pools all dates, `-1` selects the last
    observation, `0` the first, etc.

  **n_bins** *int , optional*
  : Number of histogram bins. `None` lets Plotly choose automatically.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_exposure_stability"></a>

#### plot_exposure_stability(factors=None, families='style', step=21, cs_weighting=BENCHMARK, title=None)

Weighted cross-sectional correlation of exposures between observation
$t$ and $t + \text{step}$ over time.

Measures whether the cross-sectional exposures are stable across the chosen
horizon.

The expected level depends on the factor’s investment horizon. Slow-moving
factors (e.g. value, size) should maintain high correlation at the default
monthly step and values consistently below 0.80 may indicate noisy or poorly
constructed exposures. Fast-turnover factors (e.g. reversal, short-term
momentum) are designed to reshuffle quickly and will naturally show low monthly
stability. For these factors, use a shorter `step` (e.g., 1-5 for daily data) to
assess stability at the relevant horizon.

* **Parameters:**
  **factors** *list of str, optional*
  : Explicit subset of factor names. Takes precedence over `families` when
    specified.

  **families** *str, list of str, or None, default=”style”*
  : Factor families to include. `None` includes all factors. Ignored when
    `factors` is given or when `factor_families` is `None`.

  **step** *int, default=21*
  : Number of observations between the two cross-sections being compared (e.g.,
    21 for approximately monthly stability with daily data).

  **cs_weighting** *CSWeighting, default=CSWeighting.BENCHMARK*
  : Cross-sectional weights for the correlation computation. Falls back
    to `CSWeighting.IDENTITY` with a warning when unavailable.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_exposure_vif"></a>

#### plot_exposure_vif(factors=None, families=None, window=None, title=None)

Plot exposure Variance Inflation Factors over time per factor.

When `window` is provided, plots the rolling mean over `window` observations
instead of raw per-observation values. A horizontal reference line at VIF = 5
marks the conventional collinearity threshold.

* **Parameters:**
  **factors** *list of str, optional*
  : Subset of factor names to include.

  **families** *str, list of str, optional*
  : Factor families to include. Ignored when `factors` is given.

  **window** *int, optional*
  : If provided, plot the rolling mean.

  **title** *str, optional*
  : Custom title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_factor_cumulative_returns"></a>

#### plot_factor_cumulative_returns(factors=None, families=None, title=None)

Cumulative (non-compounded) factor returns over time.

* **Parameters:**
  **factors** *list of str, optional*
  : Explicit subset of factor names. Takes precedence over `families` when
    specified.

  **families** *str, list of str, or None, default=”style”*
  : Factor families to include. `None` includes all factors. Ignored when
    `factors` is given or when `factor_families` is `None`.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_factor_forecast_correlation"></a>

#### plot_factor_forecast_correlation(factors=None, families=None, title=None)

Factor return correlation forecast heatmap from `factor_covariance`.

* **Parameters:**
  **factors** *list of str, optional*
  : Explicit subset of factor names. Takes precedence over `families` when
    specified.

  **families** *str, list of str, or None, default=”style”*
  : Factor families to include. `None` includes all factors. Ignored when
    `factors` is given or when `factor_families` is `None`.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_factor_forecast_volatilities"></a>

#### plot_factor_forecast_volatilities(factors=None, families=None, annualization_factor=252.0, title=None)

Bar chart of annualized factor volatility forecasts.

Computes annualized volatility as
$\sqrt{\mathrm{diag}(\Sigma_F) \cdot \text{annualization\_factor}}$
from `factor_covariance`. Distinct from realized historical volatility
in [`summary`](#skfolio.prior.FactorModel.summary).

* **Parameters:**
  **factors** *list of str, optional*
  : Explicit subset of factor names. Takes precedence over `families` when
    specified.

  **families** *str, list of str, or None, default=”style”*
  : Factor families to include. `None` includes all factors. Ignored when
    `factors` is given or when `factor_families` is `None`.

  **annualization_factor** *float, default=252.0*
  : Number of observations per year.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_idio_calibration"></a>

#### plot_idio_calibration(window=None, title=None)

Cross-sectional std of standardized idiosyncratic returns over time.

Under correct calibration, $\text{std}(z_t) \approx 1$. Persistent
deviations indicate mis-specified specific risk.

* **Parameters:**
  **window** *int, optional*
  : Rolling-mean smoothing window.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_idio_kurtosis"></a>

#### plot_idio_kurtosis(window=None, title=None)

Cross-sectional excess kurtosis of standardised idiosyncratic returns over
time.

Each point is the excess kurtosis of $z_{it}$ computed across assets at a
single observation. The Gaussian reference is zero, but positive values are
expected because standardised idiosyncratic returns typically have fat tails.

* **Parameters:**
  **window** *int, optional*
  : Rolling-mean smoothing window.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_idio_skewness"></a>

#### plot_idio_skewness(window=None, title=None)

Cross-sectional skewness of standardised idiosyncratic returns over time.

Each point is the skewness of $z_{it}$ computed across assets at a single
observation. The Gaussian reference is zero. Mild negative skewness is common
for equity factor models.

* **Parameters:**
  **window** *int, optional*
  : Rolling-mean smoothing window.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_idio_tail_rate"></a>

#### plot_idio_tail_rate(threshold=3.0, window=None, title=None)

Plot the idiosyncratic tail exceedance rate over time.

For each observation, the plotted value is the fraction of assets whose
finite standardized idiosyncratic return satisfies
$|z_{i,t}| > \text{threshold}$. When `window` is provided, the rolling
mean is plotted to smooth short-lived cross-sectional tail spikes.

A dashed reference line shows the Gaussian rate
$2\,\Phi(-\text{threshold})$, which is about 0.27% when `threshold = 3`.
Persistent values above this reference indicate heavier idiosyncratic residual
tails than implied by the volatility estimates. In equity factor models,
standardized idiosyncratic returns are often fat-tailed, so observed rates above
the Gaussian reference are common.

* **Parameters:**
  **threshold** *float, default=3.0*
  : Absolute standardized-return threshold.

  **window** *int, optional*
  : Rolling-mean smoothing window.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_idio_vol_ic"></a>

#### plot_idio_vol_ic(window=60, title=None)

Information Coefficient (IC) of idiosyncratic volatility estimates.

Plots the cross-sectional rank correlation (Spearman) between the predicted
specific volatility $\hat\sigma_{i,t}$ and the next-period absolute
idiosyncratic return $|\epsilon_{i,t+1}|$.

This is a ranking diagnostic: do names predicted to have larger
$\hat\sigma_{i,t}$ tend to realize larger raw absolute moves.

- High positive values indicate that the model ranks cross-sectional differences
  in idiosyncratic volatility well.
- This diagnostic can also pick up broad cross-sectional scale effects such as
  size or liquidity.

This is a ranking diagnostic, not a calibration diagnostic. For the
post-standardization check, see [`plot_idio_vol_residual_dependence`](#skfolio.prior.FactorModel.plot_idio_vol_residual_dependence).

* **Parameters:**
  **window** *int, default=60*
  : Rolling window for the smoothed mean.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.plot_idio_vol_residual_dependence"></a>

#### plot_idio_vol_residual_dependence(window=60, title=None)

Residual dependence of standardized idiosyncratic returns on predicted
idiosyncratic volatility.

Plots the cross-sectional rank correlation (Spearman) between the predicted
specific volatility $\hat\sigma_{i,t}$ and the next-period standardized
absolute idiosyncratic return
$|\epsilon_{i,t+1}| / \hat\sigma_{i,t} = |z_{i,t+1}|$.
If the volatility forecast is well calibrated, this standardized magnitude
should be roughly independent of $\hat\sigma_{i,t}$, so the correlation
should be close to 0.

Read together with [`plot_idio_vol_ic`](#skfolio.prior.FactorModel.plot_idio_vol_ic), this helps distinguish ranking
power from calibration. A desirable pattern is high [`plot_idio_vol_ic`](#skfolio.prior.FactorModel.plot_idio_vol_ic)
together with residual dependence near 0.

* **Parameters:**
  **window** *int, default=60*
  : Rolling window for the smoothed mean.

  **title** *str, optional*
  : Custom figure title.
* **Returns:**
  **fig** *go.Figure*

<a id="skfolio.prior.FactorModel.predicted_attribution"></a>

#### predicted_attribution(weights, annualization_factor=252.0, compute_asset_breakdowns=True)

Compute ex-ante (predicted) factor volatility and return attribution.

Decomposes portfolio volatility using the exposure-volatility-correlation
framework ($x$-$\sigma$-$\rho$) and, when
`factor_mu` is available, decomposes expected return into factor-spanned
and factor-orthogonal components.

See [`predicted_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.predicted_factor_attribution.html.md#skfolio.attribution.predicted_factor_attribution)
for the full mathematical description.

* **Parameters:**
  **weights** *array-like of shape (n_assets,)*
  : Portfolio weights vector.

  **annualization_factor** *float, default=252.0*
  : Annualization factor applied to variances and expected returns
    (volatilities are scaled by $\sqrt{\text{annualization\_factor}}$).
    Use 1.0 to disable annualization.

  **compute_asset_breakdowns** *bool, default=True*
  : If `True`, compute per-asset systematic/idiosyncratic
    decomposition. Set to `False` for faster computation when
    only portfolio-level results are needed.
* **Returns:**
  **attribution** *Attribution*
  : Component-level, factor-level, and optionally asset-level
    attribution results.

<a id="skfolio.prior.FactorModel.realized_attribution"></a>

#### realized_attribution(weights, portfolio_returns, annualization_factor=252.0, compute_asset_breakdowns=True, compute_uncertainty=True)

Compute realized (ex-post) factor volatility and return attribution.

Decomposes realized portfolio risk and return into contributions
from individual factors and idiosyncratic sources using actual
historical data rather than model-predicted covariances.

See [`realized_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.realized_factor_attribution.html.md#skfolio.attribution.realized_factor_attribution)
for the full mathematical description.

* **Parameters:**
  **weights** *array-like of shape (n_assets,) or (n_observations, n_assets)*
  : Portfolio weights. If 1D, the same weights are used for all
    observations. If 2D, time-varying weights are used.

  **portfolio_returns** *array-like of shape (n_observations,)*
  : Portfolio return time series.

  **annualization_factor** *float, default=252.0*
  : Annualization factor applied to variances and mean returns
    (volatilities are scaled by $\sqrt{\text{annualization\_factor}}$).
    Use 1.0 to disable annualization.

  **compute_asset_breakdowns** *bool, default=True*
  : If `True`, compute per-asset attribution breakdowns. Set to `False`
    for faster computation when only portfolio-level results are
    needed.

  **compute_uncertainty** *bool, default=True*
  : If `True`, compute attribution uncertainty (standard errors on
    the factor/idiosyncratic PnL split). Requires both
    `regression_weights` and `idio_variances` to be available
    in this factor model; raises `ValueError` otherwise.
* **Returns:**
  **attribution** *Attribution*
  : Component-level, factor-level, and optionally asset-level
    attribution results.
* **Raises:**
  ValueError
  : If `factor_returns`, `exposures`, or `idio_returns` is
    not available, or if `compute_uncertainty=True` but
    `regression_weights` or `idio_variances` is missing.

<a id="skfolio.prior.FactorModel.rolling_realized_attribution"></a>

#### rolling_realized_attribution(weights, portfolio_returns, annualization_factor=252.0, window_size=60, step=21, compute_asset_breakdowns=True, compute_asset_factor_contribs=False, compute_uncertainty=True)

Compute rolling realized (ex-post) factor attribution.

Runs [`rolling_realized_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.rolling_realized_factor_attribution.html.md#skfolio.attribution.rolling_realized_factor_attribution)
over rolling windows of the factor model’s time-varying data.

See [`rolling_realized_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.rolling_realized_factor_attribution.html.md#skfolio.attribution.rolling_realized_factor_attribution)
for the full mathematical description.

* **Parameters:**
  **weights** *array-like of shape (n_assets,) or (n_observations, n_assets)*
  : Portfolio weights. If 1D, the same weights are used for all
    observations. If 2D, time-varying weights are used.

  **portfolio_returns** *array-like of shape (n_observations,)*
  : Portfolio return time series.

  **annualization_factor** *float, default=252.0*
  : Annualization factor applied to variances and mean returns
    (volatilities are scaled by $\sqrt{\text{annualization\_factor}}$).
    Use 1.0 to disable annualization.

  **window_size** *int, default=60*
  : Number of effective return periods in each rolling window.

  **step** *int, default=21*
  : Number of observations to advance between consecutive windows.
    The default of 21 produces approximately monthly output for
    daily data.

  **compute_asset_breakdowns** *bool, default=True*
  : If `True`, compute per-asset attribution breakdowns for each window.

  **compute_asset_factor_contribs** *bool, default=False*
  : If `True`, compute asset-by-factor contributions for each window.

  **compute_uncertainty** *bool, default=True*
  : If `True`, compute per-window attribution uncertainty
    (standard errors on the factor/idiosyncratic PnL split).
    Requires both `regression_weights` and `idio_variances`
    to be available in this factor model; raises `ValueError`
    otherwise.
* **Returns:**
  **attribution** *Attribution*
  : Rolling attribution results with an additional leading dimension
    for the number of windows.
* **Raises:**
  ValueError
  : If `factor_returns`, `exposures`, or `idio_returns` are
    not available, or if `window_size` exceeds `n_observations`.

<a id="skfolio.prior.FactorModel.select_assets"></a>

#### select_assets(assets=None, slim=False)

Return a new `FactorModel` restricted to selected assets.

Per-asset fields (`asset_names`, `loading_matrix`, `exposures`,
`idio_covariance`, `idio_mu`, `idio_returns`, `idio_variances`,
`regression_weights`, `benchmark_weights`) are subsetted along the asset axis.
Per-factor and time-only fields (`factor_names`, `factor_families`,
`factor_covariance`, `factor_mu`, `factor_returns`, `observations`) and
`family_constraint_basis` are passed through by reference. When `assets` keeps
every asset in order and `slim` is `False`, `self` is returned directly.

* **Parameters:**
  **assets** *array-like, slice , optional*
  : Assets to keep. Boolean arrays are treated as masks, integer arrays and
    slices are positional selectors and other arrays are matched against
    `asset_names`. The selection must be duplicate-free. If `None`, keep all
    assets.

  **slim** *bool, default=False*
  : When `True`, heavy time-series fields not used by downstream portfolio
    optimization (`exposures`, `idio_returns`, `idio_variances`,
    `benchmark_weights`) are set to `None` to save memory.
* **Returns:**
  **subset** *FactorModel*

<a id="skfolio.prior.FactorModel.select_observations"></a>

#### select_observations(observations)

Return a new `FactorModel` restricted to selected observations.

Slices all time-varying fields (`factor_returns`, `exposures`, `idio_returns`,
`idio_variances`, `regression_weights`, `benchmark_weights`) to match
`observations` while passing through all static fields (`loading_matrix`,
`factor_covariance`, `idio_covariance`, `factor_mu`, `idio_mu`) unchanged.

When the target observations map to a contiguous range inside the model’s
observation axis, numpy views are used to avoid copies.

#### NOTE
Static fields are shared by reference.  In particular, `loading_matrix`
is **not** updated to `exposures[-1]` of the sliced model. It retains the
value set by the estimator that produced this `FactorModel`.

* **Parameters:**
  **observations** *array-like or slice*
  : Observations to keep. Boolean arrays are treated as masks, integer arrays
    and slices are positional selectors, and other arrays are matched against
    `self.observations`. The selection must be duplicate-free and preserve the
    original observation order.
* **Returns:**
  **subset** *FactorModel*
  : A `FactorModel` whose time-varying arrays cover only the requested
    observations. If `observations` already matches `self.observations`, `self`
    is returned directly (zero-cost no-op).
* **Raises:**
  ValueError
  : If any element of `observations` is not found in `self.observations`, or if
    the requested labels are repeated or not in increasing order relative to
    `self.observations`.

<a id="skfolio.prior.FactorModel.summary"></a>

#### summary(factors=None, families=None, annualization_factor=252.0, stability_step=21, stability_cs_weighting=BENCHMARK, t_stat_threshold=2.0)

Summary statistics for the factor model.

Combines factor-return statistics, Gram-matrix diagnostics, and exposure-quality
metrics:

> * `annualized_mean`: factor annualized mean return.
> * `annualized_vol`: factor annualized volatility.
> * `annualized_sharpe`: factor annualized Sharpe ratio.
> * `autocorrelation`: factor return lag-1 autocorrelation.
> * `mean_abs_t_stat`: factor mean absolute cross-sectional t-statistic.
> * `t_stat_exceedance_rate`: fraction of observations where $|t| > \text{threshold}$.
> * `mean_vif`: factor mean Variance Inflation Factor.
> * `stability`: factor median exposure stability coefficient over the chosen step.
> * `coverage`: average fraction of estimation-universe assets (positive
>   regression weight) with non-missing factor exposure.

For characteristics-based models, `annualized_mean` and `annualized_vol` are
computed from model-native factor returns: the cross-sectional regression
coefficients per one unit of exposure. Equivalently, each factor return is the
WLS factor-mimicking portfolio return with unit exposure to that factor and zero
exposure to the other regression factors, without additional rescaling to fixed
gross exposure or volatility. The sign follows the exposure convention; for
example, a size factor built from log market capitalization is large-minus-small,
the opposite sign of the Fama-French SMB convention.

* **Parameters:**
  **factors** *list of str, optional*
  : Explicit subset of factor names. Takes precedence over `families` when
    specified.

  **families** *str, list of str, optional*
  : Factor families to include. `None` includes all factors. Ignored when
    `factors` is given or when `factor_families` is `None`.

  **annualization_factor** *float, default=252.0*
  : Number of observations per year (e.g., 252 for daily data) to annualize
    mean, volatility and sharpe ratio.

  **stability_step** *int, default=21*
  : Number of observations between the two cross-sections used for the exposure
    stability coefficient (e.g. 21 for approximately monthly stability with
    daily data).

  **stability_cs_weighting** *CSWeighting, default=CSWeighting.BENCHMARK*
  : Cross-sectional weights for the stability computation. Falls back
    to `CSWeighting.IDENTITY` with a warning when unavailable.

  **t_stat_threshold** *float, default=2.0*
  : Absolute t-statistic threshold for the exceedance rate.

