
Architecting an End-to-End MLOps & Real-Time Student Risk Prediction Engine with Amazon SageMaker, TreeSHAP Explainability, and Amazon Bedrock
Production blueprint for K-12 student academic risk prediction on AWS: resolving a 35:1 class imbalance and target leakage across 98,996 records, benchmarking Logistic Regression, Decision Trees, Random Forest, and XGBoost, and automating governance with SageMaker Pipelines, Model Registry, PrivateLink, and Bedrock.
Catching K-12 students before they fail a school term (
Final_grade ≤ 13 on a 20-point scale) is a delicate balance: missing a struggling student delays support, while flooding counselors with false alarms erodes trust. Taking a model from a local notebook into school operations on AWS requires leak-free data pipelines, a solid strategy for class imbalance, fast explainability, and strict privacy controls.
In the C4 Context View (L1) above, Counselors and Teachers get sub-10ms risk predictions and TreeSHAP explanations in their portal, while Lead ML Engineers manage retraining through Amazon SageMaker Pipelines. Student records flow into Amazon SageMaker Feature Store (Online + Offline Iceberg), and Amazon Bedrock (
Claude 3.5 Haiku + Guardrails) turns top risk drivers into action plans:1. Class Imbalance (35:1 Ratio): Across 98,996 records, only 2.22% (2,196) are High Risk (Grade 1.0), vs. 19.80% Moderate (Grade 2.0) and 77.98% Low Risk (Grade 3.0). A default model hits 77.98% Accuracy while missing almost every failing student.2. Zero Data Leakage & Train/Serve Skew: Scaling, outlier cleanup, and grade averages are fitted strictly onX_trainin SageMaker Processing. All 27 features are stored in SageMaker Feature Store (Offline Icebergfor training +Online Store< 3 msGetRecordlookups in production).3. Sub-7ms Explainability & Action Plans: Native C++ TreeSHAP (0.50 ms) pulls the top 4 risk drivers per student and feeds a rule matrix and Amazon Bedrock to draft Individualized Intervention Plans (IIPs).4. Auditable Governance (ISO/IEC 23053) & Privacy: Network-isolated containers (enable_network_isolation = true), AWS PrivateLink, KMS CMK encryption,HMAC-SHA256tokenization, and SageMaker Model Registry gates keep student data protected.
1. Dataset Audit, Data Leakage Remediation & Feature Engineering
1.1 Unified Student Feature Schema (98,996 Records × 18 Attributes)
Six years of academic, attendance, portal, infirmary, behavioral, and tuition records (
2019–2024 , Terms 1..4 ) form 98,996 student-term rows:Feature / Column | Type | Range | Description & Source |
|---|---|---|---|
Student_Id | string | HMAC-SHA256 | Tokenized id_grupo.id_persona hashed before S3 ingestion |
Year_of_study / Term | int64 | 2019..2024 / 1..4 | School year and bimester/trimester ( 1 to 4 ) |
Grado / Nivel | int64 | 3..17 / 1..3 | Grade level and stage ( 1 = Early, 2 = Primary, 3 = Secondary) |
Age | float64 | 3.0..20.0 | Student age at cutoff (412 ERP typos up to 108.04 ) |
Sex / Guardian | float64 | 0, 1 | Biological sex ( 50.16% ) and parent legal guardian ( 90.02% ) |
Siblings_cnt / Parents_cnt | int64 | 0..3 / 0..4 | Enrolled siblings ( 0.35 ) and registered parents ( 1.31 ) |
Parent_interaction | float64 | 0.0..1.0 | Portal activity: (logins + agenda + news + report_cards) / 4 |
Payment_ratio | float64 | 0.0..1.0 | Ratio of on-time tuition payments to billed installments |
Sickness_cnt / Alergies_cnt | int64 | 0..2 / 0..3 | Infirmary visits and documented allergies |
Classroom_transfer / School_change | int64 | 0, 1 | Classroom switch ( 0.85% ) or school transfer ( 0.48% ) |
Awards_ratio / Summer_school | int64 | -1..1 / 0, 1 | Conduct ( +1 merit, -1 demerit) & summer school ( 1.81% ) |
Final_grade (Target y ) | float64 | 1.0, 2.0, 3.0 | 1.0 = High Risk (≤13, 2.22%), 2.0 = Mod (19.80%), 3.0 = Low (77.98%) |
1.2 Eliminating Target Leakage & Domain Outliers in SageMaker Processing
Auditing early notebooks showed why prototypes fail in production: a single column (
academic_trajectory ) held 43.66% of Gini importance, artificially inflating High-Risk Precision to 0.70 and ROC-AUC to 0.895 . Raw exports also had 412 corrupted Age rows ( 0.42% ) up to 108.04 years from birth-date typos.1. Direct Target Leakage (Final_grade.diff()): ComputingFinal_grade.diff()before separatingyembeds the current term's grade insideX.2. Full-Dataset Scaling Leakage: Runninggroupby('Grado')averages andStandardScaler().fit_transform(df)before splitting leaks test statistics into training.3. Stateful Fix (LeakFreeStudentFeatureEngineer) & Feature Store: Cleaning and feature math run inside a Scikit-Learn transformer in SageMaker Processing, learning grade medians (Age ∈ [3.0, 20.0]), means, and standard deviations only onX_train(69,296rows). The 27 leak-free features are ingested into SageMaker Feature Store (student-academic-risk-fg-prod), using the Offline Store (S3 Iceberg) for training and the Online Store for< 3 msGetRecordlookups:
Engineered Feature | Formula / Definition | Practical Meaning |
|---|---|---|
age_acceleration | Age / max(Grado, 1) | Flags students older than expected for their grade |
age_zscore_in_grade | (Age - μ_train(Grado)) / σ_train(Grado) | Age deviation vs. classmates (fitted on X_train ) |
grade_speed | Grado / max(Year_of_study - 2015, 1) | Pace of grade progression across school years |
age_parent_interaction | Age × Parent_interaction | Parent portal activity weighted by student age |
relative_parent_engagement | Parent_interaction - μ_train_parent(Grado) | Parent portal usage vs. grade peers |
academic_support_index | Parent_interaction × Parents_cnt × (1 - School_change) | Household support, portal activity, and stability |
risk_accumulation | Sum of 6 binary flags ( Sickness , Payment , etc.) | Count of simultaneous health, payment, or conduct flags |
financial_engagement_index | Payment_ratio × (Parent_interaction + 0.1) | Link between on-time tuition and portal activity |
mobility_stress_index | Classroom_transfer + (2 × School_change) + Summer_school | Stress from switching classrooms/schools or summer school |
term_completion | Term / 4.0 | Point in the school year ( 0.25 to 1.0 ) |
2. Multi-Model Benchmarking & Solving the 35:1 Class Imbalance
2.1 Why Accuracy and ROC-AUC Mislead on a 2.22% Minority Class
With
77.98% Low Risk, 19.80% Moderate Risk, and 2.22% High Risk students, standard Accuracy and ROC-AUC hide bad performance on failing students because non-failing students outnumber failing ones by 35 to 1. The SageMaker Pipeline Gate therefore evaluates PR-AUC (High Risk), High-Risk Recall ( Recall_Class_1 ), Macro F1, and p99 Latency.2.2 Benchmark Across 4 Model Families & 3 Imbalance Strategies (SageMaker Script Mode)
This architecture runs SageMaker Managed Containers in Script Mode (
sagemaker-scikit-learn:1.2-1 and sagemaker-xgboost:1.7-1 ). AWS handles image patching and C++ runtime tuning, while custom scripts ( train_xgboost.py , inference.py ) control sample weights, threshold tuning, and SHAP extraction across the leak-free splits ( Train = 69,296 , Val = 9,900 , Test = 19,800 ):1. Global Classification & Inference Latency (
Test = 19,800 ):
2.3 Key Engineering Takeaways from the Benchmark
- Why Unweighted Models Fail: Unweighted Random Forest and XGBoost reach
> 80%accuracy, yet High-Risk Recall is only8.88%and13.44%(2.28%in Logistic Regression). 86% to 97% of failing students are missed because standard loss functions optimize for the77.98%Low-Risk majority.
- Why Full SMOTE (
k=5) Hurts Precision: Oversampling all classes to[54,039 × 3]withSMOTEpushes Random Forest Recall to50.34%, but drops accuracy from80.18%to69.71%and cuts High-Risk Precision to20.95%. Interpolating across discrete whole-number features (Term,Grado,Awards_ratio,Summer_school) creates unrealistic synthetic students, lowering PR-AUC (0.2687 → 0.2472).
- Why Cost-Sensitive XGBoost + Threshold Tuning (
τ_high = 0.33,τ_mod = 0.41) Wins: Sample weights ({High: 5.5, Mod: 1.8, Low: 1.0}) with regularized trees (max_depth=6,min_child_weight=10,gamma=0.2,reg_lambda=2.0) and threshold tuning boost High-Risk Recall by 3.3× (13.44% → 43.96%) while keeping77.25%accuracy,PR-AUC = 0.2875,0.21 msp99 latency (66× faster than RF), and0.50 msC++ TreeSHAP.
Architecture Decision Record: Model Family & Imbalance Strategy Selection
Architecture Decision Record (ADR-01: Cost-Sensitive XGBoost vs. SMOTE & Deep Tabular Models):
- Context: Classify K-12 students into 3 risk tiers across 98,996 rows with a 35:1 imbalance (
2.22%High Risk), discrete features, and a< 25 msp99 SLA.
- Decision: Use SageMaker XGBoost (
1.7-1Script Mode) with weights ({1: 5.5, 2: 1.8, 3: 1.0}), tuned cutoffs (τ_high = 0.33,τ_mod = 0.41), and nativepred_contribs=TrueTreeSHAP.
- Rejected Alternatives:
- Random Forest + SMOTE (
k=5): Cut accuracy by-10.47%(80.18% → 69.71%), lowered PR-AUC (0.2875 → 0.2472), and ran 66× slower at p99 (13.99 msvs.0.21 ms).
- Deep Tabular Neural Networks (MLP / TabNet): Need GPU instances (
ml.g4dn.xlarge, ~3.8× cost), underperform GBDTs on< 100kdiscrete rows, and lack sub-ms TreeSHAP.
- Trade-Off Accepted: Accepting
28.55%High-Risk Precision (~2.5 check-ins per failing student) and threshold tuning to catch 43.96% of High-Risk students (3.3× recall gain) at0.21 msp99.
3. Multi-Tier Cloud Architecture & Topology Diagrams
Building on the C4 Context View (L1) at the start, the AWS infrastructure is organized into three views covering MLOps workflows, production security, and network isolation.
3.1 High-Level MLOps & Real-Time Inference Topology
- Online Inference Path: Requests hit API Gateway (
/predict-risk) secured by WAF and Cognito JWT. A Lambda Orchestrator hashesStudent_Id, pulls the 27 features in< 3 msfrom SageMaker Feature Store (Online) viaGetRecord, and calls the SageMaker Real-Time Endpoint (ml.m5.large) over PrivateLink for probabilities and top 4 TreeSHAP factors (~6.88 ms). Wheninclude_bedrock_narrative = truefor High/Moderate risk, it calls Amazon Bedrock (Claude 3.5 Haiku+ Guardrails) to draft an action plan.
- Offline MLOps Path: Term records in Amazon S3 trigger a SageMaker Pipeline that runs leak-free preprocessing, updates SageMaker Feature Store (Online + Offline Iceberg), trains XGBoost on Managed Spot Instances, checks PR-AUC and Recall, and registers passing models in Model Registry. Approvals trigger EventBridge to run 20% Canary Blue/Green deployments.

