Forecasting to Production: Time Series, FastAPI, Docker and Drift Monitoring

Can a forecast survive contact with the real world? In this capstone we build a time-series forecaster honestly, then ship it as a tested, containerized, monitored API.

Intro

Notebook Versus Reality

A forecast that looks brilliant in a notebook can be worthless the day it goes live. Usually the reason is not a weak model. It is a flattering evaluation, a hidden leak from the future, or a service nobody watches. In this capstone we build a forecaster honestly, and then we ship it.

  • Good notebooks can fail live
  • Leaks and weak evaluation
  • Shipping needs discipline

Two Capstones, One Pipeline

Last time, in lesson 68, we trained an image classifier and a small transformer language model. Today is capstone eleven and twelve. First a full forecasting project, then an end-to-end deployed machine learning app built on the operations ideas from lesson 63.

  • Capstone 11: forecasting
  • Capstone 12: deployed app

The Project Plan

Here is the plan. We pick a public series, set a baseline, and fit ETS, ARIMA and a gradient-boosted model. We evaluate with rolling origins, add intervals, and check for leakage. Then we wrap the winner in an API, test it, containerize it, monitor it, and finish with a postmortem.

  • Model, evaluate, check
  • Package, test, ship
  • Monitor and reflect

Data and Baselines

The Airline Passengers Series

We use the classic monthly airline passengers series, one hundred forty-four observations from 1949 to 1960. It has a rising trend and a seasonal swing that grows with the level. That growing swing is a hint that a multiplicative model, or a log transform, will help.

  • 144 monthly observations
  • Trend plus seasonality
  • Swing grows with level

Never Shuffle Time

Time order is sacred. We never shuffle. We hold out the final twelve months as a test set, and everything we tune uses only earlier data. Shuffling a series lets a model peek at tomorrow while predicting yesterday, and that is the first form of leakage.

  • Hold out the last 12 months
  • Tune only on the past
  • Shuffling leaks the future

Seasonal Naive Baseline

Now the baseline, which every forecast must beat. The seasonal naive method predicts that each month equals the same month one year earlier. Written simply, the forecast for time t equals the actual value at t minus twelve. It costs nothing, and it is surprisingly hard to beat.

  • Forecast = same month last year
  • Zero parameters
  • The bar to beat

Why Baselines Matter

Why insist on a baseline? Because a number like five percent error means nothing alone. If the naive method scores four percent, your fancy model is a loss. Every later score in this video is compared to seasonal naive, and that comparison is exactly what the MASE metric will formalize.

  • Scores need context
  • Beat the naive first
  • Complexity must earn its place

Naive Versus Seasonal Naive

A second quick check is plain naive, which repeats the last observed value. On trending seasonal data it ignores the seasons and does badly. Having both naive and seasonal naive tells us how much of the signal is just seasonality, and how much is left for real models to capture.

  • Naive repeats the last value
  • Seasonal naive repeats last cycle

ETS and ARIMA

ETS: Level, Trend, Season

Next, exponential smoothing, or ETS, from lesson 46. It tracks a level, a trend and a seasonal pattern, updating each with a smoothing weight between zero and one. Recent observations get exponentially more influence. With multiplicative seasonality, it matches our growing swings nicely.

  • Smoothing weights between 0 and 1
  • Recent data counts more
  • Multiplicative seasonality

ARIMA on a Stationary Series

Then ARIMA, also from lesson 46. We take the log of the series, difference once to remove trend, and seasonally difference at lag twelve to remove the yearly pattern. The model then describes what is left with autoregressive and moving-average terms. Differencing is why the series becomes stationary enough to model.

  • Log, then difference
  • Seasonal difference at lag 12
  • AR and MA terms on the rest

Choosing Orders, Checking Residuals

How do we choose the orders? We compare candidate models using information criteria such as AIC on the training window only, then check residuals. Good residuals look like white noise: no autocorrelation spikes, roughly constant spread. Patterns left in the residuals mean signal the model missed.

  • Compare AIC on training data
  • Residuals should be white noise
  • Spikes mean missed signal

Gradient-Boosted Lag Features

Lag Features Turn Time Into Tables

Now a different style: turn forecasting into ordinary supervised learning. For each month, build features from the past: the value one month ago, two months ago, twelve months ago, and a rolling mean of the last three. The target is the value now. Then any tabular model can learn it.

  • Lags 1, 2 and 12
  • Rolling mean of the past
  • Target is the current value

The Rolling Window Trap

Here is the trap. A rolling mean must use only earlier values. If your window accidentally includes the current month, the feature contains the answer. In code, this means shifting the series by one before rolling. This single shift separates an honest model from a fake one.

  • Window must end before t
  • Shift by one, then roll
  • One line separates honest from fake

Trees and Trends

