Repository navigation
Conversation
pred_param called every base tree with its own input check, which costs far more than the tree walk itself. When every learner is a scikit-learn regression tree, pred_param now checks X once (float32, the columns the trees read, NaN allowed only where every tree allows it) and calls the trees with check_input=False. A tree whose leaves all hold one value is replaced by its scalar update. The floating-point operations per parameter happen in the same order as before, so the output is bit-identical. The precomputed plan keeps references to the rounds it was built from and is rebuilt when they, init_params or learning_rate change. It is not pickled. max_iter, sparse input and other learners use the loop as before. fit and partial_fit warn (NGBoostDegenerateWarning) when every learner is constant, which happens silently when int(minibatch_frac * n) is below max(min_samples_split, 2 * min_samples_leaf). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N8iMyoH5TsKptT8vKngJEo
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reopening #452, which I closed by mistake; GitHub could not reopen it because the source fork had been deleted. The change is identical.
What this improves
Predictions with the default tree learners are about 2x faster, and the results are bit-identical to before. Most of the time in
pred_paramwent to scikit-learn validating the same input once per tree (1,000 checks for a 500-round Normal model), not to walking the trees. Models whose trees never split now predict in under a millisecond, andfitwarns when that happens, because such a model returns the same distribution for every input.How
DecisionTreeRegressororExtraTreeRegressor,pred_paramchecksXonce (float32, only the columns the trees read, NaN allowed only where every tree allows it, as each tree's own check does) and calls the trees withcheck_input=False.base_models,scalings,col_idxs,init_paramsorlearning_ratechange (refit,partial_fit, edits by hand), so it cannot go stale. It is left out of pickles and rebuilt on the first prediction.max_iter, sparse input and non-tree learners (for exampleRidge) still use the existing loop.fitandpartial_fitraiseNGBoostDegenerateWarningwhen every learner is constant. This happens without any message whenint(minibatch_frac * n)is belowmax(min_samples_split, 2 * min_samples_leaf).Proof it works
tests/test_prediction_plan.py(16 tests) comparespred_parambit for bit with the old loop. It covers all-constant, mixed and trailing-constant models, Normal, T, Bernoulli and k_categorical(3), minibatching,col_sample, early stopping,max_iter, staged predictions, refit,partial_fit, edited rounds, pickling,ExtraTreeRegressor,monotonic_cst, missing values, wide and narrow input,Ridgeand sparse input. It also checks the warning.--slow: 185 passed, 2 xfailed, 22 xpassed. black, isort, flake8 and pylint are clean (10.00/10).pred_paramtime before and after on Python 3.12, scikit-learn 1.6.1 and numpy 2.5 (one shared 8-core machine). Every output was bit-identical:NGBRegressor()default, California housingNGBRegressor()default, California housingNGBRegressor(col_sample=0.5, minibatch_frac=0.5)NGBClassifier()default, breast cancermin_samples_leaf=100,minibatch_frac=0.2, n=400)References
Related to #298 (a request for faster NGBoost training and inference). I found no open issue or PR for this change.
AI disclosure
This change was written with help from an AI coding assistant (Claude). The tests and linters listed above were run on this branch before opening the PR.