<jupyter_start><jupyter_text>XAI with SHAP for Multi-Class Classification:- Source: https://towardsdatascience.com/explainable-ai-xai-with-shap-multi-class-classification-problem-64dd30f97cea- SHAP = Shapley Addictive Explanations- How to use SHAP, analyze multi-class classification, and use it to improve the model<jupyter_code>!pip install tensorflow
!pip install matplotlib
!pip install sklearn
!pip install shap
import tensorflow as tf
import pandas as pd
from sklearn import model_selection
from sklearn.ensemble import RandomForestClassifier
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import plot_confusion_matrix
import shap
print(tf.__version__)
!ls
# Load the csv file as a data frame
df = pd.read_csv("log2.csv")
y = df.Action.copy()
x = df.drop("Action", axis=1)<jupyter_output><empty_output><jupyter_text>Model fit<jupyter_code># Create a model and fit
x_train, x_test, y_train, y_test = model_selection.train_test_split(x, y, random_state=0)

cls = RandomForestClassifier(max_depth=2, random_state=0)
cls.fit(x_train, y_train)<jupyter_output><empty_output><jupyter_text>Analyse model<jupyter_code># Check the importances of the model interact with the classes
importances = cls.feature_importances_
indices = np.argsort(importances)
features = df.columns
plt.title("Feature Importances")
plt.barh(range(len(indices)), importances[indices], color='g', align='center')
plt.yticks(range(len(indices)), [features[i] for i in indices])
plt.xlabel('Relative Importance')
plt.show()
# Confusion Matrix: Visualize the performance of the model. 
class_names = ['drop', 'allow', 'deny', 'reset-both']
disp = plot_confusion_matrix(cls, x_test, y_test, display_labels=class_names, cmap=plt.cm.Blues, xticks_rotation='vertical')<jupyter_output><empty_output><jupyter_text>Note: The model could not detect any instance from the class reset-both. The reason is, unbalanced dataset that gives low number of examples of reset both class to learn from<jupyter_code>y.value_counts()<jupyter_output><empty_output><jupyter_text>SHAP Summary Plot- SHAP values of a model's output explain how features impact the output of the model<jupyter_code># compute SHAP values
explainer = shap.TreeExplainer(cls)
shap_values = explainer.shap_values(x)
shap.summary_plot(shap_values, x.values, plot_type="bar", class_names= class_names, feature_names = x.columns)

shap.summary_plot(shap_values[1], x.values, feature_names = x.columns)
# If we pass a numpy array instead of a data frame then we
# need pass the feature names in separately
shap.dependence_plot(0, shap_values[0], x.values, feature_names=x.columns)<jupyter_output><empty_output><jupyter_text>SHAP Force Plot- Force plot gives us the explainability of a single model prediction. In this plot we can see how features contributed to the model’s prediction for a specific observation. It is very convenient to use for error analysis or for a deep understanding of a particular case<jupyter_code>shap.initjs()
i=8
shap.force_plot(explainer.expected_value[0], shap_values[0][i], x.values[i], feature_names = x.columns)<jupyter_output><empty_output><jupyter_text>From the plot we can see:- The model predict_proba value: 0.79- The base value: this is the value that would be predicted if we didn’t know any features for the current instance. The base value is the average of the model output over training datatset (explainer.expected_value in the code). In this example base value = 0.5749- The numbers on the plot arrows are the value of the feature for this instance. Elapsed Time (sec)=5 and Packets = 1- Red representing features that pushed the model score higher, and blue representing features that pushed the score lower.- The bigger the arrow, the bigger the impact of the feature on the output. The amount of decrease or increase in the impact can be seen in the x axis.- Elapsed Time of 5 seconds increases the property that the class is allow, Packets of 6.546 reduces the property value.  SHAP waterfall plot<jupyter_code>row = 8
shap.waterfall_plot(shap.Explanation(values=shap_values[0][row], 
                                              base_values=explainer.expected_value[0], data=x_test.iloc[row],  
                                         feature_names=x_test.columns.tolist()))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08372093023255814, 'fraction_numerical': 0.00813953488372093, 'mean_word_length': 5.606758832565284, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '194189', 'license': 'MIT', 'n_tokens_mistral': 1329, 'n_tokens_neox': 1289, 'n_words': 447, 'path': 'msa/xai/implementations/shap_example_random_forest.ipynb', 'repo_name': 'mnguyen0226/ai-assurance-research', 'size': '4300'}