Fix #1028: supply default LightGBM learner for cate scoring metrics - #1030
Conversation
jeongyoonlee
left a comment
There was a problem hiding this comment.
Please follow the existing convention in causalml/metrics/visualize.py rather than resolving the default inside the private helper.
-
Move the default into the signatures of the three public entry points that take
learner=None—compute_dr_pseudo_outcomes(:59),dr_score(:269),plug_in_t_score(:392) — aslearner=LGBMRegressor(num_leaves=64, learning_rate=0.05, n_estimators=300), matchingget_tmlegain/get_tmleqini/plot_tmlegain/plot_tmleqini(visualize.py:343, 453, 696, 740). The usual shared-instance concern with a mutable default doesn't apply here —_resolve_outcome_learnersalreadydeepcopys into each arm (:44,:49). Addverbose=-1as inplot_tmlegain(:696) if you want to silence the "no further splits" warnings noted in the description. -
Drop the
try/except ImportError. It can't fire:metrics/__init__.pyimports.visualize(:13) before.cate_scoring(:30),visualize.py:7imports lightgbm unconditionally, and lightgbm is a hard dependency (pyproject.toml:40). Import it at module top asvisualize.pydoes. -
Update
cate_scoring.py:315, which still reads "Required unlesspseudo_outcome_colis provided". That sentence is what #1028 was about, and it is now wrong in the other direction. A signature default documents itself, which is most of the reason to prefer (1). -
Keep raising when exactly one of
control_outcome_learner/treatment_outcome_learneris supplied. It currently pairs the given model with a default LightGBM for the other arm, and neither new test covers that path.
b889e91 to
c1eddde
Compare
|
I’ve updated the implementation to follow the existing visualize.py convention by moving the default LGBMRegressor into the signatures of compute_dr_pseudo_outcomes, dr_score, and plug_in_t_score. I also removed the unnecessary ImportError handling, updated the outdated learner documentation, and added regression coverage for both the default learner path and the partial outcome-learner case. |
| """ | ||
| if (learner is None) and ( | ||
| (control_outcome_learner is None) or (treatment_outcome_learner is None) | ||
| if (control_outcome_learner is None) != (treatment_outcome_learner is None) or ( |
There was a problem hiding this comment.
Let's split the condition into two, e.g., one with "!=", and the other with and/or for readability.
if (control_outcome_learner is None) != (treatment_outcome_learner is None):
raise ValueError(
"Specify both `control_outcome_learner` and `treatment_outcome_learner`, "
"or neither."
)
if learner is None and control_outcome_learner is None:
raise ValueError(
"Either `learner` or both `control_outcome_learner` and "
"`treatment_outcome_learner` must be specified."
)
c1eddde to
74ad49b
Compare
|
Done |
74ad49b to
9df136b
Compare
|
CI / CD failed so i worked on it. |
| import pytest | ||
| from sklearn.linear_model import LinearRegression |
9df136b to
9cb578e
Compare
|
Done removing duplicate imports. |
Proposed changes
This PR fixes #1028 by providing a default
LGBMRegressorwhen no outcome learner is supplied to the CATE scoring metrics.Previously,
_resolve_outcome_learnersraised aValueErrorwhen neither a learner nor both treatment/control outcome learners were provided. This prevented the metrics from being used with their expected default behavior.The fix:
LGBMRegressoras the default outcome learner.ValueErrorfallback when LightGBM is unavailable.num_leaves=64,learning_rate=0.05,n_estimators=300.Before
After
Test
Before
After
Fixes #1028.
Types of changes
Checklist
Further comments
The implementation is intentionally minimal and limited to the outcome-learner resolution path. Existing callers that provide their own learners are unaffected.
The relevant metric test completes successfully with the default learner. LightGBM emits warnings for some small test folds where no valid splits are available, but these are warnings from LightGBM and do not cause the test to fail.