Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Selects informative features for biomarker discovery using Boruta all-relevant selection, mRMR minimum redundancy, and LASSO regularization. Use when identifying biomarkers from high-dimensional omics data.
.claude/skills/bio-machine-learning-biomarker-discovery/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 18% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 33% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 9% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 74% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 58% | 0% |
<!--
#
#
-->
Identifies all features that are significantly better than random (shadow features).
pythonfrom boruta import BorutaPy from sklearn.ensemble import RandomForestClassifier import pandas as pd import numpy as np rf = RandomForestClassifier(n_estimators=100, n_jobs=-1, random_state=42) # max_iter=100: Typically sufficient; increase to 200 if many features remain tentative # perc=100: Use max of shadow features (default); lower for stricter selection boruta = BorutaPy(rf, n_estimators='auto', max_iter=100, random_state=42, verbose=0) boruta.fit(X.values, y) selected = X.columns[boruta.support_] tentative = X.columns[boruta.support_weak_] print(f'Selected: {len(selected)}, Tentative: {len(tentative)}') feature_ranks = pd.DataFrame({ 'feature': X.columns, 'rank': boruta.ranking_, 'selected': boruta.support_ }).sort_values('rank')
Selects features that are individually relevant but minimally redundant with each other.
pythonfrom mrmr import mrmr_classif # K: Number of features to select; start with 50-100 for omics selected_features = mrmr_classif(X=X, y=pd.Series(y), K=50) X_selected = X[selected_features]
L1 regularization drives irrelevant coefficients to zero.
pythonfrom sklearn.linear_model import LassoCV from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # cv=5: Standard for selection; eps and n_alphas control alpha grid lasso = LassoCV(cv=5, random_state=42) lasso.fit(X_scaled, y) selected_mask = lasso.coef_ != 0 selected = X.columns[selected_mask] print(f'LASSO selected {len(selected)} features at alpha={lasso.alpha_:.4f}') coefs = pd.Series(lasso.coef_, index=X.columns) nonzero = coefs[coefs != 0].sort_values(key=abs, ascending=False)
Reduce dimensionality before more expensive methods.
pythonfrom sklearn.feature_selection import SelectKBest, f_classif, mutual_info_classif # f_classif: Fast, assumes normality; good for log-counts # mutual_info_classif: Nonlinear relationships but slower # k=1000: Reasonable pre-filter; increase for larger omics datasets (>10k features) selector = SelectKBest(f_classif, k=1000) X_filtered = selector.fit_transform(X, y) selected_idx = selector.get_support(indices=True)
pythonfrom sklearn.pipeline import Pipeline from sklearn.ensemble import RandomForestClassifier # Pre-filter then Boruta for efficiency pipe = Pipeline([ ('prefilter', SelectKBest(f_classif, k=5000)), ('boruta', BorutaPy(RandomForestClassifier(n_jobs=-1), max_iter=100, random_state=42)) ]) # Note: BorutaPy doesn't follow sklearn API perfectly; manual fit may be needed
| Method | Strengths | Weaknesses | Use When | |--------|-----------|------------|----------| | Boruta | Finds all relevant features | Slow on large data | Want complete biomarker panel | | mRMR | Reduces redundancy | Fixed K | Want compact signature | | LASSO | Sparse, interpretable | Picks one of correlated | Want minimal predictive set | | Univariate | Fast | Ignores interactions | Pre-filtering |
pythonfrom sklearn.linear_model import LogisticRegression from sklearn.feature_selection import SelectFromModel import numpy as np n_bootstrap = 100 selection_counts = np.zeros(X.shape[1]) for i in range(n_bootstrap): idx = np.random.choice(len(X), size=len(X), replace=True) X_boot, y_boot = X.iloc[idx], y[idx] lasso = LogisticRegression(penalty='l1', solver='saga', C=0.1, max_iter=1000) lasso.fit(X_boot, y_boot) selection_counts += (lasso.coef_[0] != 0) # stability_threshold=0.6: Features selected in >60% of bootstrap samples stable_features = X.columns[selection_counts / n_bootstrap > 0.6]
<!-- AUTHOR_SIGNATURE: 9a7f3c2e-MD-BABU-MIA-2026-MSSM-SECURE -->
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 15,873 | 11,918 | -25% | 1 | 1 | 0% | 3,362 | 3,975 | +18% | 0 | 0 | — |
case-02 | pass→pass | 12,644 | 15,073 | +19% | 1 | 1 | 0% | 2,545 | 4,427 | +74% | 0 | 0 | — |
case-03 | pass→pass | 10,084 | 8,309 | -18% | 1 | 1 | 0% | 1,895 | 2,992 | +58% | 0 | 0 | — |
case-04 | pass→pass | 14,088 | 9,292 | -34% | 1 | 1 | 0% | 2,869 | 3,323 | +16% | 0 | 0 | — |
case-10 | fail→fail | 14,753 | 4,943 | -66% | 1 | 1 | 0% | 2,741 | 2,285 | -17% | 0 | 0 | — |
case-15 | pass→pass | 14,027 | 11,303 | -19% | 1 | 1 | 0% | 2,479 | 3,323 | +34% | 0 | 0 | — |
case-24 | pass→pass | 5,060 | 2,491 | -51% | 1 | 1 | 0% | 1,021 | 1,799 | +76% | 0 | 0 | — |
case-05 | pass→pass | 12,280 | 9,383 | -24% | 1 | 1 | 0% | 2,274 | 3,169 | +39% | 0 | 0 | — |
case-06 | pass→pass | 9,225 | 4,582 | -50% | 1 | 1 | 0% | 1,744 | 2,190 | +26% | 0 | 0 | — |
case-07 | pass→pass | 9,594 | 4,134 | -57% | 1 | 1 | 0% | 1,794 | 2,014 | +12% | 0 | 0 | — |
case-08 | pass→pass | 15,668 | 10,947 | -30% | 1 | 1 | 0% | 3,120 | 3,685 | +18% | 0 | 0 | — |
case-09 | fail→pass | 10,679 | 7,521 | -30% | 1 | 1 | 0% | 2,194 | 2,908 | +33% | 0 | 0 | — |
case-11 | pass→pass | 8,182 | 5,256 | -36% | 1 | 1 | 0% | 1,491 | 2,272 | +52% | 0 | 0 | — |
case-12 | fail→pass | 18,536 | 18,165 | -2% | 1 | 1 | 0% | 3,884 | 4,234 | +9% | 0 | 0 | — |
case-13 | pass→pass | 9,756 | 4,766 | -51% | 1 | 1 | 0% | 1,653 | 2,178 | +32% | 0 | 0 | — |
case-14 | pass→pass | 10,252 | 4,620 | -55% | 1 | 1 | 0% | 1,895 | 2,120 | +12% | 0 | 0 | — |
case-16 | pass→pass | 8,029 | 6,444 | -20% | 1 | 1 | 0% | 1,483 | 2,477 | +67% | 0 | 0 | — |
case-17 | pass→pass | 12,256 | 11,593 | -5% | 1 | 1 | 0% | 2,397 | 3,611 | +51% | 0 | 0 | — |
case-18 | pass→pass | 7,605 | 4,121 | -46% | 1 | 1 | 0% | 1,601 | 2,188 | +37% | 0 | 0 | — |
case-19 | pass→pass | 6,584 | 4,261 | -35% | 1 | 1 | 0% | 1,274 | 2,119 | +66% | 0 | 0 | — |
case-20 | fail→fail | 12,582 | 8,698 | -31% | 1 | 1 | 0% | 2,281 | 2,900 | +27% | 0 | 0 | — |
case-21 | pass→pass | 5,049 | 4,487 | -11% | 1 | 1 | 0% | 990 | 2,197 | +122% | 0 | 0 | — |
case-22 | pass→pass | 13,822 | 9,042 | -35% | 1 | 1 | 0% | 2,574 | 2,992 | +16% | 0 | 0 | — |
case-23 | pass→pass | 14,204 | 11,876 | -16% | 1 | 1 | 0% | 2,432 | 3,528 | +45% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted. The headline lift of +13 percentage points is the difference between those two pass rates over the 24 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/24/2026 | +32% |
Other measured skills in the registry, with their headline benchmark lift.