Leakage-safe nested-CV feature selection for small tabular classification, regression, and survival analysis.
Project description
ranking-feature-selector
ranking-feature-selector is a leakage-safe, nested-CV feature selection package for small tabular data. It supports binary classification, single-output regression, and right-censored survival analysis.
It is designed for research workflows where feature ranking, feature-count selection, preprocessing, and performance estimation should be performed inside cross-validation folds to reduce data leakage.
Installation
pip install ranking-feature-selector
For survival analysis / Random Survival Forests:
pip install "ranking-feature-selector[survival]"
For SHAP-based ranking backends:
pip install "ranking-feature-selector[shap]"
For imbalanced-learn samplers in binary classification:
pip install "ranking-feature-selector[imbalance]"
For all optional backends:
pip install "ranking-feature-selector[all]"
Quick start
from ranking_feature_selector import RobustSurvivalFeatureSelectorCV
selector = RobustSurvivalFeatureSelectorCV(
model=rsf,
max_features=20,
preset="safe",
preprocessor="standardize",
random_state=42,
)
selector.fit(X, y, groups=center_id)
print(selector.selected_features_)
print(selector.summary())
For most use cases, start with a task-specific class, model, max_features, preset, preprocessor, and random_state. Advanced controls are grouped under cv_config, selection_config, and importance_config.
Main classes
from ranking_feature_selector import (
RobustClassificationFeatureSelectorCV,
RobustRegressionFeatureSelectorCV,
RobustSurvivalFeatureSelectorCV,
)
| Class | Task | Required model API |
|---|---|---|
RobustClassificationFeatureSelectorCV |
Binary classification | fit(X, y) and predict_proba(X) |
RobustRegressionFeatureSelectorCV |
Regression | fit(X, y) and predict(X) |
RobustSurvivalFeatureSelectorCV |
Right-censored survival analysis | fit(X, y) and a risk-score interface, usually predict(X) |
RobustFeatureSelectorCV(task=...) is also available as a generic interface. RobustShapFeatureSelectorCV is kept as a backward-compatible class alias.
Backward-compatible import aliases are also provided:
from robust_feature_selector import RobustSurvivalFeatureSelectorCV
from robust_shap_selector import RobustSurvivalFeatureSelectorCV
New code should prefer:
from ranking_feature_selector import RobustSurvivalFeatureSelectorCV
What the package does
For each outer CV fold, the selector performs feature ranking and feature-count selection using only the training portion of that fold:
- Fit preprocessing on the training fold only.
- Rank features inside inner-CV training folds.
- Select the number of features using inner-CV performance.
- Refit on the outer-training fold using the selected features.
- Evaluate on the untouched outer-test fold.
- Aggregate fold-wise selections into
selected_features_using selection frequency.
This means that the reported outer-CV performance reflects fold-specific selected feature sets. The final selected_features_ list is a stability-based summary across outer folds.
Presets
| Preset | Intended use | Behavior |
|---|---|---|
"fast" |
Initial checks | Fewer repeats and smaller CV |
"safe" |
Default research use | Nested CV, one-standard-error rule, shadow features enabled |
"publication" |
More conservative analysis | More repeats and stricter stability threshold |
"custom" |
Full control | Override settings via config dictionaries |
Preprocessing and standardization
preprocessor must preserve the same number and order of columns. One-hot encoding, target encoding, PCA, or other feature-expanding transformations should be performed before calling the selector.
| Setting | Behavior |
|---|---|
preprocessor="auto" |
Median imputation |
preprocessor="median_impute" |
Median imputation |
preprocessor="standardize" |
Median imputation + StandardScaler |
preprocessor="none" |
No preprocessing |
standardize=True |
Adds StandardScaler after median imputation when using "auto" |
| custom transformer | Any same-column sklearn-compatible transformer |
Example:
selector = RobustRegressionFeatureSelectorCV(
model=model,
max_features=15,
preprocessor="standardize",
)
Custom preprocessing:
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import RobustScaler
preprocessor = Pipeline([
("imputer", SimpleImputer(strategy="median")),
("scaler", RobustScaler()),
])
selector = RobustRegressionFeatureSelectorCV(
model=model,
max_features=15,
preprocessor=preprocessor,
)
Supported models
model should be a scikit-learn compatible estimator that can be cloned with sklearn.base.clone().
Binary classification
Required API:
model.fit(X_train, y_train)
model.predict_proba(X_valid)
Recommended models include:
sklearn.ensemble.RandomForestClassifiersklearn.ensemble.ExtraTreesClassifiersklearn.linear_model.LogisticRegressionlightgbm.LGBMClassifierxgboost.XGBClassifiercatboost.CatBoostClassifiersklearn.svm.SVC(probability=True)
Classification samplers such as SMOTE can be passed only to RobustClassificationFeatureSelectorCV:
from imblearn.over_sampling import SMOTE
from ranking_feature_selector import RobustClassificationFeatureSelectorCV
selector = RobustClassificationFeatureSelectorCV(
model=model,
max_features=20,
sampler=SMOTE(random_state=42),
preset="safe",
)
Regression
Required API:
model.fit(X_train, y_train)
model.predict(X_valid)
Recommended models include:
sklearn.ensemble.RandomForestRegressorsklearn.ensemble.ExtraTreesRegressorsklearn.linear_model.ElasticNet,Ridge,Lassolightgbm.LGBMRegressorxgboost.XGBRegressorcatboost.CatBoostRegressorSVRorKNeighborsRegressorwithimportance_config={"method": "permutation"}
Survival analysis
Required API:
model.fit(X_train, y_train)
risk_score = model.predict(X_valid)
Recommended models include:
sksurv.ensemble.RandomSurvivalForestsksurv.linear_model.CoxPHSurvivalAnalysissksurv.ensemble.GradientBoostingSurvivalAnalysissksurv.ensemble.ComponentwiseGradientBoostingSurvivalAnalysis
y can be a sksurv.util.Surv.from_arrays(event, time) structured array, an (event, time) tuple, a two-column array, or a DataFrame with event/time columns.
from sksurv.util import Surv
y = Surv.from_arrays(event=event, time=time)
Survival risk-score configuration
By default, RobustSurvivalFeatureSelectorCV uses model.predict(X) as the risk score for C-index and permutation importance. Larger values are assumed to mean higher event risk.
| Setting | Meaning | Required model API |
|---|---|---|
risk_score="predict" |
Uses model.predict(X) |
predict(X) |
risk_score="event_probability" |
Uses `1 - S(t | X)atprediction_time` |
risk_score="cumulative_hazard" |
Uses `H(t | X)atprediction_time` |
| callable | Uses callable(model, X) |
User-defined |
Example using fixed-time event probability:
selector = RobustSurvivalFeatureSelectorCV(
model=rsf,
max_features=20,
risk_score="event_probability",
prediction_time=365,
preset="safe",
)
Raw RSF risk scores may have different scales across CV folds. This package does not assume that raw survival risk scores are calibrated or directly comparable across folds. They are used for within-fold rank-based evaluation such as C-index.
If your risk-score function returns lower values for higher risk, use:
selector = RobustSurvivalFeatureSelectorCV(
model=model,
max_features=20,
risk_score_direction="lower",
)
Advanced usage
Advanced settings are grouped into dictionaries.
selector = RobustSurvivalFeatureSelectorCV(
model=rsf,
max_features=20,
preset="custom",
cv_config={
"outer_splits": 5,
"inner_splits": 4,
"survival_stratify": "event",
},
selection_config={
"selection_rule": "one_se",
"min_selection_rate": 0.5,
"use_shadow": True,
"k_grid": [5, 10, 15, 20],
},
importance_config={
"method": "permutation",
"scoring": "auto",
"n_repeats": 10,
"n_jobs": -1,
},
)
Importance backends
| Method | Classification | Regression | Survival |
|---|---|---|---|
"auto" |
SHAP when available, fallback otherwise | SHAP when available, fallback otherwise | permutation C-index |
"shap" |
SHAP-based ranking | SHAP-based ranking | not the default |
"permutation" |
metric-aligned permutation | metric-aligned permutation | metric-aligned permutation |
When importance_config={"method": "permutation", "scoring": "auto"}, permutation importance is aligned with the optimization metric: log loss for classification, RMSE for regression, and C-index for survival.
Results
After fitting:
selector.selected_features_
selector.result_.outer_results
selector.result_.inner_results
selector.result_.selection_frequency
selector.summary()
Save all result tables and metadata:
selector.result_.save("fs_results")
This writes:
outer_results.csv
inner_results.csv
inner_details.csv
selection_frequency.csv
final_features.csv
ranking_outer_*.csv
config.json
metadata.json
Requirements files
The requirements/ directory provides install shortcuts. The authoritative dependency definitions remain in pyproject.toml.
pip install -r requirements/base.txt
pip install -r requirements/survival.txt
pip install -r requirements/shap.txt
pip install -r requirements/imbalance.txt
pip install -r requirements/all.txt
Development
git clone https://github.com/rik-yosh/ranking-feature-selector.git
cd ranking-feature-selector
pip install -e ".[dev]"
pytest -q
python -m build
python -m twine check dist/*
GitHub Actions publishing
This repository includes GitHub Actions workflows for tests and PyPI publishing.
.github/workflows/test.ymlruns tests and package checks on pushes and pull requests..github/workflows/publish.ymlbuilds and publishes on tags matchingv*.
For PyPI Trusted Publishing, configure the PyPI project with your GitHub owner, repository, workflow filename, and environment before pushing the release tag.
Important limitations
- The package targets research workflows and should not be used as the sole basis for clinical decision-making.
- Outer-CV performance reflects fold-specific selected feature sets.
selected_features_is a stability-based aggregate across outer folds.- Column-expanding preprocessing should be performed before using the selector.
- Survival raw risk scores are not assumed to be comparable across CV folds.
License
MIT License. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ranking_feature_selector-0.4.3.tar.gz.
File metadata
- Download URL: ranking_feature_selector-0.4.3.tar.gz
- Upload date:
- Size: 40.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ed56d2763bfbfb1d5937bf90a23ac5423bbd8cf0bab040c7857043c0cee9cdc
|
|
| MD5 |
6e393bfae4f4eb0b520e37ec76b08507
|
|
| BLAKE2b-256 |
9f8d5c1d47ca4d668ab914997bef68ec1ea6cb6cd31158ac87829734d241045e
|
Provenance
The following attestation bundles were made for ranking_feature_selector-0.4.3.tar.gz:
Publisher:
publish.yml on rik-yosh/ranking-feature-selector
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ranking_feature_selector-0.4.3.tar.gz -
Subject digest:
1ed56d2763bfbfb1d5937bf90a23ac5423bbd8cf0bab040c7857043c0cee9cdc - Sigstore transparency entry: 2116729771
- Sigstore integration time:
-
Permalink:
rik-yosh/ranking-feature-selector@6b5987116fe5b2a662a8cbb9a3ca2a00a4de1d72 -
Branch / Tag:
refs/tags/v0.4.3 - Owner: https://github.com/rik-yosh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6b5987116fe5b2a662a8cbb9a3ca2a00a4de1d72 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ranking_feature_selector-0.4.3-py3-none-any.whl.
File metadata
- Download URL: ranking_feature_selector-0.4.3-py3-none-any.whl
- Upload date:
- Size: 36.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea09cd28e1073ce65dd77a0d1111fd78a88d003ce8a6dd145fb7d2b17fe91307
|
|
| MD5 |
64a865e931e770904b8c519dc7414201
|
|
| BLAKE2b-256 |
efe430dbc5e523c0866d6e2a2a68357428c3dfe69a0242b38c350eb3e66eb26c
|
Provenance
The following attestation bundles were made for ranking_feature_selector-0.4.3-py3-none-any.whl:
Publisher:
publish.yml on rik-yosh/ranking-feature-selector
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ranking_feature_selector-0.4.3-py3-none-any.whl -
Subject digest:
ea09cd28e1073ce65dd77a0d1111fd78a88d003ce8a6dd145fb7d2b17fe91307 - Sigstore transparency entry: 2116729830
- Sigstore integration time:
-
Permalink:
rik-yosh/ranking-feature-selector@6b5987116fe5b2a662a8cbb9a3ca2a00a4de1d72 -
Branch / Tag:
refs/tags/v0.4.3 - Owner: https://github.com/rik-yosh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6b5987116fe5b2a662a8cbb9a3ca2a00a4de1d72 -
Trigger Event:
push
-
Statement type: