OLS Trainer

Week 8 · Predictive Modeling · target: days_to_pay on Summit Gear customers
Built-in AI tutor. Stuck on what a coefficient means in collections terms? Ask the helper on this page. It coaches the reading; it will not write your interpretation for you.

Week 5 drew a trendline through a scatter. This is the same idea made numeric and multi-variable: an ordinary least squares (OLS) model. The target here is days_to_pay — how long a Summit Gear customer takes to pay an invoice — and the predictors are the customer's account and order history. The AI writes the Python; the work that matters is choosing the predictors, judging the fit, and reading each coefficient in collections terms. This page builds that reading in two halves: first fit a line and see what least squares is minimizing, then read the full coefficient table the way you would read a real regression output.

On this page: A. Fit it visually  ·  B. Read the output  ·  C. Write the reading

A. Fit it visually — what is least squares minimizing?

A1 · One predictor at a time

Pick one predictor and watch OLS draw the single line that best predicts days_to_pay from it. The line is not eyeballed: it is the one line that makes the sum of squared vertical misses as small as possible. Toggle the residuals to see those misses — the dashed segments from each point to the line are what the model is shrinking.

What this panel is for: there is nothing to submit and no answer to get right. The point is to see what "best fit" actually means. For any predictor you pick, OLS lands on one specific line, the one that makes the squared residuals as small as possible. Read the slope, R², and RMSE, and toggle the residuals to see exactly what is being minimized, so that the coefficient tables later in the page are reading off a process you have already watched.

Slope (b₁)
Intercept (b₀)
RMSE (days)
Customers
Pick a predictor to see the reading.
Why square the residuals instead of just adding up the raw misses? Squaring the residuals does two things. It makes positive and negative misses both count (otherwise overshooting one customer would cancel undershooting another), and it penalizes big misses far more than small ones — a 20-day miss hurts the score four times as much as a 10-day miss. That gives OLS one clean, unique best line instead of many ties. RMSE summarizes the miss in the target's own units — roughly a typical miss, but with extra weight on the big ones, so it sits above the average miss: here, measured in days.

A fitted regression line through a scatter, with the vertical residual from each point to the line drawn as a dashed segment; one is labeled Residual = -5.58.
A residual is one customer's vertical miss: actual minus predicted. Least squares minimizes the sum of these, squared.
A2 · Train and Test

A model that fits the customers you already have is not the same as a model that predicts customers you have not seen. Split the sample: fit on one part (train), then score the held-out part (test). The chart colors the train customers and the held-out test customers differently and draws the line fit on the train set only, so you can see which points the model learned from and which ones it is being judged on. With a single clean predictor and a real relationship, you should expect train and test R² to track each other. That is the honest baseline this panel sets. The dramatic case (train great, test collapses, because the model memorized noise) takes many predictors to produce, so it is deferred to the feature-selection and multicollinearity trainer; this widget cannot manufacture it.

Currently fitting on the whole sample.

B. Read the output — the full coefficient table

A real forecast uses many predictors at once. Half A fit one predictor at a time; this is the multiple regression the AI would run for you — all the numeric predictors in one OLS on days_to_pay, 2,200 Summit Gear customers. The coefficients below are the fitted values from the Week 8 answer key. Read each one as: holding the other predictors fixed, a one-unit rise in this predictor changes predicted days-to-pay by this many days.

B1 · The prediction lab

Move a predictor and watch predicted days_to_pay update, term by term. The bar chart shows each predictor's contribution to this one customer's prediction (coefficient × value). This is what a fitted model is: a weighted sum plus an intercept.

Predicted days to pay

avg_balance and credit_limit are locked together: in this dataset they move as a unit, so the slider will not let you raise one while holding the other fixed. That "all else equal" move is exactly what the collinearity makes impossible to identify. Notice too that credit_limit and noise_a barely move the prediction on their own — their fitted coefficients are essentially zero. The next trainer shows why leaving collinear and noise predictors in is still a problem even when the coefficient looks small.

B2 · The coefficient table

This is the fitted output for the full model (R² = 0.844, adjusted R² = 0.843, n = 2,200). The Significant? column flags whether the predictor's effect is distinguishable from zero (|t| > 2, p < 0.05). Watch what gets flagged.

Predictor Coef (days) Std err t p Sig? Reading
What a careful analyst flags here. Three things. (1) noise_a and noise_b are not significant — they are random columns and the model correctly cannot find an effect. (2) credit_limit and annual_spend look near-zero and unstable, while avg_balance is strongly significant — these three move together, so the model can't tell their effects apart. That instability is the multicollinearity problem (next trainer). (3) Only avg_balance, prior_late_count, days_since_last_order, orders_per_year, and discount_rate are doing real work.
B3 · Reading the fit statistics

