Skip to content

DS 201 · Module 2

Evaluate, Interpret, and Decide on Deployment

Extend Module 1's prediction loop into classification and thresholds, overfitting and cross-validation, feature importance and fairness, and finally error analysis, drift, and deployment decisions.

Start Section 1
0 / 5 completed
Sync my progressJoin a session to keep progress across devices and share it with your instructor

Info

After you join, your completed lesson numbers are sent to your instructor together with your learner code, so they can see your progress. Use the codes your instructor gave you, and do not enter your name, company secrets or other personal data. Progress is kept with the rest of that session's data.

Learning objectives

  • Understand probability scores, thresholds, confusion matrix, precision, recall, specificity
  • Use CV on training data; keep test untouched; limit tuning complexity
  • Treat importance as predictive contribution, not causality; inspect subgroup error
  • Inspect where errors occur, costs, drift risk, monitoring and human fallback
  • Deliver baseline, model, evaluation, error analysis, limitations, and a go/no-go decision rubric

Classification and Thresholds

40 min

Classification and Thresholds

Learning goal: understand probability scores, thresholds, confusion matrix, precision, recall, specificity.

A classification model does not output "yes" or "no": it outputs a probability score between 0 and 1. Turning that into an actionable decision requires choosing a threshold: a score above the cutoff is treated as "will exceed capacity." Changing the threshold does not change the model itself, but it dramatically changes the trade-off between precision and recall.

The four cells of a confusion matrix
Predicted \ ActualActually exceeds thresholdActually does not exceed threshold
Predicted exceeds thresholdTrue Positive (caught it)False Positive (false alarm)
Predicted does not exceedFalse Negative (missed it)True Negative (correctly ruled out)
Compute precision and recall at different thresholds
from sklearn.metrics import precision_score, recall_score

proba = model_clf.predict_proba(valid[feature_cols])[:, 1]
for threshold in [0.3, 0.5, 0.7]:
    pred = (proba >= threshold).astype(int)
    precision = precision_score(valid["target_binary"], pred)
    recall = recall_score(valid["target_binary"], pred)
    print(threshold, round(precision, 3), round(recall, 3))

Before choosing a threshold, write down the real cost of each type of error: missing a site that really will exceed capacity (a False Negative) may mean degraded service or emergency reallocation cost; flagging a site that would have been fine (a False Positive) wastes the resources spent pre-allocating. Once both costs are quantified, choosing a threshold becomes a decision that can be reviewed, not a feeling.

Precision

  • Asks: of the cases the model flagged as exceeding the threshold, how many really did
  • Raising the threshold usually increases precision
  • Prioritize this when false alarms are costly

Recall

  • Asks: of all cases that really exceeded the threshold, how many were caught
  • Lowering the threshold usually increases recall
  • Prioritize this when missing a true case is costly
Case: choosing a threshold when costs are unequal (simulated)

Suppose missing one true case costs roughly three times as much as one false alarm, in overtime reallocation cost. In that situation, a team would typically choose a lower threshold, trading some precision for higher recall, because the cost of missing a true case is clearly larger. That choice, and the cost assumption behind it, should be written into the deployment document.

  • Choosing a threshold because a number 'feels right,' without comparing it to the actual business cost
  • Applying the same threshold to every site without checking whether each site's cost structure is actually the same
  • Reporting only accuracy without also reporting precision and recall at the chosen threshold
  • Not re-checking fairness across group_attribute subgroups after the threshold is chosen

Warning

There is no "correct" threshold in the abstract: it must be set from business cost: missing a site that really will exceed capacity (a False Negative) and flagging a site that would have been fine (a False Positive) rarely cost the same amount.
Check yourself

Lowering the classification threshold from 0.5 to 0.3 most likely causes what change?

Lowering the classification threshold from 0.5 to 0.3 most likely causes what change?

Key takeaway: Completing the steps is not enough; the result must be verifiable, reproducible, and explainable.

Overfitting, CV, and Tuning

40 min

Overfitting, Cross-Validation, and Tuning

Learning goal: use CV on training data; keep test untouched; limit tuning complexity.

A colleague keeps raising model complexity: training-set performance keeps improving, but validation performance starts getting worse. This is a classic overfitting signal: the model has memorized noise in the training data instead of learning patterns that generalize to new data. Cross-validation (CV) lets you evaluate different settings more robustly while using only the training data.

Tune hyperparameters with CV on training data; test stays untouched
from sklearn.model_selection import TimeSeriesSplit, cross_val_score

tscv = TimeSeriesSplit(n_splits=5)
for depth in [2, 4, 8]:
    scores = cross_val_score(make_model(max_depth=depth), train[feature_cols], train["target_numeric"], cv=tscv, scoring="neg_mean_absolute_error")
    print(depth, round(-scores.mean(), 2))
# The test set is never touched anywhere in this tuning process

