Generalized Linear Models
Least squares and logistic regression are one machine with two swap parts, a link and a noise family. Set them for counts and negatives vanish.
Why Does This Exist?
Helpdesk tickets arrive as counts. Quiet days see one or two, busy days see thirty, one Tuesday saw forty one. Marketing wants the cost of one extra promo email in tickets.
Fit least squares and it answers, then predicts minus 4.8 tickets on a zero promo day. Not zero, not flagged. A number that cannot exist. Spread breaks too: quiet days vary by two tickets while busy days swing by fifteen, but least squares assumes constant spread.
Linear regression predicts a mean directly with bell noise. Logistic regression runs the same linear score through a sigmoid with coin flip noise. Two looks, one machine with two dials. Turn the dials for counts and the negative vanishes structurally. The shared fitting principle is maximum likelihood, and its plain square loss form lives in ordinary least squares.
Think of It Like This
One camera body, two swap parts
The body never changes. Same shutter, same mount, same mechanism turning a scene into a picture. That is the linear predictor: features in, one weighted sum out.
The lens changes geometry. A wide lens and a long lens frame the same scene differently without touching the body. That is the link: it maps the weighted sum onto the thing you predict. A log lens can only output positive numbers, exactly what counts need.
The film changes grain. That is the noise family: how much spread to expect around the prediction and whether spread grows with it. Wrong lens gives impossible pictures. Wrong film gives possible pictures with wrong confidence. The body stays fine either way.
Where it stops: real lenses and films are physical and interchangeable by hand. Links and families are math choices that change the optimisation and the meaning of every coefficient. Swapping them rewrites the question, not just the framing.
How It Actually Works
Call one day features , weights , intercept . The linear predictor is unchanged from least squares:
is one real number per row. Call the expected tickets that day. The link ties them:
runs at prediction time and rules out impossible values. With , the inverse is , positive for every ever. No clipping step, no post fix.
The family sets noise around . Gaussian, Bernoulli, Poisson, Gamma all belong to one exponential family, which forces a mean variance rule for free. Fix the family and you fix how spread grows with level.
Three settings you will actually use
Identity link with Gaussian noise gives and constant variance. Maximising likelihood equals minimising squared error. That is ordinary least squares.
Logit link with Bernoulli noise gives as a probability and variance , peaking at 0.5 and vanishing at the ends. That is logistic regression.
Log link with Poisson noise gives and variance equal to mean. That is count regression: tickets per day, clicks per hour, defects per batch. It answers the minus 4.8 problem with one keyword change in most libraries.
Worked example: what one extra email costs
Suppose the fitted Poisson rate is , where counts promo emails. At zero emails the rate is , about 1.5 tickets. Each extra email multiplies the rate by , about triple. At two emails the mean is tickets with variance 13.4, while at zero the variance is only 1.5. Spread grows with level by construction. Least squares on the same 500 days extrapolates its straight line to minus 4.8 at zero, because nothing stops its identity link below zero. The diagram shows the score passing through the log inverse link to a positive mean with Poisson spread around it.
When Poisson is not enough
Poisson promises variance equals mean. Real counts break it through clustering: one outage spawns thirty tickets and unmodelled shifts lift the whole rate. That is overdispersion. Coefficients stay roughly right while standard errors come out too small, so effects look significant when they are not.
Check on residuals, not raw counts, since raw variance mostly reflects features working. Conditioned on the fit, variance over mean near 1.0 supports Poisson. Near 2.0 or higher, move to negative binomial, which is Poisson with a second parameter for exactly this slack.
Code
The point is the check: rebuild the rate math with plain arithmetic, no fitting library.
import math
intercept: float = 0.4slope: float = 1.1
at_zero: float = math.exp(intercept)per_email: float = math.exp(slope)at_two: float = math.exp(intercept + slope * 2.0)print(f"{at_zero:.2f} {per_email:.2f} {at_two:.1f}")# -> 1.49 3.00 13.4
coef: float = 0.3print(f"{math.exp(coef):.2f}")# -> 1.35Quiet days sit at 1.49 tickets, each email multiplies by 3.00, two emails give 13.4. A log coefficient of 0.30 means , so 35 percent more, not 0.30 more tickets.
Watch Out For
Fitting least squares to counts or rates
Symptom: negative predictions at the low end and residuals fanning into a wedge as fitted values grow. The identity link has no floor and Gaussian noise insists spread is constant while counts make it grow with the mean.
Fix: use log link with Poisson or negative binomial. Do not patch with least squares. That models mean of log rather than log of mean, biases low on retransform, and forces an invented constant for zeros that moves the answer.
Reading log coefficients as additive shifts
A log coefficient of 0.30 does not mean 0.30 more tickets. It means , so 35 percent more from whatever baseline applied. On a quiet 1.5 ticket day that is half a ticket. On the forty one ticket Tuesday it is fourteen.
Symptom: a modest table entry ships as a small effect while the real impact at high baselines is large. Fix: exponentiate every coefficient before it leaves the notebook, label the column as a rate ratio, and check that zero features is a state your data actually contains before quoting the intercept.
The Quick Version
- A GLM has three parts: linear predictor , link , and noise family.
- The inverse link rules out impossible values structurally, so log link never predicts minus 4.8 tickets.
- Identity plus Gaussian is least squares, logit plus Bernoulli is logistic regression, log plus Poisson is count regression.
- Our ticket model gives 1.49 at zero emails and multiplies by 3.00 per email, reaching 13.4 at two emails.
- Log coefficients multiply: 0.30 means , a 35 percent lift.
- Overdispersion leaves coefficients intact but shrinks standard errors, and negative binomial fixes it.