Dive into XAI widgets with Streamlit Components

Youchun Zhang
xaipient
Published in
8 min readSep 22, 2020

Continuing from our previous post on the attribution heatmap component, in this post we will showcase a few more XAI widgets we built at XaiPient using Streamlit.

What are XAI widgets

Each of our Explainable AI (XAI) widgets presents a different perspective of ML model behavior, and these could benefit stakeholders interacting with, impacted by, or developing those models. For example model developers can use these as a debugging aid and identify flaws or confirm that their models are working as expected. Similarly, widgets with human-friendly narrative and visual presentation can convey the key aspects of models and predictions to business users, customers, regulators or domain experts.

XaiPient Product Concept

Let us look at the example model trained on the German Credit Risk dataset again. For a loan applicant x, the model F predicts their probability F(x) of being a good credit risk. Suppose there is a dataset D of applicants (represented as a table of attributes of those applicants), and a user of our system wants to understand how the model F behaves on D globally, as well as locally on a specific x in D. In this post we will walk through how we could realize the following user experience using our XAI widgets:

  • Show a KPI card summarizing the total number of cases scored by the model and top factors impacting these cases in aggregate.
  • Show a selectable attribution table of all cases in D, where each row is a case x in D, and the columns are the features (attributes) of the cases in D, and a special column showing the model score F(x) for each x in D. Also in each row x, we’d like to represent the attributions of each feature using heatmap colors (as shown in the previous post). We’d like to also allow the user to click on a row in the prediction table to select that specific case for further analysis.
  • Finally, show a simple high-precision decision rule that characterizes a large number of cases similar to the case selected in the prediction table. We call this a decision justification widget: it shows that the model’s decision on the selected example x is part of a larger pattern among similar cases. Such an explanation can allow domain experts to easily vet a model and determine whether it accords with their intuition.

A specific realization of the above components is shown in the next three figures.

KPI Card Mockup
Selectable Attribution Table Mockup
Decision Justification Mockup

So how can we build these components with Streamlit? Starting from version 0.63, Streamlit can render Javascript and HTML components in the apps. This allows us to customize the interface further the way we need for explainable AI. Streamlit supports two types of components:

  • Static Component — using non-interactive HTML code, for example our KPI widget and the decision justification widget;
  • Bi-directional component — these are interactive components, for example the above selectable attribution table requires the Streamlit app to talk to the table in the frontend code.

Before diving into the details, here are the development dependencies:

Python 3.6+Streamlit 0.63+nodejsnpm or yarn

Static Component

Consider first the non-interactive components. We will start with using the following packages:

import streamlit as stimport streamlit.components.v1 as components

The first component we are building is the KPI card with two metrics: the total number of cases scored by the model and the top factors impacting these aggregate cases. You can start defining the variables and constructing an HTML code snippet as a Python string (you may want to test the HTML before adding it to the python file). The HTML codes in this string will be rendered in an iframe.

We will add the Google Font dependency to the head of this HTML document. Then we can specify the style for the wrapper div: it will use Open Sans as the font, and its layout will be a flex box with flex-direction: rows. This will help us to place the child divs in columns easily.

Next, we will add two columns to this flex box: one for the number of cases, and another for the top factor. Both columns will pull the variable values we defined before constructing this HTML snippet.

With streamlit.components.v1.html(), it is easy to directly implement a custom piece of HTML into an existing Streamlit app. You can fine tune the size of the component by specifying the height.

components.html(kpi_html, height=80)

Because the component.html method can render any HTML code, you can use all the data structures, control flow, and syntactic sugar in the Python language to construct the HTML string. For example, other than the “total case” and “top factors”, our third component — the decision justification widget visualizes a series of feature data (saved in a Python dictionary) and add them to the same method.

The list_html variable acts as a temporary buffer for the HTML codes for this part. We will use a for loop to iterate over the feature_data dictionary and add a div for each value and key pair to this buffer (The feature names and values are hardcoded in this example, but in an actual application these would be obtained from our explanations API).

After that we will set up the wrapper and some introduction text in the full_html variable. The HTML snippet in the list_html variable is added to a flex box with flex-direction:column style so that each feature item will be rendered as a row.

Here are the widgets:

KPI Card + Decision Justification Widget

Bi-directional Component

Streamlit also allows us to build a component that can utilize the existing functionality of react js widget. This enables more interaction between your python script and the react js widget.

For the selectable attribution table, we would like this table to have sorting and row selection interactivity. The background color of each cell will be rendered according to the attribution of the corresponding feature, as we showed in the previous post.

We can start with one of the Streamlit component templates in the component-template GitHub repo.

Initialize and run the frontend:

$ cd SelectableDataTable/frontend$ npm install $ npm run start

Run the Streamlit app:

$ cd SelectableDataTable$ streamlit run selectable_data_table.py

If all is successful, you will see a table with selectable rows.

Streamlit Example Code

Configure the Attribution Heatmap Styling

The example code has already enabled the functionality to select any row in a material ui react table and return the selected states. We will need to add more functionalities — sorting, the attribution heatmap styling, and switching the grid to a dark theme.

You can keep the component name and the folder path as what it is. In the code below, we will rename the component/function name and the folder path to AttributionHeatmapTable.

First add the import dependencies to the file /frontend/src/AttributionHeatmapTable.tsx

Create a new theme with specified color code and font family

The main interactivity is currently specified in the AttributionHeatmapTable function:

Inside the AttributionHeatmapTable function, add the following code after the columns and rows definition:

We will define an inner function CustomFormat to handle the conditional formatting logic. This inner function is a callback function that will be called in the table rendering process.

We will read the attribution data from the other table we serialized to the frontend (fmtTable). It is a Pandas DataFrame in the backend, serialized as an Apache Arrow table by default. We will need to call the .dataTable.toArray() method to convert it to a JavaScript 2D array.

We will then calculate the row index and the column index to locate the corresponding attribution value from the 2D array. This logic can be improved to be more robust. It gets the row and column indexes from the callback parameter cell. We will get the attribution value from the fmtTable and return differently styled span elements. The table rendering process will apply the style in the returned element to each cell.

And the return should be

It results in the following

Selectable Attribution Table

Local Test

Now open the main .py file. We will add a new pandas DataFrame with the feature data to the input and test how the component works locally.

Package & Install

To package the components, here are the steps:

  1. Follow the official example component template folder structure
  2. Include setup.py and the MANIFEST.in file in the folder root path
  3. Make sure that the build path in the MANIFIEST.in file is correct so that the frontend code can be packaged
  4. Rename the main .py file to __init__.py
  5. In the __init__.py, switch the _RELEASE tag to true

Also, please make sure the following code is included in the __init__.py

Finally, generate a wheel file or publish it to PyPI.

With a local wheel file, you can install the component with pip install.

$ pip install streamlit_custom_component.whl

Theming

You may find that most of our screenshots are set up with a customized dark theme. We wanted to utilize dark background when telling a story to our client with a stronger impact. Currently, Streamlit does not offer the option to customize the app styling; therefore, most of the changes we made only apply to our own development environment. We are looking forward to more customization options in a future version of Streamlit.

XaiPient Font/Color System
XaiPient Design Mockup

Using Streamlit component customization can really take our product demo to the next level. There is still a lot more you can explore about Explainable AI and Design. In a future article, we will present our design principles behind these XAI widgets.

XaiPient is fundamentally re-imagining AI explainability with the human end-user in mind. Partner with us: xaipient.com. Follow us on Twitter: @XaiPient

--

--

Youchun Zhang
xaipient

UI/UX Designer at XaiPient, ME at Cornell and MFA at Parsons