Classical Machine Learning Algorithms Questions
Foundational non-deep-learning models and when to reach for each. Covers linear and logistic regression, decision trees and ensemble methods (random forests, gradient boosting), support vector machines, k-nearest neighbors, and clustering, including their assumptions, strengths, and failure modes. Focuses on algorithm selection and the numerical and implementation considerations behind these workhorse models.
You have a dataset with thousands of numeric features, many of them strongly correlated, and far fewer samples than you would like. Would you use PCA here? Walk through how you would decide, and what you gain and lose by applying it before modeling.
Sample Answer
Direct answer
Yes, PCA is a reasonable default here: strong pairwise correlation among thousands of features is exactly the regime where a handful of components can absorb most of the variance, and reducing dimensionality before modeling helps when samples are scarce relative to features, because it shrinks the effective number of parameters the downstream model has to estimate. The decision is not PCA-or-nothing, though: it trades interpretability and some potentially label-relevant signal for variance compression, dimensionality reduction, and (indirectly) variance reduction in whatever model comes after it, so it is worth validating against alternatives rather than reaching for it reflexively.
Structured elaboration
Why correlated features plus scarce samples favors PCA. With n samples and p features where p≫n, the covariance matrix is rank-deficient and any model with p free parameters is in a severe small-sample regime, prone to high variance and overfitting. There is also a hard structural fact worth knowing: after centering, the n centered rows of X sum to zero, which forces them to lie in an (n−1)-dimensional subspace regardless of how large p is. So no matter how many thousands of features you have, PCA can produce at most n−1 components with nonzero variance; strong correlation among the original features is what determines whether most of that variance concentrates in a handful of components rather than being spread thinly across all n−1.
Decision checklist:
- Check the correlation structure first, either a correlation heatmap or the eigenvalue spectrum of the covariance matrix (the sorted list of eigenvalues, each one representing how much variance the corresponding principal component captures). If eigenvalues drop off sharply after the first few, PCA will compress well; if they decay slowly, PCA buys little.
- Decide whether the downstream model is linear or tree-based. Linear/distance-based models (linear/logistic regression, k-NN, SVM) tend to benefit most from PCA's decorrelation and dimensionality reduction; tree-based models (random forests, gradient boosting) usually do fine on raw correlated features and may lose useful axis-aligned splits after rotation.
- Decide whether you need interpretability. If a stakeholder needs to know "which original features drove this prediction," PCA's linear-combination components make that harder to answer directly (the loadings, the per-original-feature weights that make up each component, tell you which original features contribute most to a given component, but that's still an indirect read compared to a model built directly on the original features).
- Always fit the PCA transform (mean and components) on the training fold only, then apply it to validation/test, to avoid leaking information about the held-out set into the projection.
- Treat the number of components as a hyperparameter tuned by cross-validated downstream performance, not just a fixed variance threshold, when a supervised task is the actual goal.
What you gain: fewer, decorrelated features for the downstream model to fit, which reduces variance and the risk of overfitting when n is small; faster training and smaller storage; and, as a side effect, PCA acts as a form of denoising if the discarded low-variance directions are mostly noise.
What you lose: direct interpretability of individual input features; any predictive signal that happens to sit in a low-variance direction, since PCA is unsupervised and has no way to know a direction is small-variance-but-label-relevant; and a small amount of information whenever you keep k<n−1 components (the reconstruction error grows as you discard more).
Worked example
A small, fully reproducible illustration of the concentration effect. Simulate data from 3 shared latent factors plus feature-specific noise, with n=50 samples, p=200 features, a fixed seed, so anyone re-running this gets the same numbers:
import numpy as np
rng = np.random.default_rng(42)
n, p, k_true = 50, 200, 3
latent = rng.normal(size=(n, k_true))
loadings = rng.normal(size=(k_true, p))
X = latent @ loadings + rng.normal(scale=0.5, size=(n, p))
Xc = X - X.mean(axis=0)
_, S, _ = np.linalg.svd(Xc, full_matrices=False)
explained = (S ** 2) / (S ** 2).sum()
print("rank of Xc:", np.linalg.matrix_rank(Xc)) # 49, capped at n-1
print("explained variance, top 3:", explained[:3].round(4))
print("cumulative, top 3:", explained[:3].sum().round(4))
Running this gives explained variance ratios of approximately [0.4239, 0.3201, 0.1646] for the first three components, summing to about 0.9086, and a matrix rank of 49 (which is exactly n−1, confirming the structural cap above). Despite 200 features, three components recover over 90% of the variance because the features were generated from only 3 latent factors, which is the same mechanism that makes real strongly-correlated feature sets compress well.
Trade-offs & pitfalls
- Fitting PCA on the full dataset (train + test) before splitting is a common leakage mistake; always fit on train only.
- Standardize before PCA if the thousands of features are not on comparable scales, or the components will be dominated by whichever features happen to have the largest raw variance.
- Don't treat a variance-based cutoff as the final answer when there is a supervised target; cross-validate the number of components against the actual downstream metric, since maximum-variance directions and maximum-label-information directions are not guaranteed to coincide.
- If interpretability or nonlinear structure genuinely matters more than compression, compare PCA against supervised feature selection (L1-regularized models, mutual information) or a nonlinear reduction, rather than assuming PCA is the only lever available.
At a high level, how does gradient boosting build its ensemble? Walk through fitting sequential base learners to residuals or gradients, and what learning_rate, n_estimators, and base-learner complexity each control.
Sample Answer
Direct answer
Gradient boosting builds its ensemble one small step at a time: start from a simple baseline prediction, look at where that prediction is still wrong (the residual, or more generally the gradient of the loss), fit a new weak learner to predict that error, and add a shrunk version of it to the running prediction. Repeat, and each new learner nudges the ensemble a little closer to the targets. learning_rate controls the size of each nudge, n_estimators controls how many nudges you take, and base-learner complexity controls how much each individual nudge is allowed to represent.
Structured elaboration
The sequential fitting process.
- Initialize the ensemble with a simple constant prediction, typically the mean of the target for regression with squared-error loss.
- Compute how wrong the current ensemble is for every training example: for squared-error loss this is literally the residual yi−F(xi); for other losses it's the negative gradient of the loss with respect to the current prediction (a "pseudo-residual"), which reduces to the ordinary residual as a special case for squared error.
- Fit a new weak learner (almost always a shallow decision tree) to predict those residuals/gradients from the input features.
- Scale the new learner's output by
learning_rateand add it to the running prediction: Fm(x)=Fm−1(x)+learning_rate×hm(x). - Repeat steps 2 to 4 for
n_estimatorsrounds.
What each hyperparameter controls.
learning_ratescales how much each tree's correction actually moves the ensemble. A smaller learning rate (e.g., 0.05) means each step is conservative, so mistakes get corrected more gradually and the model is less likely to overreact to any single tree's idiosyncrasies, at the cost of needing more trees to reach the same overall fit.n_estimatorsis how many correction rounds you run. With a small learning rate you need more rounds to converge; with a large learning rate, few rounds can already overfit, since large corrections applied repeatedly can chase noise in the residuals.- Base-learner complexity (tree depth, or number of leaves) controls how much structure each individual correction step is allowed to capture. Very shallow trees (even single-split "stumps") are common because they're weak enough that many small, well-regularized corrections tend to generalize better than a few large, complex ones; deeper trees per step converge in fewer rounds but risk overfitting each individual correction to training-set noise.
These three interact: a smaller learning rate paired with shallower trees and more estimators is the classic "slow and steady" regularized recipe; the total model capacity is roughly the product of how many trees you fit, how expressive each one is, and how much each one is allowed to contribute.
Worked example
Toy regression with three training targets y=[3,5,9]. Initialize F0 as the mean: F0=(3+5+9)/3=17/3≈5.667 for every example. The residuals against this baseline:
r=y−F0=[3−5.667, 5−5.667, 9−5.667]=[−2.667, −0.667, 3.333]Suppose the first weak learner, fit to these residuals, predicts exactly h1=[−2.667,−0.667,3.333] (a tree that perfectly memorizes 3 training points, for illustration). With learning_rate = 0.1, the update is:
Compare to the true targets [3,5,9]: the squared error before this step was (−2.667)2+(−0.667)2+(3.333)2=7.11+0.44+11.11=18.66; after this one small step it's (3−5.400)2+(5−5.600)2+(9−6.000)2=5.76+0.36+9.00=15.12, a modest improvement from a single conservative step, exactly the "many small nudges" behavior the learning rate is designed to produce. A larger learning rate of 1.0 applied to the same h1 would move F1 all the way to [3,5,9] (perfect fit) in a single step, which is precisely why aggressive learning rates with expressive base learners overfit fast: the model has no room left to generalize beyond memorizing this exact training set.
Trade-offs & pitfalls
- Fitting sequentially to residuals means each tree depends on every tree before it; there's no natural row/column-level parallelism across boosting rounds the way there is within bagging, though modern implementations parallelize the split-finding within each individual tree.
- Too large a learning rate with too many estimators overfits fast, since large corrections applied repeatedly chase noise; too small a learning rate with too few estimators underfits, since the ensemble never fully closes the gap to the targets. Early stopping on a validation set is the standard practical guardrail against picking a bad n_estimators for a given learning rate.
- Shallow base learners (stumps or depth 2-3 trees) are usually preferred over deep ones specifically because gradient boosting already gets its expressiveness from stacking many weak learners; giving each individual learner too much capacity removes the regularizing benefit of the "many small steps" approach.
- This description covers first-order gradient boosting; modern implementations like XGBoost also use second-order (Hessian) information to compute better per-leaf updates, which changes the details of step 3 and 4 but not the overall sequential structure described here.
After adding a few correlated features to a linear model, the coefficients become unstable, and some even flip sign. What's going on, how do you confirm it (VIF, condition number), and what are your options to fix it?
Sample Answer
Direct answer
Sign flips and unstable coefficients after adding correlated features is the signature of multicollinearity: the new features carry mostly redundant information, so the loss surface has a long, flat valley and many different coefficient combinations fit the data almost equally well. Confirm it with the variance inflation factor (VIF) for each predictor and the condition number of X^T X, and fix it by dropping or combining redundant features, applying PCA, or using ridge or elastic net regularization.
Structured elaboration
Why it happens: the OLS variance of a coefficient is
Var(βj)=(n−1)Var(xj)(1−Rj2)σ2
where Rj2 is the R-squared from regressing feature j on every other predictor. As Rj2→1 (feature j becomes a near-linear combination of the others), the denominator shrinks toward zero and the variance explodes. VIF is exactly that blow-up factor:
VIFj=1−Rj21
Diagnosis:
- VIF: regress x_j on every other predictor, take that R_j^2, compute VIF_j. A common rule of thumb flags VIF > 10 (equivalently R_j^2 > 0.9); some practitioners use a stricter VIF > 5 cutoff.
- Condition number: the ratio of the largest to smallest eigenvalue (or singular value) of X^T X, after centering and scaling. Condition numbers above roughly 30 are commonly flagged; near-duplicate columns push one singular value toward zero, inflating this ratio.
Fixes and when to use them
| Fix | What it does | When to prefer it |
|---|---|---|
| Drop a redundant feature | Removes one of the correlated pair or group | You don't need both features' individual coefficients and one is clearly redundant |
| Combine features | Sum, average, or a domain-driven composite | The correlated features measure the same underlying construct |
| PCA | Replaces correlated features with orthogonal components | You care about predictive performance more than per-feature interpretation |
| Ridge / Elastic Net | Shrinks correlated coefficients together via the L2 penalty | You want to keep all features and stay close to the original coefficient space |
Worked example
Suppose x2 is nearly a linear function of x1, giving R2=0.98 when x1 is regressed on the other predictors:
VIFx1=1−0.981=50
A VIF of 50 is five times the common VIF > 10 flag: it means x1's coefficient variance is 50 times larger than it would be if x1 were uncorrelated with the other predictors, which is precisely the mechanism behind wide standard errors and sign flips across resamples. Ridge regularization counters this directly: adding lambda to X^T X adds lambda to every one of its eigenvalues, so the smallest eigenvalue (the one collinearity pushes toward zero) grows proportionally the most, shrinking the condition number and stabilizing the coefficient estimates.
Trade-offs & pitfalls
Pairwise correlation alone can miss the problem: two features can each show low pairwise correlation with every other predictor individually but still be a near-linear combination of several other predictors together; VIF catches this, a simple correlation matrix does not. PCA fixes the numerical instability but the resulting components are linear combinations of the raw features, so per-feature coefficient interpretability is genuinely lost, not just technically inconvenient, and that needs to be flagged to any stakeholder who expects a specific feature's effect. Regularization stabilizes coefficients but does not tell you which of the correlated features is truly causal, that requires domain knowledge or a design change, not a statistical fix.
Walk me through the main supervised algorithm families you know: logistic regression, decision trees, random forests, gradient boosting, and SVMs. For each, when is it a good choice, and how do dataset size, feature types, and interpretability requirements push you toward one over another?
Sample Answer
Direct answer
The honest answer to "which algorithm" is that dataset size, feature types, and interpretability requirements each push toward different families, and picking one starts from those constraints rather than from which model is generally strongest. For a fast, interpretable baseline reach for logistic regression; for structured tabular data where accuracy matters most, gradient boosting is usually the strongest default; for a quick, transparent single model that's easy to explain, a decision tree; for a well-regularized, higher-variance-tolerant version of a tree, a random forest; and SVMs earn their place on smaller or high-dimensional-sparse problems where the margin-maximizing boundary and kernel flexibility are worth the tuning cost.
The families, compared
| Algorithm | Best when | Weak when | Interpretability |
|---|---|---|---|
| Logistic regression | Need a fast, well-calibrated baseline; want to explain coefficients directly; sparse high-dimensional features (text) | True decision boundary is strongly non-linear and you haven't engineered interaction/polynomial features | High: coefficients map directly to log-odds effects |
| Decision tree | Need a single, fully transparent model; mixed feature types with no preprocessing; quick prototyping | Prone to high variance/overfitting on its own; usually beaten on accuracy by an ensemble | High: the split path is a literal explanation |
| Random forest | General-purpose tabular baseline; want strong accuracy with minimal tuning and some resistance to overfitting | Millions of rows where training/inference cost of many trees becomes expensive; need the most transparent possible explanation | Medium: feature importances available, but not a traceable single decision path |
| Gradient boosting (XGBoost/LightGBM/CatBoost) | Structured/tabular data where predictive accuracy is the priority; can tolerate more tuning and longer training | Small datasets where it can overfit without careful regularization; less naturally interpretable than a single tree | Low-medium: SHAP/feature importance are common add-ons, not built in |
| SVM (kernel) | Small-to-medium datasets, especially high-dimensional and sparse (text with a linear kernel), where margin maximization is a meaningful inductive bias | Large datasets (training cost grows quickly); needs careful C/gamma tuning and feature scaling | Low: no direct coefficient-style explanation, especially with a non-linear kernel |
How the three stated factors push the choice
Dataset size. Small datasets favor models with strong inductive bias and fewer parameters to estimate reliably, logistic regression, a shallow tree, or an SVM. Large datasets can support the extra flexibility of gradient boosting or a large random forest without as much overfitting risk, and can also make SVM training cost prohibitive.
Feature types. Trees and tree ensembles handle a mix of numeric and categorical features with comparatively little preprocessing (though categorical encoding still matters for the exact library) and don't require feature scaling. Logistic regression and SVMs require numeric, scaled features, and logistic regression additionally benefits from you having already thought about which interactions or non-linear transforms might matter, since it won't discover them on its own.
Interpretability requirements. If you have to explain individual coefficient effects to a regulator or stakeholder, logistic regression or a shallow decision tree are the honest choices, not a random forest or boosted ensemble with a SHAP plot bolted on afterward (SHAP assigns each feature a per-prediction contribution score computed after the model is trained; it explains an opaque model's output after the fact, it doesn't make the model itself inherently interpretable). If interpretability just means "we can point to which features mattered overall," feature importances from a tree ensemble usually satisfy that bar.
Worked example: applying the framework to a concrete scenario
Suppose you're building a credit-approval model: 50,000 rows, 40 features (mix of numeric income/history data and categorical fields like employment type), and a hard regulatory requirement that you can explain, per applicant, exactly why they were denied. Dataset size is moderate (rules out needing a lighter model purely for compute reasons, but also isn't so large that it demands the heaviest model available). Feature types are mixed, which trees handle natively and logistic regression needs encoding for. Interpretability is the deciding constraint here, it isn't "nice to have," it's a hard requirement, which rules out gradient boosting and kernel SVM regardless of any accuracy edge they might otherwise have, and pushes toward logistic regression (clean per-feature odds-ratio explanations) or a shallow decision tree (a literal, traceable rule path per applicant). Between those two, if the true relationship looks reasonably linear in the log-odds and you need per-feature effect sizes for a model documentation requirement, logistic regression wins; if you need a human-readable rule ("denied because income < X and credit history < Y"), a shallow tree communicates that more directly to a non-technical reviewer.
Trade-offs and pitfalls
- "Gradient boosting is usually strongest on tabular data" is a real, common pattern, but it's not a universal law, always validate on your actual dataset rather than defaulting to the ensemble because it wins on benchmarks in general.
- Interpretability requirements are often underspecified in practice; "the business wants to understand the model" can mean anything from "coefficients must be individually defensible to a regulator" to "we'd like a feature importance chart for a slide," and those two bars point toward very different model choices.
- Don't let ease-of-tuning substitute for validation: logistic regression's speed and interpretability don't make it the right choice if it demonstrably underperforms on your actual validation metric and the interpretability bar doesn't require it.
- Model choice isn't the whole story: a well-regularized, correctly-validated logistic regression can beat a poorly-tuned gradient boosting model in practice, family selection matters less than most people expect once basic tuning and validation discipline are in place.
Compare bagging, boosting, and stacking from a production standpoint: expected accuracy gains, training and inference complexity, interpretability, and operational risk. When is the extra overhead of an ensemble actually worth it versus a single model?
Sample Answer
Direct answer
Boosting typically gives the largest accuracy gains on tabular data but costs sequential training time; bagging (e.g. random forests) gives smaller, more reliable gains with cheap, embarrassingly parallel training; stacking can squeeze out the most accuracy of the three but multiplies your operational surface area (more models to serve, monitor, and retrain). In production, the extra overhead of any ensemble over a single well-tuned model is worth it when the accuracy gain is directly monetizable and you can afford the added maintenance; it's usually not worth it under tight latency or strict interpretability requirements.
Structured elaboration
Accuracy. Boosting (gradient-boosted trees) is generally the strongest of the three on structured tabular data, because it directly optimizes the loss by sequentially fitting residuals rather than averaging independent learners. Bagging gives smaller but very reliable gains, mainly by reducing the variance of an already-decent high-variance base learner (a deep tree). Stacking's ceiling is the highest of the three because it can combine genuinely different model families (a boosted tree, a linear model, a neural net), each catching errors the others miss, but the gain is conditional on the base models actually being diverse; stacking several near-identical models adds cost with little benefit.
Training and inference cost.
- Bagging: training is parallel across trees (near-linear speedup with more cores), but inference cost is the sum of every base tree's cost, since you must query all of them and average.
- Boosting: training is inherently sequential (each tree depends on the residuals of the previous ones), but a well-regularized boosted model needs fewer, shallower trees than a comparable random forest, often giving a smaller inference footprint than bagging for similar accuracy.
- Stacking: training cost is the sum of all base models plus a meta-learner, and a correctly-implemented stack requires an extra layer of cross-validation to generate out-of-fold predictions for the meta-learner (to avoid leakage), which meaningfully lengthens the training pipeline. Inference means running every base model, then the meta-learner, giving the worst latency of the three.
Interpretability and operational risk. A single boosted model is still explainable via SHAP or built-in feature importances, and it's one artifact to version, monitor, and roll back. Bagged forests are similarly explainable (importance is a little "blurred" across many trees) and have a natural resilience angle: losing or degrading a few trees barely moves the ensemble average. Stacking is the least interpretable and the highest operational risk: a silent distribution shift in one base model's inputs can corrupt the meta-learner's predictions in a way that's hard to trace back to its source, and you now have an entire fleet of models whose CI/CD, versioning, and rollback all need to be kept in sync with each other.
When the overhead is worth it. Reach for boosting as the default "best accuracy for reasonable operational cost" choice on tabular problems. Reach for bagging specifically when stability under resampled or shifting data matters more than squeezing out the last bit of accuracy, and you have spare parallel compute. Reserve stacking for settings where the last percentage point of accuracy has outsized business value (fraud, ad ranking, competition-style leaderboards) and you're willing to fund the added monitoring and retraining pipeline it requires; for most production services, a single well-tuned boosted model, or a bagged forest if latency is generous, beats a stack once you account for the true cost of running it.
Worked example
Consider a fraud-scoring service where a 0.5-point AUC improvement is worth roughly a known dollar figure per month in caught fraud minus false-positive review cost (a number the business can actually quote). If a stack adds that 0.5 points over a single boosted model but doubles inference latency and adds a second on-call surface (the meta-learner's own failure modes), the decision hinges entirely on whether that dollar figure covers the added engineering and infra cost, this is a real cost-benefit calculation the team should be able to write down, not an abstract "more accuracy is always better" argument. By contrast, in a real-time bidding path with a single-digit-millisecond latency budget, a stack's extra inference hop is very often a non-starter regardless of the accuracy gain, and a single boosted model (or even a distilled, single-tree approximation of one) is the realistic ceiling.
Trade-offs & pitfalls
- Don't evaluate ensembles on accuracy alone; the comparison that matters in production is accuracy gain per unit of added latency, memory, and on-call burden.
- Stacking without proper out-of-fold generation for the meta-learner's training data is a common, subtle leakage bug: the meta-learner ends up trained on predictions its base models could never have made "honestly" in production.
- Model distillation (training one small model to mimic a stack's or forest's outputs) is a legitimate way to keep most of the accuracy gain from an ensemble while collapsing the serving cost back down to a single model.
- "More models" is also "more failure surfaces": component-level monitoring, not just end-to-end metrics, is necessary for any of these ensembles, since an end-to-end metric can look fine for a while even after one component silently degrades.
Unlock Full Question Bank
Get access to all Classical Machine Learning Algorithms interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.