Predicting 30-Day Hospital Readmission for Diabetic Patients
When a patient leaves the hospital and comes back within a month, something has usually gone wrong. Maybe a medication wasn't adjusted, follow-up care didn't happen, or the patient went home before they were ready. Thirty-day readmissions are costly for health systems and, more importantly, often preventable. For patients with diabetes, a chronic condition that touches nearly every organ system, the risk is especially high.
I designed this project as the learning focus for the RCMI Summer Data Science Research Training Opportunity, a program that introduces trainees to biomedical data science through one real, end-to-end machine learning problem. This article lays out the project, why I chose it, how I frame the modeling problem, and the 10-week path trainees follow from their first import pandas to a finished, presentable model.
The project at a glance - Dataset: Diabetes 130-US Hospitals for Years 1999–2008 (UCI Machine Learning Repository) - Objective: predict whether a diabetic patient will be readmitted within 30 days, based on demographic, admission, and medical data - Task type: binary classification
This is a project design and curriculum, not a results write-up. Trainees produce the models and findings, and that's the point.
Why This Project?
I wanted a first project that was real, meaningful, and rich enough to teach the whole craft. Readmission prediction checks all three boxes.
1. It's a genuine biomedical problem. Hospital readmission for diabetic patients is a significant concern for health systems worldwide. Trainees work with a real clinical dataset and run into the real challenges of health data, not a toy.
2. It puts minority health and health disparities front and center. Diabetes disproportionately affects certain populations. Working on this problem invites trainees to ask how social determinants of health shape outcomes, and whether a model performs equally well for every group it will be used on. For an RCMI program, that question is central, not optional.
3. The dataset is rich and messy in instructive ways. It mixes numerical (length of stay, number of lab procedures, number of medications), categorical (admission type, discharge disposition, medical specialty), and ordinal (age bands, lab result levels) features. That variety forces trainees to practice the full preprocessing toolkit: handling missing values, encoding categorical variables, and scaling numeric ones.
4. There's real room for feature engineering. Raw diagnosis codes can be grouped into comorbidity categories. Prior-visit counts can be combined into a measure of healthcare utilization. Medication-change columns can be summarized. Good features are often worth more than a fancier algorithm, and this dataset rewards thinking.
5. It's a clean introduction to classification. The target is binary (readmitted within 30 days or not), which is the most fundamental supervised learning setup. Trainees compare logistic regression, decision trees, random forests, and support vector machines on the same problem.
6. It teaches honest model evaluation. Readmission within 30 days is the minority outcome, so accuracy alone is misleading. Trainees have to learn precision, recall, F1, ROC curves, and cross-validation, and then hyperparameter tuning to squeeze out real improvements.
Framing the Problem
The first real decision is what exactly we're predicting. In this dataset, each row is a hospital encounter, and the readmitted column records whether the patient came back within 30 days (<30), after more than 30 days (>30), or not at all (NO). Our clinical question is about the 30-day window, so I collapse it to a binary target:
- 1 = readmitted in under 30 days
- 0 = everything else (readmitted later, or not readmitted)
That choice has consequences. It makes the positive class relatively rare, which shapes every evaluation decision downstream.
A few other framing questions I make trainees answer before writing model code:
- One row per encounter, or per patient? Some patients appear many times. If the same patient lands in both the training and test sets, the model can "recognize" them, and the test score will be inflated. Splitting by patient avoids that leak.
- Who is eligible? Encounters that ended in death or hospice discharge can't be followed by a readmission, so they arguably don't belong in the population we're predicting for.
- Which error costs more? Missing a patient who will be readmitted (false negative) means a missed chance to intervene. Flagging a patient who wouldn't have been (false positive) means some wasted follow-up effort. In most care settings the first is worse, so recall on the positive class matters a lot.
import pandas as pd
df = pd.read_csv("diabetic_data.csv")
# Missing values are encoded as "?" in this dataset
df = df.replace("?", pd.NA)
# Binary target: readmitted within 30 days
df["readmit_30"] = (df["readmitted"] == "<30").astype(int)
# Always check the balance before choosing metrics
print(df["readmit_30"].value_counts(normalize=True))The Pipeline
Here's the end-to-end pipeline trainees build, step by step.
1. Exploratory data analysis
Load the data, inspect types and distributions, compute summary statistics, and look for missing values and outliers. Plot readmission rates against age, length of stay, number of prior inpatient visits, and demographic groups. EDA is where the first hypotheses come from, and where data quality problems surface.
2. Cleaning and preprocessing
- Missing data: some columns are mostly missing and may need to be dropped, while others can be imputed or given an explicit "Unknown" category. In health data, missingness itself can be informative: a lab that wasn't ordered tells you something.
- Duplicates and inconsistencies: check for repeated encounters and invalid codes.
- Encoding: one-hot encode nominal categories, and map ordinal ones (like age bands) to ordered integers.
- Scaling: standardize numeric features for distance- and gradient-based models.
3. Feature engineering
This is where domain knowledge pays off:
- Group ICD-9 diagnosis codes into clinically meaningful comorbidity categories (circulatory, respiratory, diabetes-related, and so on).
- Combine outpatient, emergency, and inpatient visit counts into a prior-utilization score.
- Summarize the many medication columns into "number of medications changed" or "insulin adjusted."
- Use length of stay (
time_in_hospital) directly, or bucket it.
Then apply feature selection (filter, wrapper, and embedded methods) to keep what's informative.
4. Modeling
Train and compare several classifiers on identical splits:
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold, cross_validate
numeric = ["time_in_hospital", "num_lab_procedures", "num_medications",
"number_outpatient", "number_emergency", "number_inpatient"]
categorical = ["race", "gender", "age", "admission_type_id",
"discharge_disposition_id", "A1Cresult", "insulin"]
preprocess = ColumnTransformer([
("num", Pipeline([("impute", SimpleImputer(strategy="median")),
("scale", StandardScaler())]), numeric),
("cat", Pipeline([("impute", SimpleImputer(strategy="constant", fill_value="Unknown")),
("onehot", OneHotEncoder(handle_unknown="ignore"))]), categorical),
])
models = {
"logistic": LogisticRegression(max_iter=1000, class_weight="balanced"),
"random_forest": RandomForestClassifier(n_estimators=300, class_weight="balanced",
random_state=42),
}
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
X, y = df[numeric + categorical], df["readmit_30"]
for name, model in models.items():
pipe = Pipeline([("prep", preprocess), ("model", model)])
scores = cross_validate(pipe, X, y, cv=cv,
scoring=["roc_auc", "recall", "precision", "f1"])
print(name, {k: v.mean().round(3) for k, v in scores.items() if k.startswith("test_")})A few deliberate choices in that sketch:
- Everything lives inside a
Pipeline, so imputation and scaling are fit only on each training fold. No leakage. class_weight="balanced"tells the model to pay more attention to the rare positive class. Resampling is another option.StratifiedKFoldkeeps the readmission rate the same in every fold.- The scoring list leads with ROC-AUC and recall, not accuracy. On an imbalanced target, a model that predicts "no readmission" for everyone can look very accurate and be useless. (For a production version I'd also switch to grouped CV by patient ID, as discussed above.)
5. Evaluation
Report the confusion matrix, precision, recall, and F1 for the positive class, the ROC curve and AUC, and the precision–recall curve, which is often more informative than ROC when positives are rare. Then pick a decision threshold that matches the clinical use case. If a care team can follow up with 50 patients a week, tune the threshold to surface the 50 highest-risk patients.
6. Model selection and tuning
Use grid search or random search over hyperparameters, and try regularization (Lasso, Ridge, Elastic Net) for logistic regression to manage the many one-hot features. Compare models on cross-validated scores, then confirm the final choice once on a held-out test set.
7. Fairness and interpretation
Break performance down by race, gender, and age group. A model with a good overall AUC can still systematically miss high-risk patients in one group. Look at which features drive predictions (coefficients for logistic regression, feature importances or SHAP values for tree models) and ask whether they make clinical sense.
The 10-Week Roadmap
The training program walks trainees through the pipeline one layer at a time:
| Week | Focus | What trainees do |
|---|---|---|
| 1 | Biomedical data science & Python | Set up Anaconda and Jupyter; Python basics (variables, loops, functions, libraries); project overview |
| 2 | Exploratory data analysis | Load and inspect the dataset with pandas; summary statistics and distributions; missing values and outliers in health data |
| 3 | Data visualization | Matplotlib, Seaborn, and Plotly; visualize distributions, relationships, and comparisons specific to the diabetes data |
| 4 | Cleaning & preprocessing | Imputation, de-duplication, fixing inconsistencies, normalization and standardization |
| 5 | Feature engineering | Create new features from existing ones; feature selection (filter, wrapper, embedded) |
| 6 | Classification algorithms | Logistic regression, decision trees, random forests, and SVMs in scikit-learn, applied to readmission |
| 7 | Model evaluation | Accuracy, precision, recall, F1, ROC/AUC, confusion matrix, classification report; k-fold and stratified k-fold CV |
| 8 | Model selection & tuning | Grid and random search; Lasso, Ridge, and Elastic Net; choosing the best model |
| 9 | Full implementation | Assemble the complete pipeline; test the final model on a holdout set; analyze and draw conclusions |
| 10 | Documentation, presentation & ethics | Document code and analysis; write a report or blog post; present the work; discuss research ethics and responsible conduct; share on GitHub or at HU-RCMI research seminars |
The order is deliberate. Trainees spend the first half of the program understanding the data before they train a single model. In my experience, that's where most of the real insight, and most of the real bugs, are found.
What Trainees Walk Away With
By the end, trainees have:
- Proficiency in Python and the core data science stack (pandas, NumPy, matplotlib, seaborn, scikit-learn), applied to biomedical research.
- Hands-on experience with real clinical data: cleaning, preprocessing, and feature engineering on a messy, mixed-type dataset.
- A working understanding of classification, and of how to pick the right algorithm for a health-outcomes problem.
- The judgment to evaluate models honestly, including imbalanced classes, threshold selection, cross-validation, and subgroup performance.
- Data visualization skills for both analysis and communication.
- A finished, portfolio-ready project that demonstrates real competency in biomedical data science to employers and collaborators.
Key Takeaways
- Start from a real question. "Will this diabetic patient be back within 30 days?" is concrete, consequential, and actionable.
- Framing is half the work. Define the target, the eligible population, and the costs of each error before you model.
- Respect the imbalance. Lead with recall, precision, F1, and AUC, not accuracy.
- Keep preprocessing inside the pipeline and split by patient to avoid leakage.
- Check fairness explicitly. In a health-disparities context, a model that works "on average" isn't good enough.
- Teach the whole craft. EDA, cleaning, features, models, evaluation, ethics, and communication are all part of data science.
The statistics, supervised learning, and classification articles in this series are the building blocks. This project is where they come together on a problem that matters.
Comments (0)