Medical Procedure Time Prediction using Stepwise Regression in ML

Get Job-ready with hands-on learning & real-time projects - Enroll Now!

Operating rooms (ORs) are high‑cost environments where inaccurate estimates of procedure duration can lead to scheduling inefficiencies, increased patient wait times, and resource under‑ or over-utilisation.

In this medical procedure time prediction ML project, we will predict the duration of surgical procedures based on pre‑operative features—such as procedure type, patient demographics (age, BMI), and surgeon characteristics—by fitting a linear regression model with stepwise feature selection. Therefore, the resulting model will identify the key influencers of procedure time, helping hospital administrators reduce operational costs.

Libraries Required

import pandas as pd               # Data manipulation  
import numpy as np                # Numerical operations  
import statsmodels.api as sm      # Statistical modeling (OLS)  
from sklearn.model_selection import train_test_split   # Data splitting  
from sklearn.metrics import r2_score, mean_squared_error  # Evaluation  
import matplotlib.pyplot as plt   # Visualization  

Dataset

Prediction of Surgery Duration

Step-by-Step Code Implementation

Data Loading & Initial Inspection

We load the CSV from Kaggle. Initial commands (.head(), .info(), .describe()) reveal data types, missing values, and basic statistics.

# Block 1: Load dataset
# Kaggle Competition: Prediction of Surgery Duration :contentReference[oaicite:1]{index=1}
df = pd.read_csv("train.csv")  

# Inspect the data
print(df.head())
print(df.info())

Data Preprocessing

Categorical fields—such as ProcedureType and SurgeonID—are transformed via one‑hot encoding. We then drop any rows with missing entries to maintain a clean modelling dataset. The features matrix X excludes the Duration column, which serves as our response variable y. The data is divided into training (80%) and testing (20%) sets.

# Block 2: Encode categoricals and clean
# Assume columns: 'ProcedureType', 'SurgeonID', 'PatientAge', 'PatientBMI', plus other numeric features, target='Duration'
df_enc = pd.get_dummies(df, columns=["ProcedureType", "SurgeonID"], drop_first=True)

# Drop rows with missing values, if any
df_enc = df_enc.dropna()

# Define predictors and target
X = df_enc.drop("Duration", axis=1)
y = df_enc["Duration"]

# Split into training and test sets (80/20)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

Stepwise Regression Function

The stepwise_selection function iteratively performs:

  • Forward Inclusion: Adds the excluded predictor with the smallest p‑value below 0.01.
  • Backward Elimination: Removes the included predictor with the largest p‑value above 0.05.

This process continues until no variables meet the criteria for addition or removal, yielding a parsimonious set of significant predictors.

# Block 3: Forward–backward stepwise selection
def stepwise_selection(X, y, 

                       initial_list=[], 

                       threshold_in=0.01, 

                       threshold_out=0.05, 

                       verbose=True):

    included = list(initial_list)
    while True:
        changed = False

        # Forward step: try adding each excluded variable
        excluded = list(set(X.columns) - set(included))
        new_pvals = pd.Series(index=excluded, dtype=float)
        for col in excluded:
            model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[included + [col]]))).fit()
            new_pvals[col] = model.pvalues[col]
        best_pval = new_pvals.min()
        if best_pval < threshold_in:
            best_var = new_pvals.idxmin()
            included.append(best_var)
            changed = True
            if verbose:
                print(f"Add  {best_var:30} p-value {best_pval:.6f}")

        # Backward step: try removing each included variable
        model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[included]))).fit()
        pvals = model.pvalues.iloc[1:]  # exclude intercept
        worst_pval = pvals.max()
        if worst_pval > threshold_out:
            worst_var = pvals.idxmax()
            included.remove(worst_var)
            changed = True
            if verbose:
                print(f"Drop {worst_var:30} p-value {worst_pval:.6f}")

        if not changed:
            break

    return included

Model Building & Evaluation

Using the selected features, we fit an Ordinary Least Squares regression via statsmodels. The printed .summary() provides coefficient estimates, p‑values, R², adjusted R², and diagnostic statistics (e.g., AIC, F‑statistic), offering insights into predictor significance and overall model fit.

Predictions on the held‑out test set allow us to compute R² (explained variance) and RMSE (root‑mean‑square error), quantifying the model’s predictive performance on unseen data.

# Block 4: Feature selection
selected_features = stepwise_selection(X_train, y_train)

# Fit the final OLS model
X_train_sel = sm.add_constant(X_train[selected_features])
model = sm.OLS(y_train, X_train_sel).fit()
print(model.summary())

# Predict on test set
X_test_sel = sm.add_constant(X_test[selected_features])
y_pred = model.predict(X_test_sel)

# Compute performance metrics
print("Test R²:", r2_score(y_test, y_pred))
print("Test RMSE:", np.sqrt(mean_squared_error(y_test, y_pred)))

Residual Diagnostics

A residual plot (predicted vs. residuals) checks for non‑random patterns, heteroscedasticity, or outliers—key assumptions for validating the linear regression model.

# Block 5: Residual plot
residuals = y_test - y_pred
plt.scatter(y_pred, residuals)
plt.axhline(0, linestyle="--")
plt.xlabel("Predicted Duration (minutes)")
plt.ylabel("Residuals")
plt.title("Residuals vs. Predicted Duration")
plt.show()

Summary

By applying stepwise regression to surgical procedure data, we find the most influential factors—such as specific procedure types, surgeon identifiers, and patient characteristics—that drive operation duration. Thus, the resulting linear model is both interpretable and performant, achieving a strong balance between explanatory insight (through p‑values and coefficients) and predictive accuracy (high test‑set R², low RMSE).

As a Result, Hospitals can leverage this model to improve OR scheduling, enhance resource utilisation, and reduce costs associated with under‑ or over‑booking surgical slots.

Your 15 seconds will encourage us to work even harder
Please share your happy experience on Google | Facebook


PythonGeeks Team

The PythonGeeks Team delivers expert-driven tutorials on Python programming, machine learning, Data Science, and AI. We simplify Python concepts for beginners and professionals to help you master coding and advance your career.

Leave a Reply

Your email address will not be published. Required fields are marked *