Machine Learning·Lesson 18·14 min·0/3 exercises

Logistic regression

The sigmoid, log-odds, and the one line of maths that makes coefficients readable

LogisticRegressionsigmoidlog-oddsodds ratioCpredict_proba

Watch it happen

Play it through, or step back and forth yourself.

LinearRegression
predicts a number
minutes = 34.2
LogisticRegression
predicts a probability
p(late) = 0.71
The "regression" in the name refers to how it's fitted, not what it predicts. It has been confusing people for a century and it isn't going to change.

The name is the worst thing about it. Logistic regression is a classifier — it predicts a probability between 0 and 1, and lesson 7's threshold turns that into a class.

The idea

The name is the worst thing about it. Logistic regression is a classifier. It predicts a probability between 0 and 1, and lesson 7's threshold turns that into a class. The "regression" refers to how it's fitted, not what it predicts, and it has been confusing people for about a century.

Why you can't just use linear regression

Fit a straight line to a 0/1 target and it happily predicts 1.4 and −0.3. Those aren't probabilities and there's no sensible way to read them. So you keep the weighted sum and squash the output:

z = b + w₁x₁ + w₂x₂ + …          # the same weighted sum as lesson 14
p = 1 / (1 + e^−z)                # the sigmoid

The sigmoid maps any real number into (0, 1). It's steep near the middle and flat at the ends, so once the evidence is strong, more of it barely moves the answer. And z = 0 maps to p = 0.5 — which is where predict()'s default threshold comes from.

The price: coefficients in log-odds

rain_heavy          +1.766
prep_min            +1.371
distance_km         +1.355
rain_none           −1.295
rider_Dev           +0.740
prep_min_missing    +0.659
intercept           −1.384

These are no longer "minutes per unit" as in lesson 14 — they're in log-odds, which nobody has intuition for. You can still read the signs and the ranking, but +1.766 as a magnitude is true and useless.

So exponentiate

np.exp(model.coef_[0])

rain_heavy      ×5.85     heavy rain multiplies the ODDS of late by 5.85
prep_min        ×3.94
distance_km     ×3.88
rain_none       ×0.27     dry weather cuts them to about a quarter

Same numbers, now sayable in a meeting. Always report the odds ratio, never the raw coefficient.

Odds, not probability

One trap worth working through once, because it's behind a lot of badly reported results. Those are odds ratios, and odds are not probability:

base rate    p = 0.222   →   odds = 0.222 / 0.778 = 0.285
heavy rain   odds × 5.85  →   odds = 1.67
back again   p = 1.67 / (1 + 1.67) = 0.625

So heavy rain takes a 22% chance to 62%, not to 130%. The multiplication happens in odds space, which is exactly why the answer stays a valid probability. odds = p / (1 − p), and back with p = odds / (1 + odds).

It's already regularised

LogisticRegression(C=1.0)     # the default — L2 penalty applied

C = 1 / alpha
C = 100     weak penalty
C = 0.01    strong penalty

Unlike LinearRegression, which has no penalty at all, logistic regression regularises out of the box. Two consequences: scaling matters (lesson 15's argument in full), and the knob is inverted — smaller C means more penalty, which makes sweeping it feel backwards the first time.

Other things worth knowing

  • max_iter=1000 — the default 100 often doesn't converge and warns. Raising it is not a fix for anything except the warning.
  • Multi-class is handled automatically, either one-vs-rest or multinomial; coef_ gains a row per class.
  • penalty="l1" with solver="liblinear" or "saga" gives you lasso-style sparsity for classification.
  • Its probabilities are reasonably calibrated out of the box, which is not true of every classifier — a forest's predict_proba is a vote share, not a probability.

Where it stands

logistic + full pipeline     5-fold AUC 0.8786 ± 0.028

Remember that number. Over the next four lessons you'll meet kNN, decision trees, random forests and gradient boosting, and none of them beats it — which is the same conclusion module 4 reached from the regression side, arrived at independently.

See it run

The lesson's code, ready to run and to fiddle with.

Putting the kettle on…

Starting up…

Worked example

not graded

Already written and ready to go — press Run to see what it does, then change a number, a column name, anything, and run it again.

trysweeping C from 0.001 to 100 and watching the coefficients shrink.

Press Run — the output appears here.

Your turn

3 exercises. Write the code yourself, then press Check — a nudge and the answer are there if you want them.

Fit the logistic pipeline and return the odds ratio for the largest coefficient by magnitude, along with its name: [name, odds_ratio], ratio rounded to 2 places.

your answer

Work the odds arithmetic. Starting from the base rate, apply an odds ratio of 5.85 and return the resulting probability, rounded to 3 places. (It is not 0.222 × 5.85.)

your answer

Return the 5-fold AUC [mean, std] for the logistic pipeline on the full feature set, rounded to 4 and 3 places. This is the number the rest of the module has to beat.

your answer