Explainability from Scratch in C++
This series implements the core ideas from Machine Learning · Explainability in plain C++. The focus is not on matching every feature of production libraries. The focus is on the mechanics: how to perturb data, query a black-box predictor, fit a weighted surrogate, and turn coefficients into explanations.
Implementation Roadmap
Permutation Importance
The baseline sanity check: shuffle one column, re-score the model, and measure how much performance drops.
LIME from Scratch
Generate local perturbations, weight them by distance, and solve weighted least squares for a local surrogate.
Kernel SHAP from Scratch
Sample coalition masks, query the model on masked rows, and fit weighted coalition regression to estimate attributions.
Tree SHAP from Scratch
Use tree structure for exact row-level explanations instead of black-box mask sampling.
Shared Predictor Interface
Every post assumes a callable predictor:
using Vector = vector<double>;
using Matrix = vector<vector<double>>;
using Predictor = function<double(const Vector&)>;