Beyond adjusting model complexity, common responses to overfitting include adding regularization, reducing the number of features, or adding more training data. The value of cross-validation is that it estimates a more robust performance range from several splits, rather than depending on whatever luck a single split happened to produce.

Signals of underfitting, a good fit, and overfitting
SituationTraining performanceValidation performance
UnderfittingPoorPoor (close to training)
Good fitGoodGood (close to training)
OverfittingVery goodClearly worse (a widening gap)
Case: variance across CV folds is also information (simulated)

A 5-fold cross-validation run produces MAE values of 8.1, 8.4, 8.0, 15.2, and 8.3. Looking only at the average might suggest performance is slightly high overall, but one fold is clearly an outlier compared to the other four, suggesting that period of data may contain an anomaly (such as a surge from a special event) worth investigating, rather than simply reporting a single average.

  • Looking only at the average CV score without checking whether variance across folds is too large
  • Using a non-time-aware KFold split on time-ordered data, leaving leakage inside each fold
  • Running unlimited tuning attempts, continuing until the validation score 'happens' to improve
  • Accidentally using the test set somewhere during tuning (for example, a typo that referenced the test variable)

Warning

The number of tuning attempts is itself a risk: the more parameter combinations you try, the more likely one will "happen" to score well on validation purely by chance. Limiting the search space and keeping the test set completely untouched are what make the final evaluation honest.
Check yourself

A model's training MAE is 2.1 but its validation MAE is 15.8: a large gap. What does this most likely indicate?

A model's training MAE is 2.1 but its validation MAE is 15.8: a large gap. What does this most likely indicate?

Key takeaway: Completing the steps is not enough; the result must be verifiable, reproducible, and explainable.

Feature Importance and Fairness

35 min

Feature Importance, Interpretation, and Fairness

Learning goal: treat importance as predictive contribution, not causality; inspect subgroup error.

The model's feature importance shows features_staffing_level as the top predictor, and a colleague immediately concludes: "So increasing staffing will reduce case volume." Feature importance only describes how much a variable contributes to the model's predictions: it does not prove that changing that variable would change the real-world outcome. This is the same trap as correlation versus causation.

Check overall importance, and error by group_attribute
importances = pd.Series(model.feature_importances_, index=feature_cols).sort_values(ascending=False)
print(importances.head())

# Check whether error is consistent across group_attribute subgroups
valid_pred = model.predict(valid[feature_cols])
valid.assign(abs_error=(valid["target_numeric"] - valid_pred).abs()).groupby("group_attribute")["abs_error"].mean()

The way feature importance is computed also affects the conclusion: rankings from a tree model's built-in importance, permutation importance, and SHAP values sometimes disagree. When reporting importance, state which method was used, and treat it as 'how much the model currently relies on this variable,' not 'how important this variable is in the real world.'

What feature importance can and cannot answer
Can answerCannot answer
How much a feature contributes to the model's predictionsWhether changing that feature would causally change the real outcome
Which features the model currently relies on mostWhether the model is equally fair across every subgroup
Whether performance would drop if the feature were removedThe business reason behind that feature
Case: high importance does not mean it is safe to act on (simulated)

features_staffing_level shows high importance, but further checking reveals staffing itself was scheduled after the fact based on 'past case volume.' In other words, it correlates strongly with the target partly because staffing itself reflects historical case volume, not because staffing 'caused' case volume to drop. Verifying causality needs an additional experimental design; feature importance alone cannot answer that question.

  • Treating a high-importance feature as causal evidence and publicly claiming 'changing it will change the outcome'
  • Looking only at the overall importance ranking without checking whether it is consistent across subgroups
  • Using only one importance method without cross-checking whether the result is stable
  • Drawing conclusions from subgroup error checks on too small a sample without noting the uncertainty

Warning

Looking only at an overall error metric can hide the model performing systematically worse for one subgroup. Checking error by group_attribute or similar subgroup fields is a required step in responsible model evaluation, not an optional extra.
Check yourself

A model's overall MAE looks good, but broken down by group_attribute, one subgroup's MAE is three times the others. What is the most appropriate next step?

A model's overall MAE looks good, but broken down by group_attribute, one subgroup's MAE is three times the others. What is the most appropriate next step?

Key takeaway: Completing the steps is not enough; the result must be verifiable, reproducible, and explainable.

Error Analysis, Drift, and Deployment Decisions

40 min

Error Analysis, Drift, and Deployment Decisions

Learning goal: inspect where errors occur, costs, drift risk, monitoring and human fallback.

Three months after launch, a model's performance has quietly degraded, but nobody noticed because the team checked the offline score once and deployed it, with no monitoring afterward. This is the most common consequence of "good test performance means auto-deploy": real-world data distributions shift over time (drift), and a model that performed well once is not guaranteed to keep performing well.

