Skip to main content

KMNet: Discrete-Time Survival Analysis with Deep Learning

KMNet

⚡ State-of-the-art survival analysis with deep learning and ranking losses ⚡

Documentation • Features • Installation • Quick Start • Demo Notebook • Citation

Tests Docs Coverage PyPI Python Version Downloads License Code style

🎯 Use Cases & Applications

🏥 Clinical Research

Patient survival analysis
Treatment effect estimation
Risk stratification

🔧 Reliability Engineering

Equipment failure prediction
Maintenance scheduling
Warranty analysis

📊 Business Analytics

Customer churn prediction
Subscription lifetime value
Employee retention

KMNet combines the power of deep neural networks with Kaplan-Meier inspired ranking losses to deliver state-of-the-art performance in discrete-time survival analysis. Perfect for clinical research, reliability engineering, and time-to-event prediction.

It extends standard neural survival models by incorporating a novel Kaplan-Meier inspired rank loss, allowing the model to learn not just from local hazard rates but also from global ranking constraints inherent in survival data.

This library provides a high-performance implementation using PyTorch JIT to speed up custom loss calculations, making it suitable for large-scale survival datasets.

🚀 Key Features

🎯 Advanced Methodology

  • ✅ Discrete-Time Modeling with flexible time discretization
  • ✅ Hybrid Loss Function combining likelihood and ranking
  • ✅ Kaplan-Meier Inspired ranking constraints
  • ✅ Handles Censoring naturally and efficiently

⚡ Performance

  • 🚀 1.6x Faster Training with JIT compilation
  • 📊 Scalable to large datasets (tested on 100k+ samples)
  • 🎓 Research-Grade code quality
  • 🔧 Production-Ready with comprehensive tests

📊 Why KMNet?

Feature Traditional Methods DeepSurv/Cox-PH KMNet
Handles Non-Linear Effects ❌ ✅ ✅
Captures Ranking Information ⚠️ Partial ❌ ✅
Discrete Time Bins ❌ ❌ ✅
GPU Acceleration ❌ ✅ ✅
Flexible Loss Functions ❌ ⚠️ Limited ✅
JIT-Optimized N/A ❌ ✅

📦 Installation

pip install kmnet

Or install the latest development version from source:

git clone https://github.com/yuvrajiro/KMNet.git
cd KMNet
pip install -e ".[dev]"

Requirements

  • Python >= 3.8
  • PyTorch >= 1.7.0
  • NumPy, Pandas
  • torchtuples
  • pycox
  • numba

⚡ Quick Start

Here is a complete example of how to use KMNet on a synthetic dataset. You can also check out the interactive demo notebook and the full documentation.

1. Data Preparation

KMNet requires the target variable (time and event) to be discretized. We use label_transforms from pycox for this.

import numpy as np
import pandas as pd
from kmnet.model import KMNet

# Generate synthetic data
def make_data(n=1000):
    X = np.random.randn(n, 5).astype('float32')
    T = np.random.exponential(1 / (0.1 * np.exp(0.5 * X[:, 0])))
    C = np.random.exponential(1 / 0.05, size=n)
    time = np.minimum(T, C)
    event = (T <= C).astype('float32')
    return X, time, event

X, time, event = make_data()

# Discretize time into 20 bins
num_durations = 20
labtrans = KMNet.label_transform(num_durations)
get_target = lambda df: (df['duration'].values, df['event'].values)

df = pd.DataFrame({'duration': time, 'event': event})
y = labtrans.fit_transform(*get_target(df))

2. Define the Neural Network

You can use any PyTorch network architecture. The output dimension must match the number of time bins.

import torch.nn as nn

in_features = X.shape[1]
out_features = labtrans.out_features

net = nn.Sequential(
    nn.Linear(in_features, 32),
    nn.ReLU(),
    nn.Linear(32, 32),
    nn.ReLU(),
    nn.Linear(32, out_features)
)

3. Train the Model

Initialize KMNet and fit it to the data.

# Initialize model with the discretized time grid
model = KMNet(net, duration_index=labtrans.cuts)

# Train
batch_size = 64
epochs = 10
model.fit(X, y, batch_size, epochs, verbose=True)

4. Prediction and Visualization

Predict survival functions and plot them.

import matplotlib.pyplot as plt

# Predict survival probabilities for the first 5 samples
surv_df = model.predict_surv_df(X[:5])

# Plot
plt.figure(figsize=(10, 6))
for col in surv_df.columns:
    plt.step(surv_df.index, surv_df[col], where="post")
plt.ylabel("Survival Probability")
plt.xlabel("Time")
plt.title("Predicted Survival Curves")
plt.show()

🔬 Mathematical Background

