-
-
Notifications
You must be signed in to change notification settings - Fork 25.8k
Add transformation option to inspect functions #18309
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
Comments
I would be more in favour of this and it would be easy for somebody to create an estimator that does such transform: class TransformPredictionRegressor(BaseEstimator):
def __init__(self, estimator=None, transform=np.log):
self.estimator = estimator
self.transform = transform
def fit(self, X, y):
# TODO: validate the parameters
self.estimator.fit(X, y)
return self
def predict(self, X):
return transform(self.estimator.predict(X)) |
Okay, agreed. The wish to apply such transform in the explainers will raise as soon as we get interaction importance measues like Friedman's H. There, it will be essential to quickly switch to the "raw" level of predictions. |
I don't get that suggestion. y in fit and the return value of predict must
be on the same scale, or metrics don't work.
|
To my limited knowledge, I agree. I thought that we develop the TransformedTargetRegressor, especially to avoid such evaluation in practice. |
For permutation importance, being able to transform the scale is less important than for partial dependence (and many other interpretability methods hopefully up to come). We could thus focus on partial dependence (and keep it in mind for upcoming extensions of inspection). |
It sounds like for permutation importance the TransformedTargetRegressor
will suffice too? So maybe we should trial such a change on partial
dependence? Would you be willing to attempt a pull request?
|
To make the argument explicit, let us assume a
class PredictionTransformRegressor(BaseEstimator):
"""Apply transformation to an already fitted estimator."""
def __init__(self, estimator=None, transform=np.log):
self.estimator = estimator
self.transform = transform
def fit(self, X, y):
# TODO: validate the parameters
# This should be a no-op, i.e. we do not fit anything.
return self
def predict(self, X):
# We do not need to check if self was fitted.
return transform(self.estimator.predict(X)) # will call check_is_fitted(estimator)
reg = PoissonRegressor().fit(X, y)
transformed_reg = PredictionTransformRegressor(reg, transform=np.log)
partial_dependence(transformed_reg, X=X, features=...) I wonder if a simple option in |
I still think this is very important for usability. To be more explicit, we are discussing Options are:
|
This would be extremely useful. In the currently available inspection tools, its indeed only partial dependence that would need to be touched. (Later also H-statistics drafted in this PR). In this jupyter notebook, we use a custom LogRegressor class to see that certain ICE curves are parallel in a Poisson boosted trees model with interaction constraints. |
@glemaitre @adrinjalali @NicolasHug @thomasjpfan Do you have preferences or other proposals? See #18309 (comment). |
For |
Describe the workflow you want to enable
I like the inspect module very much. Sometimes, interpretation of a model is more natural on a different scale (e.g. log) than on the scale of the predictions.
Here some examples:
Describe your proposed solution
Add an argument
transformation
to all explainers (partial dependence, permutation importance). By default, it is None (or the identity). The user can pass e.g.np.log
to allow evaluation on the log scale.Partial dependence plot: Here, it suffices to transform the predictions before averaging them.
Permutation importance: Here, both the response and the predictions need to be transformed. The scorer must be in line with the transformation and provided by the user.
Describe alternatives you've considered, if relevant
An alternative would be to change the prediction function of the Classifier/Regressor.
The text was updated successfully, but these errors were encountered: