Repository navigation
Automatically set type to raw to avoid emitting warnings - #29
Conversation
type to raw to avoid emitting warnings
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #29 +/- ##
==========================================
+ Coverage 81.20% 85.79% +4.59%
==========================================
Files 3 4 +1
Lines 133 176 +43
==========================================
+ Hits 108 151 +43
Misses 25 25 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| # | ||
| # Note that stats::predict() is a generic: because object$fit is an | ||
| # lgb.Booster, the call is routed to predict.lgb.Booster(), which is | ||
| # where `type` actually lands. |
There was a problem hiding this comment.
I'm not sure if this level of verbosity is needed, but I dropped it here because this generic comment would have saved me hours of time
There was a problem hiding this comment.
[Praise] I like it! This behavior is definitely confusing, so it's well worth the comment in my opinion.
jeancochrane
left a comment
There was a problem hiding this comment.
Nice job getting to the bottom of a tricky warning! Your explanations make sense and I think this is a good way of fixing the issue. Note that we'll need to merge corresponding res and condo model PRs to bump the version of this package before we can close #28.
| # | ||
| # Note that stats::predict() is a generic: because object$fit is an | ||
| # lgb.Booster, the call is routed to predict.lgb.Booster(), which is | ||
| # where `type` actually lands. |
There was a problem hiding this comment.
[Praise] I like it! This behavior is definitely confusing, so it's well worth the comment in my opinion.
| # lightgbm stores custom objectives as "none", so predict.lgb.Booster() | ||
| # has no way to produce the default "response" prediction type: it warns | ||
| # and falls back to "raw". pred_lgb_reg_num() detects this case and asks | ||
| # for "raw" directly, which avoids that warning. |
There was a problem hiding this comment.
[Question, non-blocking] I wonder if there's a way to test that the type argument to stats::predict() is set properly depending on the objective and/or the type keyword argument in pred_lgb_reg_num()? If so, it probably merits its own unit test to test the different configurations (i.e. type argument present; type argument not present with no objective; type argument not present with an objective). I assume this would require mocking out stats::predict(), which might be tricky, so I'm also fine not testing it if it's too troublesome.
There was a problem hiding this comment.
Let me know what you think of this - 8b3b045#r4095655023
| scales, | ||
| snakecase, | ||
| testthat (>= 3.0.0), | ||
| testthat (>= 3.2.0), |
There was a problem hiding this comment.
In order to use local_mocked_s3_method - https://www.rdocumentation.org/packages/testthat/versions/3.3.1/topics/local_mocked_s3_method
| # lightgbm stores custom objectives as "none", so predict.lgb.Booster() | ||
| # has no way to produce the default "response" prediction type: it warns | ||
| # and falls back to "raw". pred_lgb_reg_num() detects this case and asks | ||
| # for "raw" directly, which avoids that warning. |
The context
Issue - #28
When we supply a custom objective function
mse_cov, we setparams$objectiveto"none"which sets off this guard in
predict.lgb.BoosterThis doesn't affect the actual model fitting, it just throws out a bunch of warnings when we train models.
The fix
In
pred_lgb_reg_num, the function used for prediction, we make a conditional change. It says "if we had setparams$objectiveto"none"(our proxy for custom obj function), then we settypeto"raw".This
pred_lgb_reg_numcallsstats::predict(object$fit, ....). Which is then routed tolightgbm:::predict.lgb.Boosterwhich has thetypeargument that will now get set to"raw", rather than default to its default"response"value.You can verify the change in CV logging by comparing how the warning aggregation looked before we made this change:
to how it looks now
How is
stats::predict(object$fit, ....)routed tolightgbm:::predict.lgb.Booster?Reviewers of this PR may already know this, but this was very mysterious for me.
stats::predictis a generic R function, which means that the actual predict function that gets used is dependent upon the class of the first argument, in this case -object$fit.object$fitis classlgb.Boosterand as such it recruitspredict.lgb.Booster:which has the
typeparameter and gets passed our initially defined"raw"frompred_lgb_reg_num