-
Notifications
You must be signed in to change notification settings - Fork 10
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
explainability: new module #44
base: main
Are you sure you want to change the base?
Conversation
JochenSiegWork
commented
Jul 5, 2024
bf9714d
to
3869edb
Compare
cdbece2
to
21a13bf
Compare
9d236b9
to
d6d880e
Compare
- Add proof of concept for Explainer class and explanation data structures to express explanations for feature vectors and molecules. - Add Christian W. Feldmanns visualization code for shap weighted heatmaps of the molecular structure.
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.
- move to experimental
- only ignorer errors where required.
Overall this is a lot to look through and my brain started to nope out...
I think we can leave it as is and improve later. I still think the text below the explanations are confusing.
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.
Sorry still haven't finished everything. Just submitting a WIP
return feature_matrix | ||
|
||
|
||
def _convert_to_array(value: Any) -> npt.NDArray[np.float64]: |
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.
I think we could use numpy.atleast_1d instead.
return atom_weights | ||
|
||
|
||
ShapExplanation: TypeAlias = list[ |
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.
If I read this correctly TypeAlias
is deprecated https://docs.python.org/3/library/typing.html#typing.TypeAlias
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.
Maybe:
ShapExplanation = Sequence[SHAPFeatureExplanation | SHAPFeatureAndAtomExplanation]
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.
If its obvious some varaibles aren't required to be explicitly typed.
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.
Also the name reads to me like this was an implemented class. Maybe ExplanationList or something like this?
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.
Notebook: After cell [16]:
We hypothesis -> We hypothesi(z/s)e?
raise ValueError("Value is not a scalar or numpy array.") | ||
|
||
|
||
def _get_prediction_function(pipeline: Pipeline | BaseEstimator) -> Any: |
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.
-> Callable[[npt.Arraylike], npt.Arraylike]
return atom_weights | ||
|
||
|
||
ShapExplanation: TypeAlias = list[ |
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.
Maybe:
ShapExplanation = Sequence[SHAPFeatureExplanation | SHAPFeatureAndAtomExplanation]
return atom_weights | ||
|
||
|
||
ShapExplanation: TypeAlias = list[ |
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.
If its obvious some varaibles aren't required to be explicitly typed.
|
||
# determine type of returned explanation | ||
featurization_element = self.featurization_subpipeline.steps[-1][1] # type: ignore[union-attr] | ||
self.return_element_type_: type[ |
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.
type hints for class/instance variables should be typed outside of functions. It would be best to do this above the init function.
return atom_weights | ||
|
||
|
||
ShapExplanation: TypeAlias = list[ |
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.
Also the name reads to me like this was an implemented class. Maybe ExplanationList or something like this?
import shap | ||
from scipy.sparse import issparse, spmatrix | ||
from sklearn.base import BaseEstimator | ||
from typing_extensions import override |
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.
better use typing.override
self.values = np.zeros((self.x_res, self.y_res)) | ||
|
||
@property | ||
def dx(self) -> float: |
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.
since dx and dy are repeatedly called, would it make sense to just return self._dx or self._dy?
We make x_lim, y_lim x_res, and y_res properties and when the setter is called, we appt self._dx and self._dy.
y_lim: Sequence[float], | ||
x_res: int, | ||
y_res: int, | ||
): |
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.
allow to pass functions during init
if isinstance(explainer, SHAPTreeExplainer) and isinstance( | ||
estimator, GradientBoostingClassifier | ||
): | ||
# there is currently a bug in SHAP's TreeExplainer for GradientBoostingClassifier |
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.
maybe log a warning or info so me might remember this :D