blackbox: warn when LimeTabular ignores user-supplied mode (#477)#667
Open
jbbqqf wants to merge 1 commit intointerpretml:mainfrom
Open
blackbox: warn when LimeTabular ignores user-supplied mode (#477)#667jbbqqf wants to merge 1 commit intointerpretml:mainfrom
jbbqqf wants to merge 1 commit intointerpretml:mainfrom
Conversation
…ml#477) LimeTabular always runs the underlying lime explainer in mode="regression", regardless of whether the wrapped model is a regressor or a binary classifier — unify_predict_fn turns classifier output into a scalar probability so LIME can treat both cases uniformly. The override is intentional and necessary for the wrapper to work, but interpretml#477 showed it is silent and surprising: a user passing mode="classification" got their kwarg dropped on the floor with no indication. Issue a UserWarning whenever the user-supplied mode differs from "regression". Default-path users (no mode kwarg, or explicit mode="regression") see no warning. The override behaviour itself is unchanged — the goal is purely to reduce confusion. Add tests/blackbox/test_lime.py covering all three branches: warn on classification, quiet on default, quiet on explicit "regression". The warning case fails on origin/main (no warning emitted) and passes on this branch. Co-Authored-By: Claude Code <noreply@anthropic.com> Signed-off-by: jbbqqf <jbaptiste.braun@gmail.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #667 +/- ##
==========================================
+ Coverage 66.86% 66.93% +0.07%
==========================================
Files 77 77
Lines 11724 11728 +4
==========================================
+ Hits 7839 7850 +11
+ Misses 3885 3878 -7
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
Summary
LimeTabular(model=..., data=..., mode="classification")silently dropsthe user-supplied
modeargument and runs LIME in"regression"modeinstead. The override is necessary (the wrapper unifies classifier
predict functions to a scalar so LIME can treat them uniformly), but
silence makes it confusing — users were left wondering why their
keyword had no effect (issue #477). Emit a
UserWarningwhen theoverride actually changes anything, so the behaviour stays the same
but the surprise is gone.
Fixes #477 — Why the "mode" in lime is fixed to "regression"?
Context
In
_lime.pythe wrapper does:The forced
"regression"is intentional:unify_predict_fn(predict_fn, X, 1 if n_classes == 2 else -1)turns a classifier into something that returnsa scalar probability, and LIME-in-classification-mode would expect a 2D
probability array. Running LIME in regression mode is what makes the
wrapper work for both regression and binary classification.
That is fine. What is not fine is dropping the user's
modekwargwithout a peep:
LimeTabular(..., mode="classification")looked like itwould do something and did nothing. This PR keeps the override but
emits a
UserWarningonly when the user actually passed a differentvalue. The silent path (no
mode, or explicitmode="regression")stays warning-free so we don't nag people who follow the documented
API.
Changes
python/interpret-core/interpret/blackbox/_lime.pywarningskwargs["mode"]isalready
"regression". If not, emit aUserWarningmentioning theuser's value and explaining why the wrapper forces regression mode.
invariant explicitly (citing issue Why the "mode" in lime is fixed to "regression"? #477) so a future maintainer
doesn't have to re-derive why this guard exists.
python/interpret-core/tests/blackbox/test_lime.py(new)mode="classification", no warningwhen
modeis omitted, no warning when the user explicitly passesmode="regression". The first case fails onorigin/main.Reproduce BEFORE/AFTER yourself (copy-paste)
What I ran locally
python -m pytest -vv tests/blackbox/test_lime.py→ 3 passed onthis branch; 1 failed, 2 passed on
origin/main(the failingcase is the warning assertion — exactly the divergence this PR
introduces).
ruff check interpret-core/interpret/blackbox/_lime.py→ 1 error,identical to
origin/main(PLC0415on the existingfrom lime…inline import; pre-existing, not touched by this PR).
ruff format --checkon the touched files → already formatted.Edge cases tested
mode="classification"test_user_supplied_mode_classification_warnsmodeomittedmode=test_no_warning_when_mode_omittedmode="regression"(explicit)test_no_warning_when_mode_regressionRisk / blast radius
The override behaviour is unchanged; existing user code keeps working.
The only new artefact is a
UserWarningon a path that was previouslysilent. Anyone who was unknowingly relying on the silent-override
behaviour will now see a single warning explaining what happened, then
the wrapper continues exactly as before.
Release note
PR drafted with assistance from Claude Code. The change was reviewed
manually against
interpretml/interpret's source and the cited issue.The reproducer block above was used during development; it is the same
one a reviewer can paste verbatim.