3.2 End-to-End Production Architecture
- Encryption & Privacy: A dedicated AWS KMS CMK encrypts S3, Feature Store, EBS volumes, Data Capture, and Bedrock Guardrails. CloudWatch Logs Data Protection masks accidental PII in logs.
- Drift & Fairness Monitoring: The endpoint saves 100% Data Capture to S3. SageMaker Model Monitor compares live inputs against
statistics.json/constraints.json, while SageMaker Clarify tracks SHAP Attribution Drift and fairness acrossSexandGuardian.
- Automated Retraining Loop: If Model Monitor or
HighRiskPredictionRate > 15%breaches for 2 windows, CloudWatch Alarms trigger EventBridge to rerunStudentAcademicRiskMLOpsPipeline.

3.3 Zero-Trust Network & VPC Segmentation Topology
To protect student data under FERPA, all workloads run inside an isolated VPC (
10.50.0.0/16 ) across us-east-1a and us-east-1b with no Internet Gateways (IGW) and no NAT Gateways:- Private Orchestration Subnets (
10.50.10.0/24,10.50.20.0/24): Host Lambda ENIs (sg-lambda-orch), AWS PrivateLink Endpoints (sg-vpce-privatelink) (sagemaker.runtime,sagemaker.api,sagemaker.featurestore-runtime,bedrock-runtime,ecr,kms,logs,monitoring), and a free S3 Gateway Endpoint (pl-63a5400a).
- Isolated SageMaker Subnets (
10.50.100.0/24,10.50.200.0/24): Run Real-Time Endpoints (sg-sagemaker-rt) and Pipeline jobs (sg-sagemaker-jobs) withenable_network_isolation = trueand TLS 1.3 encryption.