We fit a gradient-boosted tree model, as in lesson 42, on these lag features. Trees cannot extrapolate beyond values they have seen, so a rising trend is a problem. A common fix is to predict the ratio to last year, or the log difference, instead of the raw level.

  • Trees cannot extrapolate
  • Predict ratios or differences
  • Transform the target

Recursive Versus Direct

For multi-step forecasts there are two strategies. Recursive forecasting feeds each prediction back as the next lag, which compounds errors. Direct forecasting trains a separate model for each horizon, using only information available at the forecast origin. Direct costs more models, but avoids error snowballing.

  • Recursive feeds back predictions
  • Errors compound
  • Direct trains one model per horizon

Rolling-Origin Evaluation

Rolling-Origin Evaluation

A single train and test split gives one noisy score. Rolling-origin evaluation repeats the test many times. We train on the first ninety-six months and forecast twelve. Then we move the origin forward twelve months, retrain, and forecast again. With one hundred forty-four points, that gives four folds.

  • Train on the past, forecast ahead
  • Slide the origin forward
  • 96, 108, 120, 132 give four folds

Average Across Folds

Every fold respects time: training data always precedes test data. Averaging errors across folds is far more stable than one split, and the spread across folds shows how reliable the model is. Remember lesson 24: all tuning belongs inside the training portion, and the final twelve months stay untouched until the very end.

  • Training always precedes testing
  • Mean and spread of fold errors
  • Final test touched once

MAPE by Hand

Now metrics. MAPE is the mean absolute percentage error. Take three months with actuals one hundred, one hundred twenty and eighty, and forecasts ninety, one hundred thirty and eighty-eight. Absolute errors are ten, ten and eight. As percentages: ten percent, eight point three percent, and ten percent. The average is about nine point four percent.

  • Absolute error divided by actual
  • Errors: 10, 10, 8
  • MAPE is about 9.4 percent

Why MASE

MAPE has flaws. It explodes when actuals are near zero, it is undefined at zero, and it penalizes over-forecasts and under-forecasts unevenly. So we add MASE, the mean absolute scaled error. It divides your mean absolute error by the mean absolute error of the seasonal naive method on the training data.

  • MAPE fails near zero
  • MASE scales by the naive error
  • Comparable across series

MASE by Hand

Using the same example, mean absolute error is twenty-eight divided by three, about nine point three three. Suppose seasonal naive scores twelve on training data. Then MASE equals nine point three three over twelve, about zero point seven eight. Below one means we beat the baseline. Above one means we lost to it.

  • MAE = 28 / 3 = 9.33
  • Naive MAE = 12
  • MASE = 0.78, below 1 wins

Comparing the Candidates

Run all four candidates across the four folds, and report MASE with its spread. A typical honest outcome is that ETS and ARIMA both beat seasonal naive clearly, while the boosted model is competitive but not always better. If so, say it plainly. Simpler models winning is a legitimate result, not a failure.

  • Report mean and spread
  • Beat naive across folds
  • Simple winners are fine

Intervals and Leakage

Forecast Intervals

A point forecast hides uncertainty. Suppose the forecast is one hundred and residual standard deviation is eight. A ninety-five percent interval is one hundred plus or minus one point nine six times eight, which is about fifteen point seven. So the range runs from roughly eighty-four to one hundred sixteen.

  • Forecast 100, sigma 8
  • 1.96 times 8 is about 15.7
  • Range 84 to 116

Intervals Widen With Horizon

Intervals should widen with the horizon, because errors accumulate. For a random-walk style model the spread grows with the square root of the number of steps. If one step has sigma eight, four steps ahead is eight times two, which is sixteen. The fan shape of a good forecast chart is this effect.

  • Errors accumulate
  • Spread grows like square root of h
  • Four steps: 8 times 2 is 16

Empirical Intervals and Coverage

For the boosted model, formulas are not handy, so we use empirical residuals or quantile regression. Collect out-of-sample errors from the rolling folds, and take their fifth and ninety-fifth percentiles as interval bounds. Then check coverage: roughly ninety percent of actual values should fall inside a ninety percent interval. If only seventy percent do, the model is overconfident.

  • Use out-of-sample residual percentiles
  • Check actual coverage
  • Low coverage means overconfidence

The Leakage Audit

Time for a leakage audit. Ask four questions. Do any features use values at or after the forecast origin? Was any scaling or imputation fit on the full series? Were hyperparameters tuned on the test months? Are future-known inputs, like holidays, genuinely known at forecast time? One yes means your score is inflated.

  • Features using the future
  • Preprocessing fit on everything
  • Tuning on the test set

Sabotage Tests

A practical test: break the pipeline on purpose. Shuffle the target within the training window, or delete the last month of data and re-run. If performance barely changes, something upstream is fake. And if a model's error is suspiciously close to zero on a noisy series, suspect leakage before celebrating.

  • Shuffle the target and re-run
  • Suspiciously perfect means suspect
  • Break it on purpose

