-
Notifications
You must be signed in to change notification settings - Fork 3.9k
[python-package] simplify eval result printing #6749
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
Changes from 2 commits
e1db89d
5fa72f4
4d446de
6b63377
f2012b7
cc9bbbd
d97590d
132075d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -73,15 +73,13 @@ class CallbackEnv: | |||
|
||||
def _format_eval_result(value: _EvalResultTuple, show_stdv: bool) -> str: | ||||
"""Format metric string.""" | ||||
if len(value) == 4: | ||||
return f"{value[0]}'s {value[1]}: {value[2]:g}" | ||||
elif len(value) == 5: | ||||
if show_stdv: | ||||
return f"{value[0]}'s {value[1]}: {value[2]:g} + {value[4]:g}" # type: ignore[misc] | ||||
else: | ||||
return f"{value[0]}'s {value[1]}: {value[2]:g}" | ||||
else: | ||||
raise ValueError("Wrong metric value") | ||||
eval_name, metric_name, eval_result, *_ = value | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think of using similar names to the ones here LightGBM/python-package/lightgbm/basic.py Line 5215 in 53e0ddf
I find the first one a bit confusing, since it's the name of the validation set. Maybe something like dataset_name, metric_name, metric_value, *_ = value ?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're totally right... I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated in 6b63377 I'll do more of this renaming in future PRs. |
||||
out = f"{eval_name}'s {metric_name}: {eval_result:g}" | ||||
# tuples from cv() sometimes have a 5th item, with standard deviation of | ||||
# the evaluation metric (taken over all cross-validation folds) | ||||
if show_stdv and len(value) == 5: | ||||
out += f"+ {value[4]}" | ||||
jameslamb marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
return out | ||||
|
||||
|
||||
class _LogEvaluationCallback: | ||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're loosing this error, not sure if it can happen but may be worth adding a check at the start like:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, I don't think this is a very helpful error message. "Wrong metric value" doesn't really describe the problem here, and you'll end up walking the stacktrace to find this point in the code anyway.
Originally in this PR, I was thinking we could just keep this simple and let Python's "too many values to unpack" or "not enough values to unpack" tuple-unpacking errors convey that information. But thinking about it more... removing this exception means that you could now implement a custom metric function that returns tuples with more than 5 elements and LightGB would silently accept it. I think it's valuable to continue preventing that, to reserve the 6th, 7th, etc. elements for future LightGBM-internal purposes.
I'll put back an exception here using logic like you suggested... but changing the message to something a bit more helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright so I tried to add an error message here, and then write a test to check that it's raised... and I couldn't find a public code path that'd allow a tuple with too few or too many tuples to get to this point.
Here's what I tried:
That gets stopped earlier:
Here:
LightGBM/python-package/lightgbm/basic.py
Lines 5209 to 5215 in b33a12e
So I think that maybe this error message we're talking about was effectively unreachable.
And I don't think we should add a custom and slightly more informative error message there in
Booster.__inner_eval()
:ValueError
if anything other than exactly a 3-item tuple (or list of such tuples) is returned... so no need to add more protection against tuples of other sizesif len() ..: raise
would add a bit of extra overhead to every iteration