Closed freddyaboulton closed 3 years ago
@chukarsten I think this is doable now that #1416 got done
@chukarsten @dsherry This issue as written only mentions the OHE. I think the plan we have in place for that is pretty clear and reasonable.
But we can also apply the same plan for other components, e.g. the TextFeaturizer
and DateTimeFeaturizer
. Is aggregating the shap values for the features created by those components in scope for this issue?
I think aggregating the shap values for features created by the TextFeaturizer
makes sense because the features are not easily interpretable by humans and the names given to these features are a bit confusing.
I'm on the fence about the DateTimeFeaturizer
. I think it's pretty clear what the features created by the DateTimeFeaturizer are, e.g. date_day_of_week
, date_month
, and users may want to know how the day-of-week impacts a prediction vs the month. So I'm in favor of not aggregating those features but curious what you guys think.
@freddyaboulton I think your instincts serve you well and these additional components should be done. I would certainly err on the side of keeping the PRs smaller and limiting the scope of this one to OHE makes sense and filing discrete issues for TF and DTF make sense. Just to keep reviews manageable and to better propagate lessons learned from completion of OHE PR to the others.
Discussed the requirements with @rpeck @dsherry @chukarsten @angela97lin and @bchen1116 :
We agreed the best long term solution is to return both the aggregated and not-aggregated shap values for the features that support aggregation.
To close this issue, only the "dict" output format needs to contain the non-aggregated shap values.
I'll try to display the aggregated and non-aggregated values for the text and dataframe output formats but if it turns out to be hard I'll file a follow-up issue!
Yay on including both the aggregated and non-aggregated SHAP values!
One note, @freddyaboulton and @dsherry:
SHAP values have the nice property that if the things we're interpreting are independent in the statistical sense, the Shapley values can be added together. This is great for things like OHE, where the features are disjoint.
However, for things like DateTime we can have different subgroups of ways of feature engineering the raw column. Each of these might or might result in a group of mutually exclusive engineered columns, but the groups could overlap. In this case, I'm 97% sure we can't just add everything together. The original source feature would be over-counted. I have to sleep on this a couple of nights to really understand how Shapley values handle conditional probabilities like this...
Think of DateTime:
However, if we add all of these, the original feature will look 3x as important, or something like that.
Just like interpretability techniques like Partial Dependence plots, the independence assumption means that Shapley values assume that you can vary one feature while holding the others constant. That obviously isn't the case for these overlapping-subgroup cases.
I think we should hold off on aggregating DateTime and text feature-engineered columns until we understand this better. We meaning I intend to give this a lot of subconscious background cycles.
A sidebar, @freddyaboulton: this means that for things like DateTime I think we will probably want to support having more than one way of splitting a given feature, each of which will sum to the same aggregated Shapley value for the original feature.
@rpeck thanks for the helpful insight! I get what you mean by overlapping subgroups and I agree it's best that we hold off on aggregating them.
From short Slack discussion:
The main points here are:
Examples of what I mean:
"the_date": {
"is holiday" : {
true: 0.15,
false: 0.25
},
"day of week" : {
"Sunday": 0.00,
"Monday": 0.08,
"Tuesday": 0.08,
"Wednesday": 0.08,
"Thursday": 0.08,
"Friday": 0.08,
"Saturday": 0.00
}
}
"sex": {
"one-hot encoded": {
"male": 0.03,
"female": 0.01,
"decline_to_state": 0.02
}
}
Discussed with @freddyaboulton @chukarsten
Problems Can't access feature value for OHE-aggregated features in a general-purpose way.
Options
@freddyaboulton likes option 2. But we should discuss further before deciding.
We agreed on option 2 while we work towards option 1 in the long term!
Here are some comments from the shap package author stating that it's reasonable to sum values across features:
https://github.com/slundberg/shap/issues/282 https://github.com/slundberg/shap/issues/465 https://github.com/slundberg/shap/issues/933
Shapley values by definition are summable IF the individual values are for disjoint features.
Since they're linear, you could presumably do this for overlapping groups:
These ones just say that you can sum the components of disjoint feature groups. That of course covers OHE, but it doesn't cover the question of overlapping features coming from DateTime expansion, for example:
This one has a comment from the author that I link to below that talks about interactions that seems to support what I was saying about overlapping groups:
https://github.com/slundberg/shap/issues/933#issuecomment-564269636
He says that the effect should be quite low for interactions. However, the effect of the "intersection" term for interactions should usually be much smaller than the features themselves. This isn't true for things like day of week
being grouped with month
...
Still thinking.
Ok. So. :-)
I thought and slept on this over the weekend, and I talked over my thoughts with Dan Putlier this morning to see what he thought. The summary of that conversation is this: his intuitions about summing Shapley values for engineered features matches mine. [breathes sigh of relief]
tl;dr: We can sum all of the "leaf" generated features up to a valid Shapley value for the source feature. The behavior of overlapping subgroups of generated features is trickier and is something to attack "later".
Details:
DateTime
, where we have subgroups like DayOfWeek
and Month
that overlap, there is an issue in the subgroups. Like the OHE case, we can sum the Shapley values all of the generated columns (think of these as the leaf nodes of the decomposition) up to the source column. DayOfWeek
) covers the space and each member (e.g., isMonday
, isTuesday
, etc) is independent, we can sum those members up to a subgroup total. In other words, the Shapley value for DayOfWeek
should be valid.DayOfWeek
and Month
, we can't necessarily trust their relative values.
If a user calls any of the explain predictions functions on a pipeline that has a OHE, the resulting table will have a row for each level of a categorical variable. We should aggregate the contributions across all levels of a categorical feature into a single row in the table so that the output is more intuitive.
There are two ways to do this:
I think we're left with 1 - looks like the library author says summing is reasonable for encoded columns so it's not too bad of a plan.