A monitoring plan needs to answer at least three questions: which metric detects degraded performance (for example, a tracked MAE or false-alarm rate), how often it is checked (daily, weekly), and who is responsible for intervening when the metric looks abnormal. 'Monitoring' that does not answer these three questions often exists only on paper, with nobody actually watching it.

Four things to check before deployment, beyond the test score
CheckQuestion
Error distribution and costIs error spread evenly, or concentrated in specific situations (a particular group_attribute or demand range)? What do a miss and a false alarm each cost?
Drift riskCould future data differ from training data (seasonality, policy changes)?
MonitoringWhat metric, and how often, will catch performance degradation after launch?
Human fallbackIs there a clear human-review or fallback path when the model is uncertain or monitoring flags an anomaly?
Check whether error concentrates in a high-demand range
valid_pred = model.predict(valid[feature_cols])
errors = (valid["target_numeric"] - valid_pred).abs()
high_demand = valid["target_numeric"] > valid["target_numeric"].quantile(0.9)
print("Average error, high-demand cases:", round(errors[high_demand].mean(), 2))
print("Average error, other cases:", round(errors[~high_demand].mean(), 2))
# If high-demand cases have much larger error, the model is least reliable exactly when accuracy matters most
Case: the quiet signs of drift (simulated)

A similar service point opens near one site, and the original case-volume pattern starts to shift, but the model still runs on parameters trained from old data. Three weeks later, the monitoring metric shows a sustained rise in error, not a one-off blip: exactly the signal that the model needs retraining, or at least a review of whether it still applies. Without a monitoring mechanism, this shift might only be discovered once users start complaining.

  • Checking overall error only once before deployment without checking whether it concentrates in specific situations
  • Not writing down the business cost of a miss versus a false alarm, leaving the threshold or decision basis opaque
  • Monitoring metrics with no clear anomaly threshold, so something 'looking off' never triggers any action
  • No human fallback mechanism, so an anomaly can only wait for the next scheduled retraining

Warning

Good test performance does not mean auto-deployment is safe. A deployment decision also needs a cost assessment, drift risk, a monitoring plan, and a human-review path; without them, even a model with a great offline score can quietly fail after launch with nobody noticing.
Check yourself

A model's test performance meets the target and the team plans to auto-deploy it with no additional monitoring. What is the biggest risk in this decision?

A model's test performance meets the target and the team plans to auto-deploy it with no additional monitoring. What is the biggest risk in this decision?

Key takeaway: Completing the steps is not enough; the result must be verifiable, reproducible, and explainable.

Independent Lab

55 min

Independent Lab: Predictive Analytics Use Case

Learning goal: independently deliver baseline, model, evaluation, error analysis, limitations, and a go/no-go decision rubric.

Info

Practice task: using the practice data, independently choose a service-demand prediction problem and walk the full course loop: Frame → Baseline → Split → Train → Evaluate → Error Analysis → Deployment Decision, then deliver a bounded Predictive Analytics Use Case + Model Card. There is no published answer: your reasoning and verification are what get reviewed.
  1. Define the prediction problem
    Write down the prediction unit, target (regression or classification), decision, and features available at prediction time.
  2. Build a baseline
    Build at least one naive/majority/mean baseline for your chosen target.
  3. Split correctly and train
    Split train/validation/test by time, train a model, and tune on validation.
  4. Evaluate and compare
    Compare the model against the baseline using MAE/RMSE or precision/recall, and examine the threshold or complexity trade-off.
  5. Error analysis
    Check whether error concentrates by group_attribute or demand range, and identify at least one pattern worth investigating further.
  6. Make a deployment decision
    Based on performance, cost, drift risk, and monitoring feasibility, write a reasoned go/no-go decision without claiming universal validity.
  • A clearly stated prediction problem and decision
  • At least one baseline and its performance
  • The correct time-based split and a record of the leakage check
  • Model performance compared to baseline, including at least two metrics
  • At least one subgroup- or situation-level error analysis
  • At least one limitation and a deployment decision (covering cost, drift, monitoring, and human fallback)
  • A record of any AI assistance used, and what you personally verified
  • A deployment decision must state the assumed costs and monitoring approach, not just a bare 'go' or 'no-go' conclusion
  • When a subgroup error analysis is based on a very small sample, say so instead of drawing a firm conclusion
  • The limitations field in the Model Card must be specific, such as 'error is less stable in subgroups with fewer than N rows,' rather than a vague 'there may be limitations'

Warning

Repeatedly checking the test-set score to decide the next tweak effectively turns the test set into another validation set, and the final reported score loses its meaning. All adjustments should happen on train/validation; test is checked exactly once at the end.

Done

If AI helps write model code or draft the Model Card text, check every item yourself: was the split correctly time-based, was the baseline actually computed, does the metric choice fit this decision, and does the deployment decision honestly reflect limitations rather than overpromising. AI can speed up drafting; verification and the final judgment remain a human responsibility.

Key takeaway: Completing the steps is not enough; the result must be verifiable, reproducible, and explainable.

What next?