Before trusting any coefficient, read the model-level numbers. These say how well the whole model fits and whether it is over-rewarded for the predictors it carries. The figures below come from the full multiple-regression fit in Section B: all numeric predictors on 2,200 Summit Gear customers, taken from the Week 8 answer key.

0.844 The share of variation in days-to-pay explained on this dataset — about 84% here. The remaining 16% is genuine noise, drivers not measured, and model misspecification; that part is not automatically recoverable by adding more columns. Treat this value as illustrative of this particular fit, not a benchmark for what an AR-aging model should hit.
Adjusted R²0.843 penalized for the number of predictors. It is barely below R² here, which means the extra columns are not buying much. If you added a useless predictor, R² would tick up but adjusted R² would drop. You can watch that happen in the live demo just below. This is the number that stops feature creep, and the centerpiece of the next trainer.
RMSE~7.1 days Root-mean-square error on this dataset, in days. It is roughly the size of a typical miss but puts extra weight on the big ones, so it sits above the average miss. RMSE is in the target's units, so it is the number to quote to a controller. This figure is illustrative of this fit.
Std err (coef)column How uncertain each coefficient is. A coefficient of 3.34 with std err 0.11 (prior_late_count) is precise. A coefficient near zero with a std err as large or larger (credit_limit) could easily be zero — that is the signal of a predictor not carrying its own information.
t and pcolumns t is coef ÷ std err: how many std errors the coefficient sits from zero. |t| > 2 (equivalently p < 0.05) is the usual "this effect is real" threshold. Below it, treat the coefficient as indistinguishable from no effect.
B3b · R² vs adjusted R², live

R² can only rise when you add a predictor, even a useless one, because the line always has more room to bend toward the points. Adjusted R² subtracts a penalty for every predictor you spend, so it rises only when the new column earns its keep. Start from the five clean predictors, then add the size-cluster correlates and the noise columns and watch the two numbers split. The two endpoints are taken straight from the Week 8 answer key: five clean predictors fit R² 0.8438, and all ten fit R² 0.8441, with adjusted R² 0.8434 either way. The per-column increments in between are illustrative.

Optional predictors on top of the five clean ones. Each is a column the next trainer argues you should drop. Click to include or exclude it; included predictors are highlighted.

5
Predictors (k)
Adjusted R²
R² − adjusted

Adjusted R² uses 1 − (1 − R²)(n − 1) ÷ (n − k − 1), where k is the predictor count. At n = 2,200 the penalty is tiny, so R² and adjusted R² read almost the same no matter what you add. Shrink n to 40 and the penalty bites: adding the noise columns now visibly pulls adjusted R² down even as R² creeps up. That divergence is the whole reason to prefer adjusted R² when comparing models.

B4 · Which coefficients are real?

Each bar is a coefficient with its 95% confidence band, scaled so the effects are comparable. If a band crosses the zero line, the predictor is not significant: the data can't rule out "no effect". The noise columns and the unstable cluster members land on or across zero.

Bands are standardized (coef × predictor SD) — each bar is the effect of a one-SD move in that predictor, in days — so a dollar predictor and a count predictor can sit on the same axis. Red = raises days-to-pay, blue = lowers it, and grey marks a predictor tagged n.s., short for not statistically significant: its confidence band crosses zero.

Two scatter plots side by side: a low R-squared noisy fit (0.19) next to a high R-squared tight fit (0.88).
R² is the share of the variation in days-to-pay that the model explains, computed as 1 − (residual sum of squares ÷ total sum of squares). The tighter the points cluster around the line, the higher it goes.

C. Write the reading

C1 · One coefficient, in collections terms

Running OLS is not the skill here; the AI can do that. The skill is reading the result like an analyst. Write a one- or two-sentence interpretation of the prior_late_count coefficient (3.34) in plain collections language: what it predicts about days-to-pay, what "holding the others fixed" adds, and whether you trust it. Then ask the tutor to react. It will not write the sentence for you, but it will tell you what a strong reading includes.

A strong reading names the direction and size (about 3.3 more days per prior late payment), states the "all else equal" caveat, ties it to a collections action, and notes that the coefficient is significant (t ≈ 30) so it is not a fluke. Try it before asking — the tutor holds back until you have an attempt down.

Where this goes next. You can now fit OLS, read a coefficient table, and judge a fit. The next trainer, Feature selection & multicollinearity, is where this gets sharp: it shows why leaving credit_limit and annual_spend in the model destabilizes the coefficients even though R² barely moves, and how a correlation matrix (a hot off-diagonal cell between two predictors is the tell) flags the cluster while adjusted R² stays flat. After that, Logistic does the same read-the-output skill for a yes/no target, defaulted.