<a id="pre-selection"></a>

<a id="pre-selection-transformers"></a>

# Pre-Selection Transformers

A [Pre-Selection transformer](https://skfolio.org/api.html.md#pre-selection-ref) performs a pre-selection on the
initial assets universe.

It follows the same API as scikit-learn’s `estimator`: the `fit_transform` method takes
`X` as the assets returns and returns a new `X` with only the pre-selected assets.

`X` can be any array-like structure (numpy array, pandas DataFrame, etc.)

Pre-selection is one way to handle missing returns before fitting estimators that
require finite inputs. See [Missing Data and Changing Universes](https://skfolio.org/user_guide/data_representation.html.md#missing-data)
for the trade-off between pre-selection, imputation and native NaN-aware estimators.

Available transformers are:
: * [`DropZeroVariance`](https://skfolio.org/generated/skfolio.pre_selection.DropZeroVariance.html.md#skfolio.pre_selection.DropZeroVariance)
  * [`DropCorrelated`](https://skfolio.org/generated/skfolio.pre_selection.DropCorrelated.html.md#skfolio.pre_selection.DropCorrelated)
  * [`SelectComplete`](https://skfolio.org/generated/skfolio.pre_selection.SelectComplete.html.md#skfolio.pre_selection.SelectComplete)
  * [`SelectKExtremes`](https://skfolio.org/generated/skfolio.pre_selection.SelectKExtremes.html.md#skfolio.pre_selection.SelectKExtremes)
  * [`SelectNonDominated`](https://skfolio.org/generated/skfolio.pre_selection.SelectNonDominated.html.md#skfolio.pre_selection.SelectNonDominated)
  * [`SelectNonExpiring`](https://skfolio.org/generated/skfolio.pre_selection.SelectNonExpiring.html.md#skfolio.pre_selection.SelectNonExpiring)

**Example:**

```python
from sklearn import set_config

from skfolio.datasets import load_sp500_dataset
from skfolio.pre_selection import DropCorrelated
from skfolio.preprocessing import prices_to_returns

set_config(transform_output="pandas")

prices = load_sp500_dataset()
X = prices_to_returns(prices)
print(X.shape)

model = DropCorrelated(threshold=0.5)
new_X = model.fit_transform(X)
print(new_X.shape)
```

Pre-Selection transformers are fully compatible with `sklearn.pipeline.Pipeline`:

**Example:**

```python
from sklearn import set_config
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline

from skfolio.datasets import load_sp500_dataset
from skfolio.optimization import MeanRisk
from skfolio.pre_selection import DropCorrelated
from skfolio.preprocessing import prices_to_returns

set_config(transform_output='pandas')

prices = load_sp500_dataset()
X = prices_to_returns(prices)
X_train, X_test = train_test_split(X, shuffle=False, test_size=0.3)

pipe = Pipeline([('pre_selection', DropCorrelated(threshold=0.9)),
                 ('mean_risk', MeanRisk())])
pipe.fit(X_train)

portfolio = pipe.predict(X_test)
print(portfolio.annualized_sharpe_ratio)
```