Architecture Decision Record: Real-Time Endpoint vs. Serverless & Batch Inference
Architecture Decision Record (ADR-02: Auto-Scaled SageMaker Real-Time Endpoint vs. Serverless & Batch):
- Context: Counselors query profiles live during grading and parent meetings, needing
< 25 mslatency, Model Monitor Data Capture, and private VPC networking.
- Decision: Deploy XGBoost + TreeSHAP on a SageMaker Real-Time Endpoint (
ml.m5.large) in isolated VPC subnets with Auto Scaling (1..4instances) and 100% Data Capture.
- Rejected Alternatives:
- SageMaker Serverless Inference: Suffers
1.5s–4.0scold starts and lacks VPC isolation (VpcConfig) and native Data Capture.
- Nightly Batch Transform Only: Cannot recalculate risk live when a counselor logs a new incident or parent meeting.
- Trade-Off Accepted: Paying ~$62.10/month with scheduled school-hour scaling for zero cold starts (
6.88 mslatency), PrivateLink isolation, and 100% Data Capture.
4. Explainable AI (TreeSHAP) & Prescriptive Intervention Engine with Amazon Bedrock
4.1 Global vs. Local TreeSHAP Feature Attributions
The endpoint uses XGBoost's C++
pred_contribs=True engine, computing exact TreeSHAP log-odds values for all 3 classes in 0.501 ms per student:Rank | Feature Name | Category | Mean |TreeSHAP| | Practical Meaning |
|---|---|---|---|---|
1 | Age | Demographic | 0.3516 | Being older than expected for the grade points to prior repetition |
2 | grade_speed | Progression | 0.3489 | Slower progression across school years ( Grado / Years ) raises risk |
3 | Year_of_study | Cohort | 0.3022 | Captures grading shifts between pandemic and post-pandemic years |
4 | relative_parent_engagement | Engagement | 0.1541 | Lower parent portal activity compared to same-grade peers |
5 | age_zscore_in_grade | Peer Z-Score | 0.1446 | Students > +1.5 SD older than classmates face higher failure risk |
6 | age_acceleration | Progression | 0.1263 | Ratio between chronological age and current grade |
7 | Grado / Sex | Stage / Demo | 0.1235 / 0.1059 | Secondary transition variance; Sex audited via SageMaker Clarify |
8 | Term / risk_accumulation | Multi-Factor | 0.1004 / 0.0773 | Term grading pressure and combined health, payment, or transfer flags |
9 | Awards_ratio / age_parent | Conduct | 0.0516 / 0.0428 | Demerits ( -1 ) raise risk; active parent portal oversight protects |
4.2 Turning SHAP Values into Action Plans: Rule Matrix + Amazon Bedrock
- Step 1 - School Rule Matrix (
DetailedInterventionSystem,< 1 ms): Matches top positive TreeSHAP drivers (shap_log_odds > 0) to school interventions (parent_engagement,academic_progression,mobility_or_remedial), assigning SLAs (48hor2-Week), staff owners, and KPIs.
- Step 2 - Summary with Amazon Bedrock (
Claude 3.5 Haiku+ Guardrails,~420 mswhen requested): Sendsstudent_token, probabilities, top 4 SHAP values, and the matched protocol to Amazon Bedrock with a FERPA Guardrail scrubbing PII (NAME,EMAIL,PHONE).
Architecture Decision Record: Hybrid Prescriptive Engine vs. Pure LLM Risk Scoring
Architecture Decision Record (ADR-03: Hybrid TreeSHAP + Rule Matrix + Amazon Bedrock vs. Direct LLM Risk Prediction):
- Context: Counselors need calibrated risk probabilities and natural-language action plans tailored to each student's risk factors.
- Decision: Keep risk scoring and rule matching 100% deterministic in SageMaker (XGBoost + TreeSHAP +
DetailedInterventionSystem), and use Amazon Bedrock Claude 3.5 Haiku (temperature = 0.1+ Guardrails) only to draft the counselor summary when requested.
- Rejected Alternatives:
- Direct LLM Risk Scoring: Poorly calibrated on tabular numbers, cannot enforce PR-AUC cutoffs on a 35:1 imbalance, ~100× costlier, and can hallucinate.
- Static Templates Only: Cannot weave multi-factor interactions (
School_change+ highage_zscore_in_grade) into a cohesive brief.
- Trade-Off Accepted: Adding
~420 mslatency and~$0.0008token cost only wheninclude_bedrock_narrative = true, keeping default scoring at6.88 ms.
5. Automated MLOps Governance with SageMaker Pipelines & Model Registry