Packaging and API

Package the Pipeline

Now capstone twelve. Take the best forecaster and make it a product. First, package the whole pipeline as one object: feature creation, the model, and the interval residuals saved together with a version tag. Training and serving must run identical code, otherwise you invite training-serving skew, as we discussed in lesson 63.

  • One artifact, one version
  • Same code for train and serve
  • Avoid training-serving skew

A FastAPI Endpoint

Next, a FastAPI endpoint. We define a request schema with pydantic: a history of recent values and a horizon. The response contains forecasts, lower and upper bounds, and the model version. Validation rejects bad input automatically, for example a negative horizon or a history shorter than twenty-four months, with a clear error code.

  • POST /forecast
  • Pydantic validates input
  • Returns bounds and version

Load Once, Expose Health

Load the model once at startup, not on every request. Loading from disk per call would dominate latency. Also add a health endpoint that returns the model version, so deployment tools and humans can confirm which artifact is live. Small design choices like these decide whether an API is dependable.

  • Load the model at startup
  • Health endpoint with version
  • Avoid per-request loading

Three Levels of Tests

Write tests at three levels. Unit tests check feature functions, such as lag alignment and the shift that prevents leakage. Contract tests confirm the schema, and that bad input returns an error. A regression test forecasts a fixed history and asserts the output stays within a tolerance of a stored answer.

  • Unit: lag and shift logic
  • Contract: schema and errors
  • Regression: fixed input and output

Docker, Monitoring and Latency

Containerize With Docker

Containerize with Docker. The Dockerfile starts from a slim Python image, installs pinned dependencies, copies the artifact and code, and starts the server. Pinning versions makes the build reproducible. Anywhere the container runs, the same libraries, same code and same model answer the same request the same way.

  • Slim base image
  • Pinned dependencies
  • Same behavior everywhere

Structured Logging

Add structured logging. For each request, log a request ID, model version, input length, horizon, latency, and a summary of the input such as its mean and last value. Do not log sensitive raw data. These logs are the raw material for both debugging and drift monitoring.

  • Request ID and model version
  • Latency and input summary
  • Never log sensitive raw data

Measuring Latency

Now demonstrate requests and measure latency. Send, say, one thousand requests with a simple load script and record each response time. Report percentiles, not just the average. If the median is twelve milliseconds but the ninety-fifth percentile is thirty, users experience that slower tail. Those numbers are examples, and yours will differ by hardware.

  • Send many requests
  • Report p50 and p95
  • Tails matter more than means

Drift and Error Monitoring

Monitoring comes next, applying lesson 63. Compare recent input distributions with the training window, using a statistic like the population stability index. A common rule of thumb treats values above zero point two as notable shift. For forecasting, also track real error: once actuals arrive, compute rolling MASE and alert if it climbs above one.

  • Compare inputs with training
  • PSI above 0.2 is notable
  • Alert when rolling MASE exceeds 1

Postmortem

Failure Mode: Structural Breaks

Now the postmortem. Where can this system fail? First, structural breaks. A forecaster trained on years of stable seasonality cannot anticipate a sudden shock, like a pandemic or a policy change. Its intervals were calibrated on calm history, so they will look confidently wrong exactly when it matters most.

  • Shocks are not in training data
  • Intervals assume calm history
  • Confidently wrong when it matters

Failure Modes: Bad Data and Feedback

Second, data problems in production. Missing months, delayed data, unit changes, or a sensor that starts reporting zeros will all produce plausible-looking nonsense. Validation can catch some of it, but not all. Third, feedback loops: if forecasts drive decisions, such as stock levels, those decisions can change the data the model later learns from.

  • Gaps, delays, unit changes
  • Plausible nonsense output
  • Forecasts that change the data

Limits and Honest Reporting

Finally, limits of our evaluation. One series is one story. Four folds on one hundred forty-four months say little about other domains. Our latency tests ran on one machine, and our drift thresholds are rules of thumb. The honest conclusion is a documented model, a known baseline gap, and a plan to retrain and review.

  • One series, four folds
  • Rules of thumb, not laws
  • Document limits and retrain plan

Recap and Next Steps

Recap

Let us recap. We set a seasonal naive baseline, then fit ETS, ARIMA and a lag-feature boosted model. We judged them with rolling origins, MASE and MAPE, added intervals and checked coverage, and audited for leakage. Then we packaged, served, tested, containerized, logged, monitored and measured the app, and wrote a postmortem.

  • Honest forecasting evaluation
  • Tested, containerized, monitored API
  • Postmortem on failure modes

Next: Course Wrap-Up

In the next and final lesson, we wrap up the whole course and build your roadmap beyond it. Thanks for learning with me, and I will see you in lesson seventy.

  • Lesson 70: wrap-up and roadmap
  • Subscribe and build your own