Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Analyzes time-to-event data using Kaplan-Meier curves, log-rank tests, and Cox proportional hazards regression with lifelines. Builds survival models from clinical and omics features. Use when predicting patient survival or modeling time-to-event outcomes.
.claude/skills/bio-machine-learning-survival-analysis/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | 110% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 5% | 0% |
| case-16 | ✓→✓ | = Same ✓ | -1% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 55% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 43% | 0% |
<!--
#
#
-->
pythonfrom lifelines import KaplanMeierFitter import matplotlib.pyplot as plt kmf = KaplanMeierFitter() # T: time to event or censoring # E: event indicator (1=event occurred, 0=censored) kmf.fit(T, event_observed=E) # Plot survival curve kmf.plot_survival_function() plt.xlabel('Time (months)') plt.ylabel('Survival probability') plt.savefig('km_curve.png', dpi=150)
pythonfrom lifelines import KaplanMeierFitter from lifelines.statistics import logrank_test import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(8, 6)) for group, color in zip(['high', 'low'], ['red', 'blue']): mask = df['risk_group'] == group kmf = KaplanMeierFitter() kmf.fit(df.loc[mask, 'time'], event_observed=df.loc[mask, 'event'], label=group) kmf.plot_survival_function(ax=ax, color=color) # Log-rank test high = df[df['risk_group'] == 'high'] low = df[df['risk_group'] == 'low'] results = logrank_test(high['time'], low['time'], event_observed_A=high['event'], event_observed_B=low['event']) print(f'Log-rank p-value: {results.p_value:.4e}') ax.set_xlabel('Time (months)') ax.set_ylabel('Survival probability') ax.set_title(f'Log-rank p = {results.p_value:.4e}') plt.savefig('km_comparison.png', dpi=150)
pythonfrom lifelines import CoxPHFitter # Prepare data: must have 'time' and 'event' columns # Include covariates as additional columns cph = CoxPHFitter() cph.fit(df, duration_col='time', event_col='event') # Summary with hazard ratios cph.print_summary() # Get hazard ratios as DataFrame hr = cph.summary[['exp(coef)', 'exp(coef) lower 95%', 'exp(coef) upper 95%', 'p']] print(hr) # Concordance index (c-index): 0.5=random, 1.0=perfect print(f'C-index: {cph.concordance_index_:.3f}')
pythonfrom lifelines import CoxPHFitter import pandas as pd # Combine clinical and omics features cox_df = pd.DataFrame({ 'time': meta['survival_months'], 'event': meta['vital_status'], 'age': meta['age'], 'stage': meta['stage_numeric'], 'GENE1': expr.loc['GENE1'], 'GENE2': expr.loc['GENE2'] }) cph = CoxPHFitter(penalizer=0.1) # L2 regularization for stability cph.fit(cox_df, duration_col='time', event_col='event') cph.print_summary()
python# Partial hazard (risk score) risk_scores = cph.predict_partial_hazard(cox_df) # Median risk split for KM plot df['risk_group'] = (risk_scores > risk_scores.median()).map({True: 'high', False: 'low'})
python# Test PH assumption cph.check_assumptions(df, p_value_threshold=0.05, show_plots=True)
python# Survival probability at specific times survival_probs = kmf.survival_function_at_times([12, 24, 60]) print(survival_probs) # Median survival print(f'Median survival: {kmf.median_survival_time_:.1f}')
pythonfrom lifelines import CoxPHFitter import pandas as pd # Univariate screening results = [] for gene in expr.index[:1000]: cox_df = pd.DataFrame({ 'time': meta['survival_months'], 'event': meta['vital_status'], 'gene': expr.loc[gene] }) cph = CoxPHFitter() cph.fit(cox_df, duration_col='time', event_col='event') results.append({ 'gene': gene, 'hr': cph.hazard_ratios_['gene'], 'p': cph.summary.loc['gene', 'p'] }) results_df = pd.DataFrame(results) sig_genes = results_df[results_df['p'] < 0.05].sort_values('p')
<!-- 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-16 | pass→pass | 9,069 | 2,531 | -72% | 1 | 1 | 0% | 1,780 | 1,767 | -1% | 0 | 0 | — |
case-01 | pass→pass | 13,929 | 6,402 | -54% | 1 | 1 | 0% | 1,723 | 2,679 | +55% | 0 | 0 | — |
case-02 | pass→pass | 8,081 | 4,105 | -49% | 1 | 1 | 0% | 1,603 | 2,285 | +43% | 0 | 0 | — |
case-03 | pass→pass | 6,284 | 5,820 | -7% | 1 | 1 | 0% | 1,357 | 2,487 | +83% | 0 | 0 | — |
case-04 | pass→pass | 13,932 | 6,227 | -55% | 1 | 1 | 0% | 3,002 | 2,670 | -11% | 0 | 0 | — |
case-05 | pass→pass | 7,274 | 4,192 | -42% | 1 | 1 | 0% | 1,452 | 2,245 | +55% | 0 | 0 | — |
case-06 | pass→pass | 7,342 | 5,990 | -18% | 1 | 1 | 0% | 1,397 | 2,331 | +67% | 0 | 0 | — |
case-07 | fail→pass | 4,742 | 3,138 | -34% | 1 | 1 | 0% | 978 | 2,050 | +110% | 0 | 0 | — |
case-08 | pass→pass | 12,541 | 10,114 | -19% | 1 | 1 | 0% | 2,692 | 3,531 | +31% | 0 | 0 | — |
case-09 | pass→pass | 4,091 | 2,438 | -40% | 1 | 1 | 0% | 717 | 1,797 | +151% | 0 | 0 | — |
case-15 | pass→pass | 8,751 | 2,085 | -76% | 1 | 1 | 0% | 1,584 | 1,726 | +9% | 0 | 0 | — |
case-10 | pass→pass | 10,707 | 4,393 | -59% | 1 | 1 | 0% | 2,032 | 2,142 | +5% | 0 | 0 | — |
case-11 | pass→pass | 8,013 | 5,893 | -26% | 1 | 1 | 0% | 1,695 | 2,617 | +54% | 0 | 0 | — |
case-12 | pass→pass | 15,281 | 4,991 | -67% | 1 | 1 | 0% | 1,820 | 2,481 | +36% | 0 | 0 | — |
case-13 | pass→pass | 11,055 | 7,967 | -28% | 1 | 1 | 0% | 2,053 | 2,732 | +33% | 0 | 0 | — |
case-14 | fail→pass | 11,782 | 5,169 | -56% | 1 | 1 | 0% | 2,198 | 2,311 | +5% | 0 | 0 | — |
case-17 | pass→pass | 7,529 | 4,431 | -41% | 1 | 1 | 0% | 1,399 | 2,147 | +53% | 0 | 0 | — |
case-18 | pass→pass | 11,582 | 6,517 | -44% | 1 | 1 | 0% | 2,308 | 2,668 | +16% | 0 | 0 | — |
case-19 | pass→pass | 10,232 | 4,217 | -59% | 1 | 1 | 0% | 2,094 | 2,290 | +9% | 0 | 0 | — |
case-20 | pass→pass | 11,874 | 10,229 | -14% | 1 | 1 | 0% | 2,502 | 3,396 | +36% | 0 | 0 | — |
case-21 | pass→pass | 16,950 | 13,723 | -19% | 1 | 1 | 0% | 3,061 | 3,860 | +26% | 0 | 0 | — |
case-22 | pass→pass | 14,904 | 11,162 | -25% | 1 | 1 | 0% | 2,878 | 3,489 | +21% | 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. 22 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 22 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/26/2026 | +14% |
Other measured skills in the registry, with their headline benchmark lift.