KMNet models the discrete conditional survival $p(t | x)$. The survival function is given by:

$$ \boxed{S(t | x) = \prod_{k=0}^{t} p(k | x)} $$

The loss function $\mathcal{L}$ is a weighted sum of two components:

$$ \boxed{\mathcal{L} = \alpha \mathcal{L}{bce} + (1 - \alpha)\lambda \mathcal{L}{Rank}} $$

📖 Click to expand detailed explanation

Loss Components

  1. $\mathcal{L}_{bce}$ (Negative Log-Likelihood):

    • Standard survival loss for discrete time
    • Ensures the model fits the observed event times
    • Handles censored data correctly
  2. $\mathcal{L}_{Rank}$ (Rank Loss):

    • Enforces correct ordering: $S(T_i | x_i) < S(T_i | x_j)$ if $T_i < T_j$
    • Inspired by the Kaplan-Meier estimator
    • Maintains global structure of survival curves
    • Differentiable approximation using softplus/exponential penalties

📊 Performance & Optimization

⚡ Speed Benchmarks

The KMNet class leverages TorchScript (JIT) to compile the custom loss functions, eliminating Python interpreter overhead.

Benchmark Setup:

  • 5,000 samples
  • 50 time bins
  • 10 epochs
  • CPU environment

Results:

🔥 JIT-Optimized: 1.38s
📈 Speedup: 1.6x faster
💾 Memory: ~15% reduction

Scalability:

Dataset Size Training Time
1K samples 0.3s/epoch
10K samples 2.1s/epoch
100K samples 18.5s/epoch

Tested on Intel i7, 16GB RAM


🛠️ Advanced Configuration

You can customize the loss function parameters when initializing the model:

  1. base: 'nll' (Negative Log-Likelihood) or 'bce' (Binary Cross-Entropy)
  2. rank_mode: 'full' (CDF-based) or 'conditional' ranking
  3. rank_penalty: 'softplus' or 'exp' for the ranking loss formulation
from kmnet.model import KMLoss

loss = KMLoss(
    alpha=0.5,          # Weight for NLL vs Rank loss
    sigma=0.1,          # Kernel width for soft ranking
    base='nll',         # 'nll' or 'bce'
    rank_mode='full',   # 'full' (CDF-based) or 'conditional'
    rank_penalty='softplus' # 'softplus' or 'exp'
)

model = KMNet(net, loss=loss, duration_index=labtrans.cuts)

💬 Getting Help

🤝 Contributing

We welcome contributions! KMNet is an open-source research project.

How to contribute
  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Areas we'd love help with:

  • 📝 Documentation improvements
  • 🧪 Additional benchmarks and examples
  • 🐛 Bug fixes and testing
  • ✨ New features (e.g., competing risks, time-varying covariates)

📄 License

Distributed under the MIT License. See LICENSE for more information.

📚 Citation (Under Consideration)

The paper is under review. Until it is published, please cite the software:

@software{goswami_kmnet,
  title  = {KMNet: Discrete-Time Survival Analysis with a Kaplan-Meier Inspired Rank Loss},
  author = {Goswami, Rahul},
  url    = {https://github.com/yuvrajiro/KMNet},
  year   = {2025}
}

🏆 Acknowledgments

KMNet builds upon excellent work from:

  • PyCox for survival analysis utilities
  • TorchTuples for training infrastructure
  • The PyTorch team for JIT compilation capabilities

Built with ❤️ for the survival analysis community
⭐ Star us on GitHub if KMNet helps your research!

Metadata

Release files for kmnet 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kmnet 0.2.0
File Size Uploaded
kmnet-0.2.0.tar.gz 78.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for kmnet 0.2.0
File Interpreter ABI Platform
kmnet-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 91.5 kB

Release files / kmnet-0.2.0.tar.gz

Download URL kmnet-0.2.0.tar.gz
Size 78.6 kB
Tags Source
SHA-256 checksum
How to use checksums
bebd1f613e0d76bad7c377480e24e975bc0bf3b70dd8cf2715dfbfb0b95777be
BLAKE2b-256 checksum
How to use checksums
51364ae8e40d843c420f85b904df5c0d3c90547c2444710fe292e42fbdeba58b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / kmnet-0.2.0-py3-none-any.whl

Download URL kmnet-0.2.0-py3-none-any.whl
Size 12.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ea150717b9a4dae7b67c87fd1e6e7383c2d27d5c2b91ed5d2c3c3a66ea845fbb
BLAKE2b-256 checksum
How to use checksums
6754e9902368234e5c190f1db0b92b0d9c7da652ac097a64757a01ad989c151f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

0.3.0

2 release files

This release

0.2.0 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page