No history yet

Bootstrapping Machine Learning

Transcript

Beau

Okay, Jo, so we've spent all this time building up the bootstrap logic—resampling with replacement, getting these distributions... and my big question now is, how does this actually help me with my scikit-learn model? You know, I've just trained a LightGBM classifier, I run `model.score()`, and it spits out, say, 92% accuracy. I'm happy, my boss is happy. Why do I need to make it more complicated?

Jo

That's the perfect question. Because that 92% is a point estimate. It's a single number based on one specific slice of data—your test set. But what if you had a slightly different test set? Would you still get 92%? Or would it be 89%? Or maybe 94%?

Beau

Right, I see where you're going. It's the same logic we talked about with the mean. The sample mean isn't the *true* population mean. So my 92% accuracy isn't the *true* accuracy of the model.

Jo

Exactly. It's just an estimate. And bootstrapping is how we figure out how good that estimate is. Instead of just reporting 'the accuracy is 92%', we can say 'we are 95% confident that the true accuracy of this model is between 89% and 94%.' That's a much more powerful and honest statement.

Beau

So how does that work in practice? Am I... bootstrapping my predictions?

Jo

Almost. You bootstrap your test set. Let's say your test set has 1,000 data points. You'd create a new, 'bootstrapped' test set by sampling 1,000 points from the original one *with replacement*. Some data points will be left out, some will appear once, some might appear multiple times.

Beau

Okay, so I have this new, slightly weird version of my test set.

Jo

And on that new test set, you calculate your metric—say, accuracy or AUC. You get one number. Maybe it's 91.5%. Then you do it again. Create another bootstrapped test set, calculate the metric. Maybe this time you get 92.8%. You repeat this a thousand times.

Beau

And I end up with a list of a thousand accuracy scores. And *that* is my bootstrap distribution. From there, I can just take the 2.5th and 97.5th percentiles to get my confidence interval, just like we did before.

Jo

You've got it. That's the percentile method we covered. It's incredibly powerful for metrics like AUC or F1-score where there isn't a simple textbook formula for the confidence interval. But we're not just limited to the final performance score.

Beau

Oh? What else can we... bootstrap?

Jo

Feature importances. You know that bar chart you get from LightGBM showing which features were most important? That's also a point estimate. On a different sample of data, a different feature might have looked more important.

Beau

Wait, that's huge. I've definitely had situations where I re-run something and the second-most important feature suddenly becomes the fourth-most. I always just assumed it was random noise.

Jo

It's sampling variability! And we can measure it. Instead of just running the feature importance once on your whole dataset, you bootstrap your *training* data this time. You create a thousand bootstrapped training sets, train a thousand different LightGBM models, and get a thousand sets of feature importances.

Beau

So for each feature, I'd have a distribution of its importance score. Instead of a single bar on a chart, I'd have... a box plot?

Jo

Exactly! You'd see not just which feature is most important on average, but also how stable that importance is. If one feature has a very tight, high box plot and another has a really wide one that even goes down to zero, you have much more confidence in the first feature being genuinely important.

Beau

That completely changes how I would present results. It's the difference between saying 'Feature A is most important' and 'Feature A is consistently the most important, while the importance of Feature B varies a lot.'

Jo

Now, this process of bootstrapping the training set actually has a special name that you might have heard of... out-of-bag estimation.

Beau

OOB! Yes, I've seen the `oob_score` parameter in Random Forests in scikit-learn. I never really got what it was doing under the hood.

Jo

It's just bootstrapping! When you create a bootstrap sample from your training data, about one-third of the original data points are left out, on average. Those are the 'out-of-bag' samples. For each tree in a Random Forest, which is trained on a bootstrap sample, you can use its out-of-bag samples as a mini-validation set.

Beau

So it's like getting a free cross-validation score while you train. That's clever. It's all just resampling with replacement.

Jo

It all comes back to that. Now for the final step. Let's say you've built your awesome LightGBM model. And I've built one too, maybe a logistic regression. Your model gets 92% accuracy, and mine gets 91%. Is your model actually better?

Beau

Well... it's higher. So yes?

Jo

Maybe. But maybe not *statistically significantly* better. What we can do is bootstrap the test set, just like we did before. But this time, on each bootstrapped sample, we calculate the accuracy for *your* model and for *my* model. And then we calculate the difference.

Beau

So if I run 1,000 bootstraps, I'll have a list of 1,000 accuracy differences. Like, plus 1.2%, minus 0.5%, plus 2.1%...

Jo

Exactly. You create a distribution of the *difference* in performance. Then you can calculate a 95% confidence interval on that difference. If that interval is, say, 0.5% to 2.5%, it doesn't contain zero. That means you can be 95% confident your model is truly better.

Beau

But if the interval was something like minus 1% to positive 3%, it *does* contain zero. Which means it's plausible the true difference is zero, and my model isn't actually better. That one point of accuracy I saw initially could have just been luck of the draw with the test set.

Jo

And that is the entire point. It moves us from chasing single point estimates to understanding and quantifying the uncertainty around our models. It lets us know how much we should trust our accuracy score, our feature importances, and even our model comparisons.

Beau

So... I guess I have a lot of loops to write. But it feels like it's worth it to stop guessing.