- Step 1 -
LeakFreeFeatureEngineeringAndFeatureStoreIngest(ProcessingStep): RunsSKLearnProcessoronml.m5.xlargein private subnets. Fixes the 412Ageoutliers usingX_trainmedians, computes the 10 engineered features, ingests all 27 features into SageMaker Feature Store (Online + Offline Iceberg), exports splits to S3, and writesstatistics.json/constraints.json.
- Step 2 -
TrainCostSensitiveXGBoost(TrainingStep): Trains SageMaker XGBoost1.7-1with Managed Spot Training (~70%savings) and weights{0: 5.5, 1: 1.8, 2: 1.0}.
- Step 3 -
EvaluateAndCalibrateThresholds(ProcessingStep): Evaluates on the19,800test rows, tunes(τ_high, τ_mod), checks TreeSHAP speed, and writesevaluation.json.
- Step 4 -
CheckHighRiskRecallAndPrAuc(ConditionStep): Inspectsevaluation.jsonviaJsonGet; only proceeds ifRecall_Class_1 ≥ 0.44andPR_AUC_Class_1 ≥ 0.28.
- Step 5 -
RegisterStudentRiskModel& Canary Rollout: Registers the package instudent-academic-risk-models(PendingManualApproval). Upon approval, EventBridge launches a 20% Canary deployment with CloudWatch5XXauto-rollback.
Aligning AWS MLOps Governance with ISO/IEC 23053 (AI Systems Using Machine Learning)
Mapping every Amazon SageMaker step to ISO/IEC 23053 (Framework for AI Systems Using Machine Learning) gives cloud engineers and institutional auditors a shared checklist:
ISO/IEC 23053 Stage | AWS / SageMaker Implementation | Practical Engineering & Audit Guarantee |
|---|---|---|
1. Data Prep & Feature Store | SageMaker Processing + Feature Store ( Online + Iceberg ) | Zero target leakage ( X_train fit), zero train-serve skew ( GetRecord ), age fix, and HMAC-SHA256 hashing. |
2. Modeling & Training | SageMaker Training Job ( XGBoost {5.5, 1.8, 1.0} ) | KMS-encrypted model.tar.gz artifacts with tracked hyperparameters and weights. |
3. Verification & Validation | EvaluationStep + ConditionStep ( PR-AUC ≥ 0.25 , Recall ≥ 0.40 ) | Automated quality gate ( evaluation.json ) blocking weak models from registration. |
4. Model Repository & Lineage | SageMaker Model Registry ( student-academic-risk-models ) | Approval state machine ( PendingManualApproval → Approved ) with dataset and image lineage. |
5. Deployment & Explainability | Real-Time Endpoint + Native TreeSHAP + Amazon Bedrock | Sub-7ms predictions with exact per-student SHAP ( 0.50 ms ) and guardrailed action plans. |
6. Continuous Monitoring | SageMaker Model Monitor ( 100% Capture) + SageMaker Clarify | Ongoing data drift checks ( constraints.json ) and fairness audits across Sex and Grado . |
Architecture Decision Record: SageMaker Pipelines + Model Registry vs. Notebook Deployments
Architecture Decision Record (ADR-04: Governed SageMaker Pipelines & Model Registry vs. Ad-Hoc Notebook Deployments):
- Context: Risk models are retrained each term (
Term 1..4). Manual notebook retraining previously caused untracked changes and target leakage (Final_grade.diff()).
- Decision: Automate retraining via SageMaker Pipelines and Model Registry, with an IAM rule blocking
sagemaker:UpdateEndpointunless the package isApproved.
- Rejected Alternatives:
- Direct
estimator.deploy()from Notebooks: No lineage, prone to leakage/skew, and no metric gate.
- Self-Managed Kubeflow / Airflow on EKS: Adds $140+/month in cluster overhead unnecessary for term-based tabular retraining.
- Trade-Off Accepted: Writing ~200 lines of Python SDK pipeline code upfront while paying $0.00/month in orchestration fees.
6. Implementation Code: Feature Pipeline, Inference Handler & Terraform IaC
A. Leak-Free Feature Engineering Transformer ( src/benchmark_models.py )
Python
from sklearn.base import BaseEstimator, TransformerMixinfrom sklearn.preprocessing import StandardScalerimport pandas as pdclass LeakFreeStudentFeatureEngineer(BaseEstimator, TransformerMixin):def __init__(self, min_age: float = 3.0, max_age: float = 20.0):self.min_age, self.max_age = min_age, max_ageself.scaler_ = StandardScaler()self.cols_ = ["age_acceleration", "age_parent_interaction", "grade_speed", "age_zscore_in_grade","relative_parent_engagement", "academic_support_index", "risk_accumulation","term_completion", "financial_engagement_index", "mobility_stress_index",]def fit(self, X: pd.DataFrame, y=None):v = X[(X["Age"] >= self.min_age) & (X["Age"] <= self.max_age)]self.global_med_ = float(v["Age"].median())self.grade_meds_ = v.groupby("Grado")["Age"].median().to_dict()st = v.groupby("Grado")["Age"].agg(["mean", "std"]).to_dict(orient="index")self.grade_stats_ = {g: (float(s["mean"]), max(float(s["std"] or 1.0), 1e-6)) for g, s in st.items()}self.parent_means_ = X.groupby("Grado")["Parent_interaction"].mean().to_dict()self.scaler_.fit(self._compute(X)[self.cols_])return selfdef _compute(self, X: pd.DataFrame) -> pd.DataFrame:df = X.copy()inv = (df["Age"] < self.min_age) | (df["Age"] > self.max_age)if inv.any():df.loc[inv, "Age"] = df["Grado"].map(self.grade_meds_).fillna(self.global_med_)[inv]df["age_acceleration"] = df["Age"] / df["Grado"].clip(lower=1)df["age_parent_interaction"] = df["Age"] * df["Parent_interaction"]df["grade_speed"] = df["Grado"] / (df["Year_of_study"] - 2015).clip(lower=1)gm = df["Grado"].map(lambda g: self.grade_stats_.get(g, (self.global_med_, 1.0))[0])gs = df["Grado"].map(lambda g: self.grade_stats_.get(g, (self.global_med_, 1.0))[1])df["age_zscore_in_grade"] = (df["Age"] - gm) / gsdf["relative_parent_engagement"] = df["Parent_interaction"] - df["Grado"].map(self.parent_means_).fillna(0.108)df["academic_support_index"] = df["Parent_interaction"] * df["Parents_cnt"] * (1 - df["School_change"])df["risk_accumulation"] = ((df["Sickness_cnt"] > 0).astype(int) + (df["Parent_interaction"] == 0).astype(int)+ (df["School_change"] > 0).astype(int) + (df["Payment_ratio"] == 0).astype(int)+ (df["Awards_ratio"] < 0).astype(int) + (df["Summer_school"] > 0).astype(int))df["term_completion"] = df["Term"] / 4.0df["financial_engagement_index"] = df["Payment_ratio"] * (df["Parent_interaction"] + 0.1)df["mobility_stress_index"] = df["Classroom_transfer"] + 2 * df["School_change"] + df["Summer_school"]return dfdef transform(self, X: pd.DataFrame) -> pd.DataFrame:df = self._compute(X)df[self.cols_] = self.scaler_.transform(df[self.cols_])return df
B. Real-Time Inference Handler ( src/inference.py )
Python
import hashlib, hmac, json, os, timeimport boto3, joblib, numpy as np, pandas as pd, xgboost as xgbREGION = os.environ.get("AWS_REGION", "us-east-1")FG_NAME = os.environ.get("FEATURE_GROUP_NAME", "student-academic-risk-fg-prod")SECRET = os.environ.get("STUDENT_ID_HMAC_SECRET", "ferpa-kms-injected-salt")def fetch_online_features(token: str) -> dict:fs = boto3.client("sagemaker-featurestore-runtime", region_name=REGION)resp = fs.get_record(FeatureGroupName=FG_NAME, RecordIdentifierValueAsString=token)return {i["FeatureName"]: float(i["ValueAsString"]) for i in resp.get("Record", [])if i["FeatureName"] not in ("Student_Token", "Event_Time")}def model_fn(model_dir: str):fe = joblib.load(os.path.join(model_dir, "feature_engineer.joblib"))model = xgb.XGBClassifier()model.load_model(os.path.join(model_dir, "xgboost_student_risk.json"))with open(os.path.join(model_dir, "thresholds.json")) as f:th = json.load(f)return {"fe": fe, "model": model, "booster": model.get_booster(), "th": th}def predict_fn(payload: dict, art: dict) -> dict:t0 = time.perf_counter()raw_id = str(payload.get("student_id", "anonymous"))token = hmac.new(SECRET.encode(), raw_id.encode(), hashlib.sha256).hexdigest()[:16]df_X = art["fe"].transform(pd.DataFrame([payload["student_features"]]))cols, X_mat = list(df_X.columns), df_X.valuesp_high, p_mod, p_low = [float(x) for x in art["model"].predict_proba(X_mat)[0]]risk = "High Risk" if p_high >= art["th"].get("tau_high_risk", 0.33) else ("Moderate Risk" if p_mod >= art["th"].get("tau_mod_risk", 0.41) else "Low Risk")shap_vals = art["booster"].predict(xgb.DMatrix(X_mat, feature_names=cols), pred_contribs=True)[0, 0, :-1]top_idx = np.argsort(np.abs(shap_vals))[::-1][:4]top_shap = [{"feature": cols[i], "value": round(float(X_mat[0, i]), 3),"shap_log_odds": round(float(shap_vals[i]), 4)} for i in top_idx]plan = DetailedInterventionSystem.map_shap_drivers_to_actions(top_shap, risk)brief = synthesize_bedrock_narrative(token, risk, [p_high, p_mod, p_low], top_shap, plan) if (payload.get("include_bedrock_narrative") and risk != "Low Risk") else Nonereturn {"student_token": token, "risk_level": risk,"probabilities": {"High": round(p_high, 4), "Mod": round(p_mod, 4), "Low": round(p_low, 4)},"top_shap_attributions": top_shap, "intervention_plan": plan,"bedrock_counselor_brief": brief, "latency_ms": round((time.perf_counter() - t0) * 1000, 2),}
Verified Output ( 6.88 ms End-to-End Execution)
JSON
{"student_token": "50cf366653e07d5c", "risk_level": "Low Risk","probabilities": {"High": 0.1992, "Mod": 0.2028, "Low": 0.5980},"top_shap_attributions": [{"feature": "School_change", "value": 1.0, "shap_log_odds": 1.0480},{"feature": "Summer_school", "value": 1.0, "shap_log_odds": -1.0274},{"feature": "age_zscore_in_grade", "value": 5.471, "shap_log_odds": 0.3696},{"feature": "Age", "value": 14.8, "shap_log_odds": 0.3655}],"intervention_plan": {"priority": "Standard Monitoring", "recommended_actions": [{"what": "Transition & Classroom Integration", "when": "Weekly (4 wks)", "who": "School Psychologist"}]},"bedrock_counselor_brief": null, "latency_ms": 6.88}
C. Production Infrastructure Blueprint ( iac/main.tf )
HCL
resource "aws_kms_key" "student_risk_cmk" {description = "CMK for Student Risk S3, Feature Store, EBS, and Data Capture"deletion_window_in_days = 30enable_key_rotation = true}resource "aws_vpc_endpoint" "mlops_privatelink" {for_each = toset(["com.amazonaws.us-east-1.sagemaker.runtime", "com.amazonaws.us-east-1.sagemaker.api","com.amazonaws.us-east-1.sagemaker.featurestore-runtime", "com.amazonaws.us-east-1.bedrock-runtime","com.amazonaws.us-east-1.ecr.api", "com.amazonaws.us-east-1.ecr.dkr", "com.amazonaws.us-east-1.logs"])vpc_id = var.vpc_idservice_name = each.valuevpc_endpoint_type = "Interface"subnet_ids = var.private_subnet_idssecurity_group_ids = [aws_security_group.sagemaker_endpoint_sg.id]private_dns_enabled = true}resource "aws_sagemaker_feature_group" "student_risk_fg" {feature_group_name = "student-academic-risk-fg-${var.environment}"record_identifier_feature_name = "Student_Token"event_time_feature_name = "Event_Time"role_arn = aws_iam_role.sagemaker_execution_role.arnonline_store_config {enable_online_store = truesecurity_config { kms_key_id = aws_kms_key.student_risk_cmk.arn }}offline_store_config {table_format = "Iceberg"s3_storage_config {s3_uri = "s3://sagemaker-student-risk-mlops-${var.environment}/feature-store"kms_key_id = aws_kms_key.student_risk_cmk.arn}}}resource "aws_sagemaker_model" "student_risk_xgb" {name = "student-risk-xgb-${var.environment}"execution_role_arn = aws_iam_role.sagemaker_execution_role.arnenable_network_isolation = trueprimary_container {model_package_name = var.approved_model_package_arnenvironment = {BEDROCK_MODEL_ID = "anthropic.claude-3-5-haiku-20241022-v1:0"BEDROCK_GUARDRAIL_ID = aws_bedrock_guardrail.student_intervention_guardrail.guardrail_id}}vpc_config {subnets = var.private_subnet_idssecurity_group_ids = [aws_security_group.sagemaker_endpoint_sg.id]}}resource "aws_sagemaker_endpoint_configuration" "student_risk_config" {name = "student-risk-ep-config-${var.environment}"kms_key_id = aws_kms_key.student_risk_cmk.arnproduction_variants {variant_name = "PrimaryXGBoostTreeSHAP"model_name = aws_sagemaker_model.student_risk_xgb.nameinitial_instance_count = 1instance_type = "ml.m5.large"}data_capture_config {enable_capture = trueinitial_sampling_percentage = 100destination_s3_uri = "s3://sagemaker-student-risk-mlops-${var.environment}/data-capture"kms_key_id = aws_kms_key.student_risk_cmk.arncapture_options { capture_mode = "Input" }capture_options { capture_mode = "Output" }}}resource "aws_sagemaker_endpoint" "student_risk_endpoint" {name = "student-academic-risk-rt-${var.environment}"endpoint_config_name = aws_sagemaker_endpoint_configuration.student_risk_config.namedeployment_config {blue_green_update_policy {traffic_routing_configuration {type = "CANARY"wait_interval_in_seconds = 300canary_size {type = "CAPACITY_PERCENT"value = 20}}termination_wait_in_seconds = 300}auto_rollback_configuration {alarms { alarm_name = aws_cloudwatch_metric_alarm.endpoint_5xx_errors.alarm_name }}}}
7. Production Observability, Drift Detection & Student Data Privacy (FERPA)
Running a student risk model across school years means watching for feature drift, grading shifts, and broken ERP feeds:
- Catching Broken ERP Syncs with CloudWatch EMF: If an ERP update breaks parent portal sync,
Parent_interactiondrops to0.0(#4 TreeSHAP driver), causing a spike in High-Risk flags. Lambda emitsHighRiskPredictionRate; if the 1-hour rate exceeds15.0%(vs.2.22%–6.5%baseline), CloudWatch alerts the team before counselors see bad alerts.
- Model Monitor & Clarify Drift: Daily Data Quality jobs check
constraints.jsonbounds (3.0 ≤ Age ≤ 20.0,0.0 ≤ Payment_ratio ≤ 1.0). Weekly Clarify jobs check NDCG on the TreeSHAP ranking and trigger EventBridge retraining if key drivers shift.
- Protecting Minor PII (FERPA): Student names, IDs, and addresses never enter S3 or SageMaker.
Student_Idis hashed viaHMAC-SHA256with a KMS salt, and Bedrock Guardrails scrub PII before generating notes.
8. Cost & TCO Optimization
Combining Managed Spot Training, Scheduled Endpoint Auto-Scaling (
07:00–19:00 Mon–Fri ), and on-demand Bedrock Haiku calls keeps the full production setup at $112.60/month :AWS Service / Component | Sizing & Utilization | Optimization Lever | Monthly Cost |
|---|---|---|---|
SageMaker Real-Time Endpoint | 1 × ml.m5.large , scaled down off-hours | Scheduled + Target Auto-Scaling | $62.10 |
SageMaker Pipelines & Training | ml.m5.xlarge Processing + XGBoost | Spot Training (70% off) + $0 DAG | $1.85 |
SageMaker Feature Store | Online ( <3 ms ) + Offline S3 Iceberg | Eliminates train-serve skew | $4.18 |
SageMaker Monitor & Clarify | Weekly runs ( 4 × 15 min/mo ) | Matches grading cadence | $0.46 |
Amazon Bedrock ( Haiku 3.5 ) | ~6,000 narratives/mo + Guardrail | Only when risk != Low & requested | $4.92 |
AWS PrivateLink & S3 Gateway | VPC Interface Endpoints + Free S3 Gateway | Avoids NAT Gateway data fees | $28.80 |
S3, KMS CMK & CloudWatch | 15 GB lake + Data Capture, CMK, Alarms | S3 Intelligent-Tiering | $10.29 |
Total Production TCO | End-to-End MLOps + Feature Store + Bedrock | ~63% savings vs. 24/7 setup | $112.60 / mo |
9. Architecture Trade-Offs Summary (ADR Table)
ADR Ref | Decision | Alternatives | Trade-Off Accepted | Primary Benefit |
|---|---|---|---|---|
ADR-01 | Cost-Sensitive XGBoost + Threshold ( τ = 0.33 ) | RF + SMOTE (k=5) , Deep MLP | 28.55% Precision + threshold step | 3.3× Recall gain ( 43.96% ), PR-AUC = 0.2875 , 0.21 ms p99, 0.50 ms TreeSHAP |
ADR-02 | Auto-Scaled Real-Time Endpoint ( ml.m5.large ) | Serverless, Batch Transform | ~$62.10/mo baseline compute | Zero cold starts ( 6.88 ms ), PrivateLink isolation, 100% Data Capture |
ADR-03 | Hybrid Engine (TreeSHAP + Rules + Bedrock) | Direct LLM Scoring, Static Text | +420 ms & ~$0.0008 on demand | 100% deterministic scoring + guardrailed counselor action plans |
ADR-04 | SageMaker Pipelines + Registry ( ConditionStep ) | Notebook deploy() , EKS Airflow | ~200 LOC SDK pipeline code | Blocks leaked/weak models, full lineage, Canary rollback, $0 idle fee |
10. Conclusion & Production Verification Checklist
Taking a student risk model from a notebook into Amazon SageMaker shows that clean data pipelines and solid MLOps matter just as much as algorithm choice. Fixing target leakage (
Final_grade.diff() ), cleaning birth-date typos on X_train , storing features in SageMaker Feature Store, using cost-sensitive XGBoost instead of blind SMOTE , and combining TreeSHAP with Amazon Bedrock gives schools a fast, transparent tool to help struggling students early.Production Readiness Checklist
- [x] Zero Data Leakage: Medians, Z-scores, and
StandardScalerfit strictly onX_trainand stored in SageMaker Feature Store.
- [x] Imbalance Metrics First: Pipeline
ConditionStepenforces Class-1 Recall (≥ 0.44) and PR-AUC (≥ 0.28) over Accuracy.
- [x] Sub-10 ms Explainability: Native C++
pred_contribs=Truecomputes local TreeSHAP values in0.50 msper student.
- [x] Private VPC Networking: Containers run with
enable_network_isolation = true, TLS 1.3 encryption, and AWS PrivateLink.
- [x] Student Privacy & Guardrails:
HMAC-SHA256ID hashing, KMS CMK encryption, CloudWatch Data Protection, and Bedrock Guardrails.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article