Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert ntree limit fix #6616

Merged
merged 5 commits into from
Jan 19, 2021
Merged

Conversation

trivialfis
Copy link
Member

Close #6615 .

@trivialfis trivialfis requested a review from hcho3 January 18, 2021 14:22
tests/python/test_predict.py Show resolved Hide resolved
best_ntree_limit=str(
(bst.best_iteration + 1) * num_parallel_tree * num_groups
)
best_ntree_limit=str((bst.best_iteration + 1) * num_parallel_tree)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not an exact revert since we also have fix for an old bug for gblinear with ntree_limit, which is valid.

Copy link
Collaborator

@hcho3 hcho3 Jan 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the best_ntree_limit attribute is really a misnomer; it behaves more like best_iteration in the C++ layer. Is my understanding correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The C++ layer considers num_group as it's a model parameter, and predictor PredictBatch has GBTreeModel as its argument. But it doesn't consider num_parallel_tree, which is a training parameter instead of model parameter. So the C++ function for ntree_limit is half implementation for best_iteration.

Copy link
Collaborator

@hcho3 hcho3 Jan 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it's best_iteration * num_parallel_tree then? We should clearly document the meaning of best_ntree_limit, e.g.

Despite its name, the best_ntree_limit attribute is actually the product (best_iteration * num_parallel_tree).
If you set num_parallel_tree > 1, then best_ntree_limit won't be equal to the best boosting round.

Going forward, please use model slicing in all new code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify and reinforce: The best_ntree_limit equals num_parallel_tree * best_iteration. num_class is multiplied inside predictor.

When using classifier, the best_ntree_limit equals to number of trees produced in best iteration / num_class.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inplace prediction doesn't have this problem as it can use best_iteration directly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hcho3 I will try to deprecate the attribute after setting it as a Python @property where we can throw proper warnings.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, the sklearn model uses this attribute by default when running prediction.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a short note on train function.

@trivialfis trivialfis merged commit d6d72de into dmlc:master Jan 19, 2021
@trivialfis trivialfis deleted the revert-ntree-limit-fix branch January 19, 2021 15:51
trivialfis added a commit to trivialfis/xgboost that referenced this pull request Jan 19, 2021
The old (before fix) best_ntree_limit ignores the num_class parameters, which is incorrect. In before we workarounded it in c++ layer to avoid possible breaking changes on other language bindings. But the Python interpretation stayed incorrect. The PR fixed that in Python to consider num_class, but didn't remove the old workaround, so tree calculation in predictor is incorrect, see PredictBatch in CPUPredictor.
trivialfis added a commit to trivialfis/xgboost that referenced this pull request Jan 19, 2021
The old (before fix) best_ntree_limit ignores the num_class parameters, which is incorrect. In before we workarounded it in c++ layer to avoid possible breaking changes on other language bindings. But the Python interpretation stayed incorrect. The PR fixed that in Python to consider num_class, but didn't remove the old workaround, so tree calculation in predictor is incorrect, see PredictBatch in CPUPredictor.
trivialfis added a commit that referenced this pull request Jan 19, 2021
The old (before fix) best_ntree_limit ignores the num_class parameters, which is incorrect. In before we workarounded it in c++ layer to avoid possible breaking changes on other language bindings. But the Python interpretation stayed incorrect. The PR fixed that in Python to consider num_class, but didn't remove the old workaround, so tree calculation in predictor is incorrect, see PredictBatch in CPUPredictor.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incorrect best_ntree_limit.
2 participants