Skip to content
ML Academy

Week 3 · Sunday — consolidate and defend

Forecasting studio 3: review flawed model code and defend the validation design

Project thread forecasting · linked lessons day 11, day 12, day 13, day 14, day 15

Milestone W3-b: a leakage-aware review of a flawed forecasting script, a repaired version on the protected split, and a written defense of the validation design. Together with Saturday, this is the Week 3 main evidence in Appendix C: a runnable baseline, validation predictions and a leakage-aware review.

  • 90 minsession length
  • 4timed blocks
  • 5tasks
  • —status

Session plan90 min

  1. 20′Spaced recall
  2. 40′Improve - review deliberately flawed code
  3. 20′Decision defense - validation design
  4. 10′Weekly review and planning

Before you start

Prepare before the session (2 minutes). Save the following as forecasting-project/review/flawed_w03.py. It is scaffolding with deliberate flaws, so do not reuse it.

# flawed_w03.py - a colleague's "D-14 forecast" (contains deliberate flaws; do not reuse)
import sqlite3
import numpy as np
import pandas as pd
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

con = sqlite3.connect("python/artifacts/airline_sample.sqlite")
df = pd.read_sql("""
    SELECT f.date, f.flight_no, f.route, f.weekday, f.holiday, f.capacity, f.fare_level,
           f.bookings_final, b.cumulative_bookings AS bk_on_hand
    FROM flight_day f
    JOIN booking_curve b ON b.date = f.date AND b.flight_no = f.flight_no
    WHERE b.days_to_departure = 7
""", con)

df["route_mean"] = df.groupby("route")["bookings_final"].transform("mean")
df["fare_level"] = df["fare_level"].map({"L": 0, "M": 1, "H": 2})
X = df[["weekday", "holiday", "capacity", "fare_level", "bk_on_hand", "route_mean"]]
y = df["bookings_final"]

X = StandardScaler().fit_transform(X)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2, shuffle=True, random_state=0)

best = None
for depth in [2, 3, 4, 5]:
    m = GradientBoostingRegressor(max_depth=depth, random_state=0).fit(X_tr, y_tr)
    mae = mean_absolute_error(y_te, m.predict(X_te))
    if best is None or mae < best[0]:
        best = (mae, depth)

baseline_mae = mean_absolute_error(y_te, np.full(len(y_te), y_te.mean()))
print(f"model MAE {best[0]:.1f} (depth {best[1]}) vs baseline MAE {baseline_mae:.1f}")

Run it from the repository root with uv run --project python python forecasting-project/review/flawed_w03.py. It takes a few seconds. You also need src/w03_fit.py, outputs/val_predictions_w03.csv and the boundary note from Saturday. The colleague is simulated.

Blocks4

  1. Block 1: Spaced recall

    20 min

    Answer the prompts in task recall-week3 closed-book (12 minutes). Then check them against lessons 6-15 and your own notes (8 minutes). Log misses with corrections. Include any concept the Week 2 routing decision marked as weak.

  2. Block 2: Improve - review deliberately flawed code

    40 min

    A simulated colleague's script, review/flawed_w03.py (see setup), claims a strong D-14 forecast. Work through it in four steps:

    1. Minutes 0-5 - commit. Run it from the repository root, note what it prints, and write one sentence on whether you believe it. Do this before reading the code closely.
    2. Minutes 5-20 - find the flaws. Read it line by line and list every flaw (task review-flaws).
    3. Minutes 20-35 - repair. Write the smallest repaired version that uses your Week 2-3 boundary, and run it (task repair-and-compare).
    4. Minutes 35-40 - compare. Put the repaired result next to your own Saturday results, and explain any difference.
  3. Block 3: Decision defense - validation design

    20 min

    Answer the simulated reviewer's five questions in task defend-validation, in at most 80 words each. Each answer names the specific leak or bias it prevents and points to your own code or numbers.

  4. Block 4: Weekly review and planning

    10 min

    Update decision-log.md with:

    • lessons 11-15 status;
    • recall misses;
    • studio status for both Week 3 ids;
    • whether the routing decision is working;
    • next week's priority, which is normally the error slice behind Saturday's hypothesis.

Tasks5

Sign in to save your work.
  1. Task 1

    recall

    Answer closed-book:

    1. Why is a regression coefficient not a causal effect?
    2. What does log loss penalize that accuracy ignores?
    3. Give one reason boosting can overfit, and the control that limits it.
    4. Why can trees not extrapolate a trend?
    5. How do you choose a threshold from a cost matrix?
    6. Name the roles of the training, validation and test sets in one line each.
    7. When is group k-fold needed? What is the "group" in your project?
    8. Give one Week 1 item and one Week 2 item from your recall log's miss list.

    The expected evidence for this task is shown after you save your own output.

  2. Task 2

    review

    List every flaw in flawed_w03.py with its line, the leak or bias it creates, and its severity: does it inflate the reported score, make it meaningless, or only weaken it? Rank the flaws. Your committed first sentence stays in the note unchanged.

    The expected evidence for this task is shown after you save your own output.

  3. Task 3

    code

    Write review/repaired_w03.py: the smallest version that removes every flaw you listed in review-flaws. It must respect your own dataset contract, your Week 2 evaluation boundary and the protected test period. Any configuration is selected on validation and reported as such, and the result is compared with the pickup baseline.

    Run it. Put its validation MAE next to your Saturday numbers and the flawed script's printout.

    The expected evidence for this task is shown after you save your own output.

  4. Task 4

    defense

    A simulated reviewer asks:

    1. "Why not 5-fold cross-validation? It uses more data."
    2. "Why throw away 14 days of training data before validation?"
    3. "Can't we look at the test set once now, just to be safe?"
    4. "Should folds be grouped by flight number?"
    5. "Your validation window is January to June. Does it represent the July to December test period?"

    The expected evidence for this task is shown after you save your own output.

  5. Task 5

    review

    Write the Week 3 review entry in decision-log.md. Include:

    • the status of each Week 3 studio;
    • recall misses;
    • whether the Week 2 routing decision is working, with the evidence;
    • next week's priority.

    The expected evidence for this task is shown after you save your own output.

Rubric4 criteria

CriterionMeetsExceeds
Leakage detectionAt least six of the eight flaws are identified with the correct mechanism.All eight are identified and ranked by their effect on the reported score, with at least one ablation run to support the ranking.
Repair qualityThe repaired script runs, respects the D-14 cutoff, the protected test period and train-only fitting, and is compared with the pickup baseline.The repair reuses the project's split/guard function rather than re-implementing it, and the comparison table reconciles with Saturday's results.
Validation defenseAll five answers are correct and concise, and each names the leak or bias it prevents.The answers anticipate how Week 5's rolling-origin design will change the evidence, and what would invalidate the current split.
Recall and reviewThe recall is done closed-book, with corrections, and the weekly review names next week's priority.The review checks whether the Week 2 routing decision is working, using evidence.

Required output

Saved in forecasting-project/:

  • review/flaw-review-w03.md, with the committed first sentence, the ranked flaws and the comparison table;
  • review/repaired_w03.py, runnable;
  • the five defense answers;
  • updated notes/recall-log.md and decision-log.md, with next week's priority.

This completes the Week 3 main evidence: a runnable baseline, validation predictions and a leakage-aware review.

Studios are tracked separately from the 60 core lessons; completing one never completes a lesson.