Skip to content

Commit

Permalink
Add explanation notebooks (kubeflow#509)
Browse files Browse the repository at this point in the history
* Update explainer demos with new notebooks

* Add updated explanation notebooks

* Update from review comments

* clean up

* rerun income explainer notebook to see output

* removing output as plot.ly graphs don't show on github
  • Loading branch information
ukclivecox authored and k8s-ci-robot committed Nov 2, 2019
1 parent 4865e54 commit dab7a24
Show file tree
Hide file tree
Showing 10 changed files with 629 additions and 256 deletions.
76 changes: 76 additions & 0 deletions docs/samples/explanation/alibi/alibi_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import numpy as np
import requests
from alibi.datasets import fetch_adult
import pandas as pd
import plotly.graph_objects as go
from IPython.display import display, Markdown, display

def getFeatures(X,cmap):
return pd.DataFrame(X).replace(cmap).values.squeeze().tolist()

def predict(X, name, ds, svc_hostname, cluster_ip):
formData = {
'instances': X
}
headers = {}
headers["Host"] = svc_hostname
res = requests.post('http://'+cluster_ip+'/v1/models/'+name+':predict', json=formData, headers=headers)
if res.status_code == 200:
return ds.target_names[np.array(res.json()["predictions"])[0]]
else:
print("Failed with ",res.status_code)
return []

def explain(X, name, svc_hostname, cluster_ip):
formData = {
'instances': X
}
headers = {}
headers["Host"] = svc_hostname
res = requests.post('http://'+cluster_ip+'/v1/models/'+name+':explain', json=formData, headers=headers)
if res.status_code == 200:
return res.json()
else:
print("Failed with ",res.status_code)
return []

def show_bar(X, labels, title):
fig = go.Figure(go.Bar(x=X,y=labels,orientation='h',width=[0.5]))
fig.update_layout(autosize=False,width=700,height=300,
xaxis=dict(range=[0, 1]),
title_text=title,
font=dict(family="Courier New, monospace",size=18,color="#7f7f7f"
))
fig.show()


def show_feature_coverage(exp):
data = []
for idx, name in enumerate(exp["names"]):
data.append(go.Bar(name=name, x=["coverage"], y=[exp['raw']['coverage'][idx]]))
fig = go.Figure(data=data)
fig.update_layout(yaxis=dict(range=[0, 1]))
fig.show()

def show_anchors(names):
display(Markdown('# Explanation:'))
display(Markdown('## {}'.format(names)))

def show_examples(exp,fidx,ds,covered=True):
if covered:
cname = 'covered'
display(Markdown("## Examples covered by Anchors: {}".format(exp['names'][0:fidx+1])))
else:
cname = 'covered_false'
display(Markdown("## Examples not covered by Anchors: {}".format(exp['names'][0:fidx+1])))
if "feature_names" in ds:
return pd.DataFrame(exp['raw']['examples'][fidx][cname],columns=ds.feature_names)
else:
return pd.DataFrame(exp['raw']['examples'][fidx][cname])

def show_prediction(prediction):
display(Markdown('## Prediction: {}'.format(prediction)))

def show_row(X,ds):
display(pd.DataFrame(X,columns=ds.feature_names))

9 changes: 8 additions & 1 deletion docs/samples/explanation/alibi/income/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

This example uses a [US income dataset](https://archive.ics.uci.edu/ml/datasets/adult)

You can also try out the [Jupyter notebook](income_explanations.ipynb).

We can create a InferenceService with a trained sklearn predictor for this dataset and an associated model explainer. The black box explainer algorithm we will use is the Tabular version of Anchors from the [Alibi open source library](https://github.com/SeldonIO/alibi). More details on this algorithm and configuration settings that can be set can be found in the [Seldon Alibi documentation](https://docs.seldon.io/projects/alibi/en/stable/).

The InferenceService is shown below:
Expand All @@ -14,19 +16,24 @@ metadata:
spec:
default:
predictor:
minReplicas: 1
sklearn:
storageUri: "gs://seldon-models/sklearn/income/model"
resources:
requests:
cpu: 0.1
limits:
cpu: 1
explainer:
minReplicas: 1
alibi:
type: AnchorTabular
storageUri: "gs://seldon-models/sklearn/income/explainer"
resources:
requests:
cpu: 0.1
limits:
cpu: 1
```

Create this InferenceService:
Expand Down
12 changes: 10 additions & 2 deletions docs/samples/explanation/alibi/income/income.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,28 @@ apiVersion: "serving.kubeflow.org/v1alpha2"
kind: "InferenceService"
metadata:
name: "income"
namespace: default
spec:
default:
predictor:
minReplicas: 1
sklearn:
storageUri: "gs://seldon-models/sklearn/income/model"
resources:
requests:
cpu: 0.1
memory: 1Gi
limits:
cpu: 1
memory: 1Gi
explainer:
minReplicas: 1
alibi:
type: AnchorTabular
storageUri: "gs://seldon-models/sklearn/income/explainer"
resources:
requests:
cpu: 0.1

memory: 1Gi
limits:
cpu: 1
memory: 4Gi
Loading

0 comments on commit dab7a24

Please sign in to comment.