Assignment 7-A

Model Deployment Project

Build a production-ready ML system with model interpretability (SHAP, LIME), REST API deployment (Flask/FastAPI), Docker containerization, and monitoring. Take your ML skills from notebook to production!

8-10 hours
Advanced
250 Points
Submit Assignment
What You'll Build
  • SHAP & LIME interpretability
  • Flask/FastAPI REST API
  • Docker containerization
  • Production logging & monitoring
  • Complete deployment pipeline
Contents
01

Assignment Overview

In this capstone-level assignment, you will build a complete production-ready ML system. This project bridges the gap between building models in notebooks and deploying them in real-world production environments. You'll implement model interpretability, create REST APIs, containerize with Docker, and set up monitoring - the full MLOps lifecycle!

Production Focus: This is not just about building a model. You must demonstrate that your system can be deployed, monitored, and explained to stakeholders. The API must be functional and the Docker container must run successfully.
Skills Applied: This assignment tests your understanding of SHAP/LIME interpretability, Flask/FastAPI development, Docker containerization, logging, and production best practices.
Interpretability

SHAP values, LIME explanations, feature importance, partial dependence

REST API

Flask/FastAPI endpoints, request validation, error handling

Docker

Containerization, Dockerfile, docker-compose, portability

Monitoring

Logging, metrics tracking, health checks, A/B testing concepts

Ready to submit? Already completed the assignment? Submit your work now!
Submit Now
02

The Scenario

HealthPredict Inc. - Patient Risk Assessment

You have been hired as a Machine Learning Engineer at HealthPredict Inc., a healthcare technology company. The data science team has built a diabetes prediction model, but it's stuck in a Jupyter notebook. The CTO has given you this challenge:

"We have a great model with 85% accuracy, but doctors don't trust black-box predictions. We need to explain WHY the model makes each prediction, deploy it as an API that our hospital partners can integrate, containerize it for easy deployment, and monitor it in production. Can you take this notebook and turn it into a production system?"

Your Task

Build a complete deployment pipeline for a diabetes prediction model. Your system must provide interpretable predictions, expose a REST API, run in Docker, and include production monitoring capabilities.

03

The Dataset

Use the Pima Indians Diabetes dataset or create a similar synthetic dataset with the following structure:

File: diabetes.csv (Diabetes Prediction Data)

pregnancies,glucose,blood_pressure,skin_thickness,insulin,bmi,diabetes_pedigree,age,outcome
6,148,72,35,0,33.6,0.627,50,1
1,85,66,29,0,26.6,0.351,31,0
8,183,64,0,0,23.3,0.672,32,1
1,89,66,23,94,28.1,0.167,21,0
0,137,40,35,168,43.1,2.288,33,1
...
Columns Explained
  • pregnancies - Number of pregnancies (integer)
  • glucose - Plasma glucose concentration (integer)
  • blood_pressure - Diastolic blood pressure mm Hg (integer)
  • skin_thickness - Triceps skin fold thickness mm (integer)
  • insulin - 2-Hour serum insulin mu U/ml (integer)
  • bmi - Body mass index (float)
  • diabetes_pedigree - Diabetes pedigree function (float)
  • age - Age in years (integer)
  • outcome - Target: 0 = No diabetes, 1 = Diabetes (binary)
Dataset Note: You can use the original Pima Indians Diabetes dataset from Kaggle or UCI ML Repository, or generate synthetic data with similar distributions (at least 768 samples).
04

Requirements

Your project must include ALL of the following components. Each component is mandatory and will be tested individually.

1
Model Training Notebook

Create model_training.ipynb that:

  • Loads and preprocesses the diabetes dataset
  • Trains a classification model (Random Forest, XGBoost, or similar)
  • Evaluates with accuracy, precision, recall, F1, and ROC-AUC
  • Saves the trained model using joblib
# model_training.ipynb
import joblib
from sklearn.ensemble import RandomForestClassifier

# Train model
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

# Save model
joblib.dump(model, 'models/diabetes_model.joblib')
joblib.dump(scaler, 'models/scaler.joblib')
2
Model Interpretability Notebook

Create interpretability.ipynb that:

  • Computes feature importance from tree-based models
  • Generates SHAP summary plots (global and local)
  • Creates LIME explanations for individual predictions
  • Plots partial dependence (PDP) and ICE curves
  • Saves all visualizations as PNG files
# interpretability.ipynb
import shap
import lime
from lime.lime_tabular import LimeTabularExplainer

# SHAP
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X_test)
shap.summary_plot(shap_values, X_test, show=False)
plt.savefig('visualizations/shap_summary.png')

# LIME
lime_explainer = LimeTabularExplainer(X_train, feature_names=feature_names)
exp = lime_explainer.explain_instance(X_test[0], model.predict_proba)
exp.save_to_file('visualizations/lime_explanation.html')
3
Flask/FastAPI REST API

Create app.py that implements:

  • GET /health - Health check endpoint
  • POST /predict - Single prediction with probability
  • POST /predict/batch - Batch predictions
  • POST /explain - Prediction with SHAP explanation
  • Input validation using Pydantic (FastAPI) or marshmallow (Flask)
  • Proper error handling with meaningful messages
# app.py (FastAPI example)
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import joblib

app = FastAPI(title="Diabetes Prediction API")

class PatientData(BaseModel):
    pregnancies: int
    glucose: float
    blood_pressure: float
    skin_thickness: float
    insulin: float
    bmi: float
    diabetes_pedigree: float
    age: int

@app.get("/health")
def health_check():
    return {"status": "healthy", "model_loaded": True}

@app.post("/predict")
def predict(patient: PatientData):
    # Load model, make prediction, return result
    pass

@app.post("/explain")
def explain(patient: PatientData):
    # Return prediction with SHAP values
    pass
4
Docker Containerization

Create Dockerfile and docker-compose.yml that:

  • Uses Python 3.9+ slim base image
  • Installs all dependencies from requirements.txt
  • Copies model files and application code
  • Exposes port 8000 for the API
  • Runs the API server on container start
# Dockerfile
FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
# docker-compose.yml
version: '3.8'
services:
  diabetes-api:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - ./logs:/app/logs
    environment:
      - LOG_LEVEL=INFO
5
Logging & Monitoring

Create monitoring.py that:

  • Implements structured logging with timestamps
  • Logs all API requests with input features
  • Logs predictions and response times
  • Tracks prediction distribution over time
  • Saves logs to file and optionally to console
# monitoring.py
import logging
import time
from functools import wraps

logging.basicConfig(
    filename='logs/predictions.log',
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

def log_prediction(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        duration = time.time() - start_time
        logging.info(f"Prediction: {result}, Duration: {duration:.4f}s")
        return result
    return wrapper
6
API Testing Script

Create test_api.py that:

  • Tests all API endpoints
  • Validates response formats and status codes
  • Tests error handling with invalid inputs
  • Includes at least 10 test cases
# test_api.py
import requests
import pytest

BASE_URL = "http://localhost:8000"

def test_health_endpoint():
    response = requests.get(f"{BASE_URL}/health")
    assert response.status_code == 200
    assert response.json()["status"] == "healthy"

def test_predict_valid_input():
    patient_data = {
        "pregnancies": 6, "glucose": 148, "blood_pressure": 72,
        "skin_thickness": 35, "insulin": 0, "bmi": 33.6,
        "diabetes_pedigree": 0.627, "age": 50
    }
    response = requests.post(f"{BASE_URL}/predict", json=patient_data)
    assert response.status_code == 200
    assert "prediction" in response.json()
    assert "probability" in response.json()
7
Documentation

Create comprehensive README.md that includes:

  • Project overview and architecture diagram
  • Installation instructions (local and Docker)
  • API documentation with example requests/responses
  • Model performance metrics
  • Interpretability explanation for non-technical stakeholders
  • Future improvements and scaling considerations
05

Submission

Create a public GitHub repository with the exact name shown below:

Required Repository Name
diabetes-prediction-deployment
github.com/<your-username>/diabetes-prediction-deployment
Required Files
diabetes-prediction-deployment/
├── app.py                      # Flask/FastAPI REST API
├── model_training.ipynb        # Model training notebook
├── interpretability.ipynb      # SHAP, LIME, PDP analysis
├── monitoring.py               # Logging and monitoring utilities
├── test_api.py                 # API test cases
├── requirements.txt            # Python dependencies
├── Dockerfile                  # Docker configuration
├── docker-compose.yml          # Docker Compose configuration
├── diabetes.csv                # Dataset
├── models/
│   ├── diabetes_model.joblib   # Trained model
│   └── scaler.joblib           # Fitted scaler
├── visualizations/
│   ├── shap_summary.png        # SHAP summary plot
│   ├── shap_waterfall.png      # SHAP waterfall (local)
│   ├── lime_explanation.html   # LIME explanation
│   ├── feature_importance.png  # Feature importance bar chart
│   └── pdp_plots.png           # Partial dependence plots
├── logs/
│   └── predictions.log         # Sample prediction logs
└── README.md                   # REQUIRED - comprehensive docs
README.md Must Include:
  • Your full name and submission date
  • Architecture diagram showing system components
  • API documentation with curl/Python examples
  • Model performance metrics (accuracy, F1, ROC-AUC)
  • Docker run instructions
  • Interpretability insights for stakeholders
Do Include
  • All API endpoints working and tested
  • Docker container runs without errors
  • SHAP and LIME visualizations
  • Comprehensive logging implementation
  • At least 10 API test cases passing
  • Clear, professional README
Do Not Include
  • Hardcoded absolute paths
  • API keys or credentials in code
  • Large model files (use joblib compression)
  • Virtual environment folders
  • __pycache__ or .pyc files
  • Incomplete or broken Docker setup
Testing Required: Before submitting, build and run your Docker container locally. Verify all API endpoints work. Run your test suite and ensure all tests pass!
Submit Your Assignment

Enter your GitHub username - we'll verify your repository automatically

06

Grading Rubric

Your assignment will be graded on the following criteria:

Criteria Points Description
Model Training & Performance 30 Model achieves ≥80% accuracy, proper preprocessing, saved correctly
Interpretability (SHAP/LIME) 50 SHAP summary & waterfall, LIME explanations, PDP/ICE plots
REST API Implementation 50 All endpoints working, input validation, error handling, /explain endpoint
Docker Containerization 40 Dockerfile correct, container runs, docker-compose works
Logging & Monitoring 30 Structured logging, request/response tracking, log files generated
Testing 25 At least 10 test cases, all passing, covers edge cases
Documentation & Code Quality 25 Comprehensive README, clean code, proper structure
Total 250

Ready to Submit?

Make sure you have completed all requirements and reviewed the grading rubric above.

Submit Your Assignment
07

What You Will Practice

Model Interpretability

SHAP values for global/local explanations, LIME for instance-level interpretability, PDP/ICE plots

API Development

Building REST APIs with Flask/FastAPI, input validation, error handling, documentation

Docker & Containers

Containerizing ML applications, Dockerfile best practices, docker-compose orchestration

Production MLOps

Logging, monitoring, testing, and deploying ML models in production environments

08

Pro Tips

SHAP Best Practices
  • Use TreeExplainer for tree-based models (faster)
  • Limit background data for KernelExplainer
  • Save SHAP values for later use
  • Create force plots for individual explanations
API Security
  • Validate all input data strictly
  • Don't expose internal error details
  • Rate limit in production
  • Use environment variables for config
Docker Optimization
  • Use multi-stage builds for smaller images
  • Cache pip install layer efficiently
  • Don't copy unnecessary files (.dockerignore)
  • Use slim/alpine base images when possible
Common Pitfalls
  • Forgetting to include model files in Docker
  • Not handling missing values in API input
  • SHAP explainer not matching model type
  • Logs not persisted outside container
09

Pre-Submission Checklist

Code Requirements
Repository Requirements