CASPER-t: a reliability-weighted topological feature selector (scikit-learn compatible)
Project description
CASPER-t
Covering Approximation Space Permutation Elimination Rule (t-statistic form) — a reliability-weighted topological feature selector, packaged as a drop-in scikit-learn transformer.
Keep a small, confident subset of features instead of all of them — without paying for it in accuracy. On 9 benchmark datasets CASPER-t retains a median 60 % of features while tracking full-feature accuracy to within ~1–2 points.
pip install casper-fs
How it works
CASPER-t treats each feature's usefulness as a measured quantity with an error bar, and keeps a feature only when its measured contribution clears a reliability margin — not merely when it looks large once.
flowchart LR
A["X, y"] --> B["Jenks<br/>discretisation"]
B --> C["L₁ tolerance<br/>relation"]
C --> D["select ε*<br/>(covering radius)"]
D --> E["γ-PFI<br/>N permutations"]
E --> F["tᶠ = (Δγ − Q1) / SEM > κ"]
F --> G["selected<br/>subset"]
-
Discretise each feature by unsupervised Jenks natural breaks.
-
Build an L₁ tolerance relation and pick the covering radius ε* that maximises the γ dependency degree (just below saturation).
-
Score every feature by the drop in γ under N permutations (γ-PFI) — a permutation-importance signal native to the covering approximation space.
-
Retain a feature only when that drop clears the first quartile of the feature-wise distribution by a reliable margin:
tᶠ = (mean(Δγ_f) − Q1) / SEM_f > κ (default κ = 1.5)
Everything is refit on the training split it is given, so it is leakage-free
inside a scikit-learn Pipeline / cross-validation loop.
Benchmark
Protocol. Nested cross-validation on 9 datasets, evaluated across 8 classifiers, against 13 feature-selection baselines (filter, wrapper, embedded, and rough-set families). Baselines are compared at matched cardinality — each is truncated to CASPER-t's own per-fold feature count — so every method is judged on the same feature budget.
The headline is parsimony: CASPER-t discards 25–51 % of the features yet stays within a point or two of using everything — and matches or beats the full set on 4 of 9 datasets (banknote, diabet, htru2, sonar).
| Dataset | Features kept (K / p) | CASPER-t acc. | All-features acc. | Δ |
|---|---|---|---|---|
| banknote | 3.0 / 4 | 96.8 | 97.1 | −0.2 |
| htru2 | 5.7 / 8 | 97.1 | 97.0 | +0.1 |
| magic | 7.0 / 10 | 81.2 | 82.5 | −1.3 |
| diabet | 6.7 / 10 | 77.6 | 76.5 | +1.1 |
| phoneme | 3.0 / 5 | 77.7 | 81.9 | −4.2 |
| cyron | 3.6 / 6 | 84.9 | 87.7 | −2.9 |
| sonar | 34.0 / 60 | 80.3 | 80.2 | +0.2 |
| parkinson | 8.4 / 17 | 86.2 | 86.4 | −0.3 |
| kanser | 12.7 / 26 | 94.2 | 96.0 | −1.8 |
Accuracy is the mean over 8 classifiers × outer folds. K is the mean per-fold subset size; p is the number of candidate features.
On honest terms. At a matched feature budget no single selector dominates the
field — CASPER-t's mean Accuracy rank is mid-pack (≈ 7.7 of 14 methods), and
its value is the combination of a principled topological criterion with a
reliability gate that yields compact subsets. Every rank, dispersion (fold std and
across-classifier std), and per-fold number behind these figures is shipped in
detailed_tables/ — nothing is averaged away.
Quickstart
from casper import CasperT
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_breast_cancer
X, y = load_breast_cancer(return_X_y=True)
# standalone
sel = CasperT(kappa=1.5, n_permutations=30, random_state=42).fit(X, y)
print(sel.get_support().sum(), "features selected") # -> 13 of 30
print(sel.eps_star_, sel.t_stats_) # diagnostics
# leakage-free inside a Pipeline (refits per fold)
pipe = Pipeline([("casper", CasperT()), ("clf", SVC())])
cross_val_score(pipe, X, y, cv=5)
Requires Python ≥ 3.9, numpy, scipy, scikit-learn. Install from a clone with
pip install ..
API
CasperT(kappa=1.5, n_permutations=30, max_bins=7, target_gvf=0.80, max_topological=3000, random_state=42)
| Parameter | Meaning |
|---|---|
kappa |
reliability margin of the tᶠ rule; larger ⇒ fewer, more confident features |
n_permutations |
permutation replicates per feature in γ-PFI |
max_bins / target_gvf |
Jenks bin cap / goodness-of-variance-fit early-stop target |
max_topological |
subsample cap for the O(n²) topological stage (evaluation uses full data) |
Fitted attributes: support_, delta_gamma_, sem_, t_stats_, eps_star_,
gamma_base_, q1_. Standard SelectorMixin API: fit, transform,
get_support, get_feature_names_out.
Reproducing the article
pipeline/gamma_pfi_uhem.py is the full nested-CV pipeline used for the paper
(all baselines, statistics, and per-fold outputs); pipeline/make_tables.py
regenerates the LaTeX tables from those outputs.
Detailed results (detailed_tables/)
The article's tables report means only, for readability. These files hold the same numbers with their dispersion and at fold-level granularity:
| File | What it is |
|---|---|
summary_mean_std.csv |
one row per (dataset × method × metric): mean, fold std, across-classifier std, retained K, p, retained % |
fold_level_hybrid.csv |
every outer fold, HYBRID classifier only |
fold_level_raw.csv.gz |
every outer fold × 8 classifiers × every method |
Method ids: V1_tstat = CASPER-t; *_matchK = baselines truncated at CASPER-t's
per-fold cardinality; *_native = rough-set baselines at their own stopping point;
ALL = full feature set.
Citation
If you use CASPER-t, please cite the article:
@article{casper_t,
title = {A Topological Feature Selection Framework via Generalized Covering
Approximation Spaces with Permutation Importance},
author = {Boyabatli, K. and others},
year = {2026}
}
License
MIT — 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 casper_fs-0.1.0.tar.gz.
File metadata
- Download URL: casper_fs-0.1.0.tar.gz
- Upload date:
- Size: 331.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cfc781002bca40d35c579f4386f2ca9d8a264156aeba2b3263c7de4ca704f4cd
|
|
| MD5 |
2cc507c7fc36c963f96eee1343a962c3
|
|
| BLAKE2b-256 |
61626a4d085b8dfc81fda7ea6738c2838892c2a7c0520985853bb9315e79e952
|
File details
Details for the file casper_fs-0.1.0-py3-none-any.whl.
File metadata
- Download URL: casper_fs-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da674037431d684c58484185579d9a40238c5f3a95b3d2148d13af1370dc5bd6
|
|
| MD5 |
fb35d1a59da8419af515775177abd23c
|
|
| BLAKE2b-256 |
8e717adea5543b9baee3dc65be23a5b9e6797bdea99d1f4929e6060d3fe3c43f
|