Share a LIME explanation

LIME exists for one conversation: someone does not believe a prediction, and you have to show them why the model made it. That conversation almost never happens with the person who ran the notebook — it happens with a product manager, a risk reviewer, a domain expert, a regulator.

And the artifact that would settle it is sitting in a notebook cell.

from lime.lime_tabular import LimeTabularExplainer

explainer = LimeTabularExplainer(X_train.values, feature_names=features,
                                 class_names=classes, mode="classification")
exp = explainer.explain_instance(X_test.iloc[42].values, model.predict_proba,
                                 num_features=10)
exp.save_to_file("explanation.html")

save_to_file writes a self-contained document — the weight chart, the class probabilities, and for text models the document with the driving tokens highlighted.

Publish it

Drop explanation.html into Comma, or straight from the notebook:

import requests, os

requests.post(
    "https://commareports.com/api/v1/reports",
    headers={"Authorization": f"Bearer {os.environ['COMMA_API_TOKEN']}"},
    json={
        "title": "Why application 4471 was declined",
        "html": open("explanation.html").read(),
    },
).raise_for_status()

Scripts run inside a sandboxed iframe (allow-scripts, no allow-same-origin), so the hover weights, the class toggle and the text highlighting all work at the URL. See the API reference.

The interaction is the argument

A LIME explanation flattened to an image is a bar chart of feature names, and a bar chart of feature names is exactly the thing people nod at without understanding. What convinces is the interaction: switching the explained class, reading the actual feature values next to their weights, seeing which words in the document carried the classification.

That is the difference between "the model says decline" and "the model is declining this because of a feature that is a proxy for something we are not allowed to use" — which is a finding, and it only surfaces when the reviewer can poke at the thing.

Comments are the audit trail

Anchored threads put the domain expert's objection on the feature:

  • "days_since_last_contact is a proxy for channel, not risk."
  • "This instance is mislabelled in the training set — see ticket 812."

They stay attached across republishes, so when the model is retrained and the explanation regenerated at the same URL, the history of what people objected to is still there. For a model that has to be defended later, that trail is worth more than the explanation itself. See commenting on HTML.

Treat it as sensitive

An explanation contains one instance's feature values. For anything person-level that is personal data, so:

  • Set access to private or team, never link-anyone.
  • Publish the explanation for a redacted or synthetic instance when the point is the model's behaviour rather than this specific case.

See sharing & access control.

Limits

  • Entry HTML: 5 MB. A text explanation over a long document can approach it; truncate the document or reduce num_features.
  • Assets: 25 MB per file, 250 MB and 500 files total.
  • 60 requests/minute per token.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish an explanation →

Related