Skip to content
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

Prediction Explanations: Force Plots #2157

Merged
merged 14 commits into from
Jun 19, 2021
Merged

Prediction Explanations: Force Plots #2157

merged 14 commits into from
Jun 19, 2021

Conversation

chukarsten
Copy link
Contributor

@chukarsten chukarsten commented Apr 20, 2021

Addresses #1970

Single row explanations force plots:

Screen Shot 2021-04-21 at 1 19 18 PM

@codecov
Copy link

codecov bot commented Apr 20, 2021

Codecov Report

Merging #2157 (d9c88c1) into main (d9fd7b1) will increase coverage by 0.1%.
The diff coverage is 100.0%.

Impacted file tree graph

@@           Coverage Diff           @@
##            main   #2157     +/-   ##
=======================================
+ Coverage   99.7%   99.7%   +0.1%     
=======================================
  Files        281     283      +2     
  Lines      25057   25233    +176     
=======================================
+ Hits       24957   25133    +176     
  Misses       100     100             
Impacted Files Coverage Δ
...prediction_explanations/_report_creator_factory.py 100.0% <ø> (ø)
...nderstanding/prediction_explanations/explainers.py 100.0% <ø> (ø)
...ediction_explanations_tests/test_user_interface.py 100.0% <ø> (ø)
evalml/model_understanding/force_plots.py 100.0% <100.0%> (ø)
...derstanding/prediction_explanations/_algorithms.py 99.0% <100.0%> (+0.1%) ⬆️
...tanding/prediction_explanations/_user_interface.py 100.0% <100.0%> (ø)
...s/prediction_explanations_tests/test_algorithms.py 98.3% <100.0%> (+0.1%) ⬆️
.../prediction_explanations_tests/test_force_plots.py 100.0% <100.0%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d9fd7b1...d9c88c1. Read the comment docs.

@chukarsten chukarsten changed the title Force Plots WIP: Force Plots Apr 21, 2021
@chukarsten chukarsten changed the title WIP: Force Plots Force Plots Apr 21, 2021
@chukarsten chukarsten changed the title Force Plots WIP: Force Plots Apr 21, 2021
@chukarsten chukarsten force-pushed the 1970-force_plots branch 2 times, most recently from ec4e02b to 94d9241 Compare May 10, 2021 20:20
@dsherry dsherry changed the title WIP: Force Plots Prediction Explanations: Force Plots May 14, 2021
"""Computes SHAP values for each feature.

Arguments:
pipeline (PipelineBase): Trained pipeline whose predictions we want to explain with SHAP.
features (pd.DataFrame): Dataframe of features - needs to correspond to data the pipeline was fit on.
training_data (pd.DataFrame): Training data the pipeline was fit on.
For non-tree estimators, we need a sample of training data for the KernelSHAP algorithm.
return_explainer (bool): Whether to return the explainer used in the SHAP computation.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intent behind this is to calculate the expected value.

Comment on lines 194 to 191
for d in data:
if "expected_value" in d.keys():
del(d["expected_value"])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the similar style as drill down.

Copy link
Contributor

@freddyaboulton freddyaboulton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chukarsten Thank you for making the changes! I think one clean-up I'd like to do is remove the _include_expected_value parameter since it's not used by the forceplot code and it doesn't seem to change the output of the explainers.

I left a comment about adding some tests for pipelines that use OHE/Text Featurizers so that we check the features are aggregated. Let me know what you think about this change.

I also think there may be a bug with the jupyter display? The following code raises TypeError: Object of type Timestamp is not JSON serializable:

from evalml.demos import load_fraud
from evalml.pipelines import BinaryClassificationPipeline
from evalml.model_understanding import explain_predictions
from evalml.model_understanding.force_plots import graph_force_plot
import pytest


X, y = load_fraud(1000)

pipeline = BinaryClassificationPipeline(["Text Featurization Component", "DateTime Featurization Component",
                                         "One Hot Encoder", "Random Forest Classifier"])
pipeline.fit(X, y)

results = graph_force_plot(pipeline, rows_to_explain=[1],
                           training_data=X, y=y)

for result in results:
    for cls in result:
        print("Class:", cls)
            display(result[cls]["plot"])

image

I think the issue is that the input features are timestamps:

image

I say we don't block merge on that bug though cause it's coming from the display call. My hypothesis is that it might work if users use their own code to display the data from force_plot. I think we should file a spike issue to investigate further. Let me know what you think.

@chukarsten chukarsten force-pushed the 1970-force_plots branch 3 times, most recently from 4f7911b to 9cb264d Compare June 8, 2021 18:16
# for positive class
expected_value = explainer.expected_value[1]
except IndexError:
expected_value = explainer.expected_value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have test coverage for this logic?

Copy link
Contributor

@dsherry dsherry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chukarsten looking good to me :) left a couple questions

Copy link
Contributor

@bchen1116 bchen1116 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! Left a few questions and clean-up comments.

]
},
{
"cell_type": "code",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: empty cell

"for idx, result in enumerate(results):\n",
" print(\"Row:\", idx)\n",
" for cls in result:\n",
" print(\"Class:\", cls)\n",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How long does this take? Can we limit it to only doing the force plots for a few columns rather than all? Our docs take a while to build already

'shap_values': [0.05, 0.03, 0.02],
'plot': AdditiveForceVisualizer}]

Raises:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I like this

y=y,
matplotlib=False,
)
assert not initjs.called
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference between this and initjs.assert_called()?


for result in results:
class_labels = result.keys()
assert len(class_labels) == 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we assert len(class_labels)==1 here? Does this imply that there's only 1 class we're doing this for on regression pipelines?

@chukarsten chukarsten merged commit 963c66b into main Jun 19, 2021
@chukarsten chukarsten deleted the 1970-force_plots branch June 19, 2021 13:59
@chukarsten chukarsten mentioned this pull request Jun 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants