shap/shap

BUG: TreeExplainer ignores "link" argument passed by the Explainer API

connortann opened this issue · 1 comments

The current implementation of TreeExplainer entirely ignores the link and linearize_link arguments which are passed from Explainer here:

explainers.TreeExplainer.__init__(self, self.model, self.masker, link=self.link, feature_names=self.feature_names, linearize_link=linearize_link, **kwargs)

They are currently caught by the "deprecated options" catchall, and subsequently ignored:

def __init__(
self,
model,
data=None,
model_output="raw",
feature_perturbation="interventional",
feature_names=None,
approximate=False,
**deprecated_options,
):

This seems rather concerning. It's not obvious to me where precisely the link function should be applied in TreeExplainer, if at all. As far as I can make out, the TreeExplainer uses the "model_output" inferred from the explained model rather than the user-defined "link" variable.

The link function is there since non-linear transformations of the shap values will break additivity because
$\log(x + \bar{x}) \ne \log(x) + \log(\bar{x})$. This can also be relevant for trees, e.g. here: https://github.com/shap/shap/pull/3616/files#diff-575fa6d845d524882a8ba5609d8a2c7f877844870c10aa551a67d8fa24461b05R1919.

Hmm, not sure where it should be applied, usually one hands the link over to the masker. Will need to take another look but wanted to note this here.

Edit: I guess the link function/linearized_link should be applied before checking additivity and nowhere else.