Six supervised families for tabular data, each an objective plus a bet: name the assumption you are betting on and you name the failure mode in the same breath.
Picking a family
On tabular data gradient boosting is the default; everything else needs a reason (small n, interpretability, latency, calibrated extrapolation).
flowchart TD
S{"Tabular?"} -->|Text| TXT["Linear SVM / logistic on TF-IDF"]
S -->|Images| IMG["Pretrained backbone + linear head"]
S -->|Yes| N{"n rows"}
N -->|"< ~1k"| P{"Need a probability?"}
N -->|"1k–10M"| GBDT["Gradient boosting"]
N -->|"> ~10M"| LIN["Linear / logistic + SGD"]
P -->|Yes| LR["Regularized logistic"]
P -->|No| SVM["Kernel SVM"]
GBDT -.->|"must explain coefficients"| LR
style GBDT fill:#2d6a4f,color:#fff
Linear regression
- OLS: minimize
||y - Xw||^2; convex, closed formw = (X^T X)^-1 X^T y(normal equations). Only model here with no iteration. - Cost: closed form
O(np^2 + p^3), memoryp^2(Gram matrix); SGDO(np)/epoch, memoryp, streams.p(notn) sets the crossover. - Never compute
inv(X.T @ X): formingX^T Xsquares the condition number, sokappa^2 · epsblows up. Use QR/SVD (lstsq). - Only two assumption violations bias the coefficients: non-linearity and exogeneity (
E[e|X]=0). Non-independence, heteroscedasticity, non-normal errors break only the standard errors (fix with HC3 / Newey-West). - Collinearity:
Var(beta_j) ∝ 1/(1 - R_j^2);VIF = 1/(1-R_j^2), SE inflates bysqrt(VIF). Hurts interpretation only, never prediction.
Regularization: L1 vs L2
- Ridge (L2) penalizes
sum w^2; Lasso (L1) penalizessum |w|.lambda=0is OLS. Standardize first (penalty acts on raw units); never penalize the intercept; tunelambdaby CV. - One coordinate (orthonormal design), OLS value
z:
z | Ridge z/(1+2λ) | Lasso soft-threshold |
|---|---|---|
| large | shrinks a lot | barely moves |
| small | shrinks, stays nonzero | set to exactly 0 |
- Why L1 zeroes: the subgradient of
|w|at 0 is the whole interval[-λ, λ], so 0 is optimal for a range of gradients. L2’s gradient2λwvanishes at 0, so it never reaches zero. (Geometry: diamond corners on the axes vs smooth ball.) - Rules: ridge
w = z/(1+2λ); lassow = sign(z)·max(|z|-λ, 0). - Elastic net for correlated feature blocks: L2 term makes the objective strictly convex, so the non-unique lasso pick (a coin flip) becomes a stable shared weight (grouping effect).
Logistic regression
- Squash score
w·xwith the sigmoid1/(1+e^-z), fit by max likelihood. Boundary is a flat hyperplane atw·x=0. Logit = log-odds is the canonical link for Bernoulli. - Not MSE: over a sigmoid MSE is concave for
s < 1/3(non-convex) and its gradient is ~50× smaller ats=0.01(vanishing). Log loss is convex everywhere with clean gradients - y. beta_j= change in log-odds;exp(beta_j)= odds ratio (constant). The probability change is not constant: OR 2 movesp0.10→0.18 but 0.50→0.67.- Complete separation sends the MLE to infinity (
coef=24.7+ convergence warning); L2 (sklearnC=1.0,C= inverse penalty) fixes it.
Trees, kNN, SVM, naive Bayes
- Trees: recursive
x <= tsplits, greedy max gain (Gini1 - Σp²or entropy). Two overfit paths: (1) max gain over~p·ncandidates is positive even with zero signal (>4 sd at 50k candidates); (2) rows halve each level, leaves become single memorized rows. Controls:min_samples_leaf(best single knob),ccp_alphapost-pruning,max_depth. No scaling needed, no extrapolation (leaf means flatline outside training range → trending features fail silently). - kNN: no training,
O(nd)/query. Curse of dimensionality: relative distance spread= 1.183/sqrt(d), so past ~20–30 features “nearest” stops meaning anything. Works on embeddings because intrinsic dimension (10–30) drives it, not ambient. Standardize, reduce dimension, pickkby CV, distance-weight. - SVM: maximize margin
2/||w||; soft margin adds slack priced atC(inverse regularization). Hinge loss is exactly 0 past the margin, so only support vectors matter (a million easy points don’t move the boundary). Kernel trick: dual uses only inner products, so replace withK(x,z)(RBF = infinite-dim map). Died on big tabular because the kernel matrix isn×n(80 GB at n=100k). Still wins whenp > n. Outputs distance not probability → Platt-scale. - Naive Bayes:
P(y|x) ∝ P(y)·Π P(x_j|y), assumes conditional independence (false everywhere). Survives because correlated evidence distorts the probability but not the argmax/ranking. Laplace smoothing (α=1) is mandatory or one unseen token zeroes the product. Use as label/rank only; isotonic-calibrate before thresholding.O(n·nnz), streams.
Symptom → fix
| Symptom | Fix |
|---|---|
| Huge opposite-sign coefficients, unstable | Collinearity; drop/combine/ridge if you must interpret |
inv(X.T@X) garbage on wide data | QR/SVD (lstsq) |
| Lasso zeroed everything / nothing | Standardize, tune λ by CV |
| Lasso picks a different feature each refit | Elastic net |
| Training stalls, confident wrong preds | Log loss, not MSE |
| Coef 24.7 + convergence warning | Regularize (separation) |
| Tree 100% train, 62% test | min_samples_leaf, ccp_alpha, or ensemble |
| Tree flatlines as feature trends | Difference/ratio it; no hyperparameter helps |
| kNN collapses past ~30 features | Reduce dimension first |
| Kernel SVM won’t fit in memory | Linear SVM + SGD, or Nystroem |
| Naive Bayes says 0.94, wrong half the time | Isotonic-calibrate; argmax still valid |
| Poisson, everything “significant” | Deviance/df > 1 → negative binomial / quasi-Poisson |