{
"cells": [
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"import warnings\n",
"warnings.filterwarnings(\"ignore\")\n",
"\n",
"from xai_agg import *\n",
"\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn.metrics import accuracy_score, roc_auc_score\n",
"from sklearn.ensemble import RandomForestClassifier\n",
"\n",
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"from IPython.core.display import display, HTML\n",
"\n",
"def display_side_by_side(dfs: list[pd.DataFrame], captions: list[str] = []):\n",
" \"\"\"Display tables side by side to save vertical space\n",
" Input:\n",
" dfs: list of pandas.DataFrame\n",
" captions: list of table captions\n",
" \"\"\"\n",
" output = \"\"\n",
" for i, df in enumerate(dfs):\n",
" caption = captions[i] if i < len(captions) else \"\"\n",
" \n",
" output += df.style.set_table_attributes(\"style='display:inline'\").set_caption(f\"{caption}\")._repr_html_()\n",
" output += \"\\xa0\\xa0\\xa0\"\n",
" display(HTML(output))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Preprocess the data\n",
"1. One-hot-encode categorical variables, making sure the one-hot-encoded column names are in the format \"[FEATURE]_[CATEGORY]\"\n",
"2. Make sure all column names are valid python identifiers"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Unnamed: 0 | \n",
" Age | \n",
" Sex | \n",
" Job | \n",
" Housing | \n",
" Saving accounts | \n",
" Checking account | \n",
" Credit amount | \n",
" Duration | \n",
" Purpose | \n",
" Credit Risk | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" 0 | \n",
" 67 | \n",
" male | \n",
" 2 | \n",
" own | \n",
" NaN | \n",
" little | \n",
" 1169 | \n",
" 6 | \n",
" radio/TV | \n",
" 1 | \n",
"
\n",
" \n",
" | 1 | \n",
" 1 | \n",
" 22 | \n",
" female | \n",
" 2 | \n",
" own | \n",
" little | \n",
" moderate | \n",
" 5951 | \n",
" 48 | \n",
" radio/TV | \n",
" 2 | \n",
"
\n",
" \n",
" | 2 | \n",
" 2 | \n",
" 49 | \n",
" male | \n",
" 1 | \n",
" own | \n",
" little | \n",
" NaN | \n",
" 2096 | \n",
" 12 | \n",
" education | \n",
" 1 | \n",
"
\n",
" \n",
" | 3 | \n",
" 3 | \n",
" 45 | \n",
" male | \n",
" 2 | \n",
" free | \n",
" little | \n",
" little | \n",
" 7882 | \n",
" 42 | \n",
" furniture/equipment | \n",
" 1 | \n",
"
\n",
" \n",
" | 4 | \n",
" 4 | \n",
" 53 | \n",
" male | \n",
" 2 | \n",
" free | \n",
" little | \n",
" little | \n",
" 4870 | \n",
" 24 | \n",
" car | \n",
" 2 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Unnamed: 0 Age Sex Job Housing Saving accounts Checking account \\\n",
"0 0 67 male 2 own NaN little \n",
"1 1 22 female 2 own little moderate \n",
"2 2 49 male 1 own little NaN \n",
"3 3 45 male 2 free little little \n",
"4 4 53 male 2 free little little \n",
"\n",
" Credit amount Duration Purpose Credit Risk \n",
"0 1169 6 radio/TV 1 \n",
"1 5951 48 radio/TV 2 \n",
"2 2096 12 education 1 \n",
"3 7882 42 furniture/equipment 1 \n",
"4 4870 24 car 2 "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Unnamed: 0 | \n",
" Age | \n",
" Job | \n",
" Credit amount | \n",
" Duration | \n",
" Credit Risk | \n",
"
\n",
" \n",
" \n",
" \n",
" | count | \n",
" 954.000000 | \n",
" 954.000000 | \n",
" 954.000000 | \n",
" 954.000000 | \n",
" 954.000000 | \n",
" 954.000000 | \n",
"
\n",
" \n",
" | mean | \n",
" 476.500000 | \n",
" 35.501048 | \n",
" 1.909853 | \n",
" 3279.112159 | \n",
" 20.780922 | \n",
" 1.302935 | \n",
"
\n",
" \n",
" | std | \n",
" 275.540378 | \n",
" 11.379668 | \n",
" 0.649681 | \n",
" 2853.315158 | \n",
" 12.046483 | \n",
" 0.459768 | \n",
"
\n",
" \n",
" | min | \n",
" 0.000000 | \n",
" 19.000000 | \n",
" 0.000000 | \n",
" 250.000000 | \n",
" 4.000000 | \n",
" 1.000000 | \n",
"
\n",
" \n",
" | 25% | \n",
" 238.250000 | \n",
" 27.000000 | \n",
" 2.000000 | \n",
" 1360.250000 | \n",
" 12.000000 | \n",
" 1.000000 | \n",
"
\n",
" \n",
" | 50% | \n",
" 476.500000 | \n",
" 33.000000 | \n",
" 2.000000 | \n",
" 2302.500000 | \n",
" 18.000000 | \n",
" 1.000000 | \n",
"
\n",
" \n",
" | 75% | \n",
" 714.750000 | \n",
" 42.000000 | \n",
" 2.000000 | \n",
" 3975.250000 | \n",
" 24.000000 | \n",
" 2.000000 | \n",
"
\n",
" \n",
" | max | \n",
" 953.000000 | \n",
" 75.000000 | \n",
" 3.000000 | \n",
" 18424.000000 | \n",
" 72.000000 | \n",
" 2.000000 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Unnamed: 0 Age Job Credit amount Duration \\\n",
"count 954.000000 954.000000 954.000000 954.000000 954.000000 \n",
"mean 476.500000 35.501048 1.909853 3279.112159 20.780922 \n",
"std 275.540378 11.379668 0.649681 2853.315158 12.046483 \n",
"min 0.000000 19.000000 0.000000 250.000000 4.000000 \n",
"25% 238.250000 27.000000 2.000000 1360.250000 12.000000 \n",
"50% 476.500000 33.000000 2.000000 2302.500000 18.000000 \n",
"75% 714.750000 42.000000 2.000000 3975.250000 24.000000 \n",
"max 953.000000 75.000000 3.000000 18424.000000 72.000000 \n",
"\n",
" Credit Risk \n",
"count 954.000000 \n",
"mean 1.302935 \n",
"std 0.459768 \n",
"min 1.000000 \n",
"25% 1.000000 \n",
"50% 1.000000 \n",
"75% 2.000000 \n",
"max 2.000000 "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"RangeIndex: 954 entries, 0 to 953\n",
"Data columns (total 11 columns):\n",
" # Column Non-Null Count Dtype \n",
"--- ------ -------------- ----- \n",
" 0 Unnamed: 0 954 non-null int64 \n",
" 1 Age 954 non-null int64 \n",
" 2 Sex 954 non-null object\n",
" 3 Job 954 non-null int64 \n",
" 4 Housing 954 non-null object\n",
" 5 Saving accounts 779 non-null object\n",
" 6 Checking account 576 non-null object\n",
" 7 Credit amount 954 non-null int64 \n",
" 8 Duration 954 non-null int64 \n",
" 9 Purpose 954 non-null object\n",
" 10 Credit Risk 954 non-null int64 \n",
"dtypes: int64(6), object(5)\n",
"memory usage: 82.1+ KB\n"
]
},
{
"data": {
"text/plain": [
"None"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Unique values of the categorical features:\n",
"\t- Sex: ['male' 'female']\n",
"\t- Housing: ['own' 'free' 'rent']\n",
"\t- Saving accounts: [nan 'little' 'quite rich' 'rich' 'moderate']\n",
"\t- Checking account: ['little' 'moderate' nan 'rich']\n",
"\t- Purpose: ['radio/TV' 'education' 'furniture/equipment' 'car' 'business'\n",
" 'domestic appliances' 'repairs' 'vacation/others']\n"
]
}
],
"source": [
"original_data = pd.read_csv('../data/german_credit_data_updated.csv')\n",
"\n",
"# Dataset overview - German Credit Risk (from Kaggle):\n",
"# 1. Age (numeric)\n",
"# 2. Sex (text: male, female)\n",
"# 3. Job (numeric: 0 - unskilled and non-resident, 1 - unskilled and resident, 2 - skilled, 3 - highly skilled)\n",
"# 4. Housing (text: own, rent, or free)\n",
"# 5. Saving accounts (text - little, moderate, quite rich, rich)\n",
"# 6. Checking account (numeric, in DM - Deutsch Mark)\n",
"# 7. Credit amount (numeric, in DM)\n",
"# 8. Duration (numeric, in month)\n",
"# 9. Purpose (text: car, furniture/equipment, radio/TV, domestic appliances, repairs, education, business, vacation/others)\n",
"\n",
"display(original_data.head())\n",
"display(original_data.describe())\n",
"display(original_data.info())\n",
"\n",
"# Display the unique values of the categorical features:\n",
"print('Unique values of the categorical features:')\n",
"for col in original_data.select_dtypes(include='object'):\n",
" print(f'\\t- {col}: {original_data[col].unique()}')"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Categorical features: Index(['Sex', 'Job', 'Housing', 'Saving accounts', 'Checking account',\n",
" 'Purpose'],\n",
" dtype='object')\n",
"Numerical features: Index(['Age', 'Credit amount', 'Duration'], dtype='object')\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Age | \n",
" Credit_amount | \n",
" Duration | \n",
" Credit_Risk | \n",
" Sex_female | \n",
" Sex_male | \n",
" Job_highlyskilled | \n",
" Job_skilled | \n",
" Job_unskilled_nonresident | \n",
" Job_unskilled_resident | \n",
" ... | \n",
" Checking_account_none | \n",
" Checking_account_rich | \n",
" Purpose_business | \n",
" Purpose_car | \n",
" Purpose_domestic_appliances | \n",
" Purpose_education | \n",
" Purpose_furniture_equipment | \n",
" Purpose_radio_TV | \n",
" Purpose_repairs | \n",
" Purpose_vacation_others | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" 67 | \n",
" 1169 | \n",
" 6 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" ... | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" | 1 | \n",
" 22 | \n",
" 5951 | \n",
" 48 | \n",
" 1 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" ... | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" | 2 | \n",
" 49 | \n",
" 2096 | \n",
" 12 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" ... | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" | 3 | \n",
" 45 | \n",
" 7882 | \n",
" 42 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" ... | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" | 4 | \n",
" 53 | \n",
" 4870 | \n",
" 24 | \n",
" 1 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" ... | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
"
\n",
"
5 rows × 30 columns
\n",
"
"
],
"text/plain": [
" Age Credit_amount Duration Credit_Risk Sex_female Sex_male \\\n",
"0 67 1169 6 0 0 1 \n",
"1 22 5951 48 1 1 0 \n",
"2 49 2096 12 0 0 1 \n",
"3 45 7882 42 0 0 1 \n",
"4 53 4870 24 1 0 1 \n",
"\n",
" Job_highlyskilled Job_skilled Job_unskilled_nonresident \\\n",
"0 0 1 0 \n",
"1 0 1 0 \n",
"2 0 0 0 \n",
"3 0 1 0 \n",
"4 0 1 0 \n",
"\n",
" Job_unskilled_resident ... Checking_account_none Checking_account_rich \\\n",
"0 0 ... 0 0 \n",
"1 0 ... 0 0 \n",
"2 1 ... 1 0 \n",
"3 0 ... 0 0 \n",
"4 0 ... 0 0 \n",
"\n",
" Purpose_business Purpose_car Purpose_domestic_appliances \\\n",
"0 0 0 0 \n",
"1 0 0 0 \n",
"2 0 0 0 \n",
"3 0 0 0 \n",
"4 0 1 0 \n",
"\n",
" Purpose_education Purpose_furniture_equipment Purpose_radio_TV \\\n",
"0 0 0 1 \n",
"1 0 0 1 \n",
"2 1 0 0 \n",
"3 0 1 0 \n",
"4 0 0 0 \n",
"\n",
" Purpose_repairs Purpose_vacation_others \n",
"0 0 0 \n",
"1 0 0 \n",
"2 0 0 \n",
"3 0 0 \n",
"4 0 0 \n",
"\n",
"[5 rows x 30 columns]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"RangeIndex: 954 entries, 0 to 953\n",
"Data columns (total 30 columns):\n",
" # Column Non-Null Count Dtype\n",
"--- ------ -------------- -----\n",
" 0 Age 954 non-null int64\n",
" 1 Credit_amount 954 non-null int64\n",
" 2 Duration 954 non-null int64\n",
" 3 Credit_Risk 954 non-null int64\n",
" 4 Sex_female 954 non-null int64\n",
" 5 Sex_male 954 non-null int64\n",
" 6 Job_highlyskilled 954 non-null int64\n",
" 7 Job_skilled 954 non-null int64\n",
" 8 Job_unskilled_nonresident 954 non-null int64\n",
" 9 Job_unskilled_resident 954 non-null int64\n",
" 10 Housing_free 954 non-null int64\n",
" 11 Housing_own 954 non-null int64\n",
" 12 Housing_rent 954 non-null int64\n",
" 13 Saving_accounts_little 954 non-null int64\n",
" 14 Saving_accounts_moderate 954 non-null int64\n",
" 15 Saving_accounts_none 954 non-null int64\n",
" 16 Saving_accounts_quite_rich 954 non-null int64\n",
" 17 Saving_accounts_rich 954 non-null int64\n",
" 18 Checking_account_little 954 non-null int64\n",
" 19 Checking_account_moderate 954 non-null int64\n",
" 20 Checking_account_none 954 non-null int64\n",
" 21 Checking_account_rich 954 non-null int64\n",
" 22 Purpose_business 954 non-null int64\n",
" 23 Purpose_car 954 non-null int64\n",
" 24 Purpose_domestic_appliances 954 non-null int64\n",
" 25 Purpose_education 954 non-null int64\n",
" 26 Purpose_furniture_equipment 954 non-null int64\n",
" 27 Purpose_radio_TV 954 non-null int64\n",
" 28 Purpose_repairs 954 non-null int64\n",
" 29 Purpose_vacation_others 954 non-null int64\n",
"dtypes: int64(30)\n",
"memory usage: 223.7 KB\n"
]
},
{
"data": {
"text/plain": [
"None"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"preprocessed_data = original_data.copy()\n",
"\n",
"# For savings and checking accounts, we will replace the missing values with 'none':\n",
"preprocessed_data['Saving accounts'].fillna('none', inplace=True)\n",
"preprocessed_data['Checking account'].fillna('none', inplace=True)\n",
"\n",
"# Dropping index column:\n",
"preprocessed_data.drop(columns=['Unnamed: 0'], inplace=True)\n",
"\n",
"# Using pd.dummies to one-hot-encode the categorical features\n",
"preprocessed_data[\"Job\"] = preprocessed_data[\"Job\"].map({0: 'unskilled_nonresident', 1: 'unskilled_resident',\n",
" 2: 'skilled', 3: 'highlyskilled'})\n",
"\n",
"categorical_features = preprocessed_data.select_dtypes(include='object').columns\n",
"numerical_features = preprocessed_data.select_dtypes(include='number').columns.drop('Credit Risk')\n",
"print(f'Categorical features: {categorical_features}')\n",
"print(f'Numerical features: {numerical_features}')\n",
"\n",
"preprocessed_data = pd.get_dummies(preprocessed_data, columns=categorical_features, dtype='int64')\n",
"\n",
"# Remapping the target variable to 0 and 1:\n",
"preprocessed_data['Credit Risk'] = preprocessed_data['Credit Risk'].map({1: 0, 2: 1})\n",
"\n",
"# Make sure all column names are valid python identifiers (important for pd.query() calls):\n",
"preprocessed_data.columns = preprocessed_data.columns.str.replace(' ', '_')\n",
"preprocessed_data.columns = preprocessed_data.columns.str.replace('/', '_')\n",
"\n",
"display(preprocessed_data.head())\n",
"display(preprocessed_data.info())"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"y = preprocessed_data['Credit_Risk']\n",
"X = preprocessed_data.drop(columns='Credit_Risk')\n",
"\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Accuracy: 0.7696335078534031\n",
"ROC AUC: 0.6830357142857143\n"
]
}
],
"source": [
"clf = RandomForestClassifier(random_state=42)\n",
"clf.fit(X_train, y_train)\n",
"\n",
"y_pred = clf.predict(X_test)\n",
"\n",
"print(f'Accuracy: {accuracy_score(y_test, y_pred)}')\n",
"print(f'ROC AUC: {roc_auc_score(y_test, y_pred)}')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Applying the Aggregate Explainer"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"agg_explainer = AggregatedExplainer(\n",
" explainer_types=[LimeWrapper, ShapTabularTreeWrapper, AnchorWrapper], # Wrapped explainers whose explanations will be aggregated\n",
" model=clf, X_train=X_train, categorical_feature_names=categorical_features, # Model and training data\n",
" metrics=['nrc', 'sensitivity_spearman', 'faithfulness_corr'], # Metrics to be considered for the aggregation\n",
" noise_gen_args={'encoding_dim': 5, 'epochs': 500}, # Arguments passed to the autoencoder noisy data generator\n",
" evaluator_args={\"debug\": False} # Arguments passed to the evaluator class \n",
") "
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
" Feature importance scores:\n",
" \n",
" \n",
" | | \n",
" feature | \n",
" score | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" Duration | \n",
" 0.809114 | \n",
"
\n",
" \n",
" | 1 | \n",
" Purpose_furniture_equipment | \n",
" 0.568681 | \n",
"
\n",
" \n",
" | 2 | \n",
" Checking_account_none | \n",
" 0.497863 | \n",
"
\n",
" \n",
" | 3 | \n",
" Age | \n",
" 0.232698 | \n",
"
\n",
" \n",
" | 4 | \n",
" Checking_account_little | \n",
" 0.111593 | \n",
"
\n",
" \n",
" | 5 | \n",
" Credit_amount | \n",
" 0.041399 | \n",
"
\n",
" \n",
" | 6 | \n",
" Checking_account_moderate | \n",
" 0.039992 | \n",
"
\n",
" \n",
" | 7 | \n",
" Housing_free | \n",
" 0.027987 | \n",
"
\n",
" \n",
" | 8 | \n",
" Sex_female | \n",
" 0.018932 | \n",
"
\n",
" \n",
" | 9 | \n",
" Saving_accounts_moderate | \n",
" 0.015219 | \n",
"
\n",
" \n",
" | 10 | \n",
" Sex_male | \n",
" 0.014925 | \n",
"
\n",
" \n",
" | 11 | \n",
" Job_highlyskilled | \n",
" 0.009129 | \n",
"
\n",
" \n",
" | 12 | \n",
" Housing_own | \n",
" 0.008308 | \n",
"
\n",
" \n",
" | 13 | \n",
" Purpose_car | \n",
" 0.008169 | \n",
"
\n",
" \n",
" | 14 | \n",
" Saving_accounts_little | \n",
" 0.006912 | \n",
"
\n",
" \n",
" | 15 | \n",
" Purpose_radio_TV | \n",
" 0.006733 | \n",
"
\n",
" \n",
" | 16 | \n",
" Job_skilled | \n",
" 0.006117 | \n",
"
\n",
" \n",
" | 17 | \n",
" Saving_accounts_none | \n",
" 0.006015 | \n",
"
\n",
" \n",
" | 18 | \n",
" Job_unskilled_resident | \n",
" 0.005921 | \n",
"
\n",
" \n",
" | 19 | \n",
" Housing_rent | \n",
" 0.004658 | \n",
"
\n",
" \n",
" | 20 | \n",
" Job_unskilled_nonresident | \n",
" 0.004482 | \n",
"
\n",
" \n",
" | 21 | \n",
" Saving_accounts_quite_rich | \n",
" 0.002573 | \n",
"
\n",
" \n",
" | 22 | \n",
" Purpose_education | \n",
" 0.002123 | \n",
"
\n",
" \n",
" | 23 | \n",
" Purpose_repairs | \n",
" 0.001111 | \n",
"
\n",
" \n",
" | 24 | \n",
" Purpose_business | \n",
" 0.000986 | \n",
"
\n",
" \n",
" | 25 | \n",
" Purpose_vacation_others | \n",
" 0.000942 | \n",
"
\n",
" \n",
" | 26 | \n",
" Checking_account_rich | \n",
" 0.000937 | \n",
"
\n",
" \n",
" | 27 | \n",
" Saving_accounts_rich | \n",
" 0.000645 | \n",
"
\n",
" \n",
" | 28 | \n",
" Purpose_domestic_appliances | \n",
" 0.000545 | \n",
"
\n",
" \n",
"
\n",
" \n",
"\n",
" Feature importance ranking:\n",
" \n",
" \n",
" | | \n",
" feature | \n",
" rank | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" Duration | \n",
" 1 | \n",
"
\n",
" \n",
" | 1 | \n",
" Purpose_furniture_equipment | \n",
" 2 | \n",
"
\n",
" \n",
" | 2 | \n",
" Checking_account_none | \n",
" 3 | \n",
"
\n",
" \n",
" | 3 | \n",
" Age | \n",
" 4 | \n",
"
\n",
" \n",
" | 4 | \n",
" Checking_account_little | \n",
" 5 | \n",
"
\n",
" \n",
" | 5 | \n",
" Credit_amount | \n",
" 6 | \n",
"
\n",
" \n",
" | 6 | \n",
" Checking_account_moderate | \n",
" 6 | \n",
"
\n",
" \n",
" | 7 | \n",
" Housing_free | \n",
" 7 | \n",
"
\n",
" \n",
" | 8 | \n",
" Sex_female | \n",
" 7 | \n",
"
\n",
" \n",
" | 9 | \n",
" Saving_accounts_moderate | \n",
" 8 | \n",
"
\n",
" \n",
" | 10 | \n",
" Sex_male | \n",
" 8 | \n",
"
\n",
" \n",
" | 11 | \n",
" Job_highlyskilled | \n",
" 8 | \n",
"
\n",
" \n",
" | 12 | \n",
" Housing_own | \n",
" 8 | \n",
"
\n",
" \n",
" | 13 | \n",
" Purpose_car | \n",
" 8 | \n",
"
\n",
" \n",
" | 14 | \n",
" Saving_accounts_little | \n",
" 8 | \n",
"
\n",
" \n",
" | 15 | \n",
" Purpose_radio_TV | \n",
" 8 | \n",
"
\n",
" \n",
" | 16 | \n",
" Job_skilled | \n",
" 8 | \n",
"
\n",
" \n",
" | 17 | \n",
" Saving_accounts_none | \n",
" 8 | \n",
"
\n",
" \n",
" | 18 | \n",
" Job_unskilled_resident | \n",
" 8 | \n",
"
\n",
" \n",
" | 19 | \n",
" Housing_rent | \n",
" 9 | \n",
"
\n",
" \n",
" | 20 | \n",
" Job_unskilled_nonresident | \n",
" 9 | \n",
"
\n",
" \n",
" | 21 | \n",
" Saving_accounts_quite_rich | \n",
" 9 | \n",
"
\n",
" \n",
" | 22 | \n",
" Purpose_education | \n",
" 9 | \n",
"
\n",
" \n",
" | 23 | \n",
" Purpose_repairs | \n",
" 9 | \n",
"
\n",
" \n",
" | 24 | \n",
" Purpose_business | \n",
" 9 | \n",
"
\n",
" \n",
" | 25 | \n",
" Purpose_vacation_others | \n",
" 9 | \n",
"
\n",
" \n",
" | 26 | \n",
" Checking_account_rich | \n",
" 9 | \n",
"
\n",
" \n",
" | 27 | \n",
" Saving_accounts_rich | \n",
" 9 | \n",
"
\n",
" \n",
" | 28 | \n",
" Purpose_domestic_appliances | \n",
" 9 | \n",
"
\n",
" \n",
"
\n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Apply the aggregate explainer on a sample instance:\n",
"sample_idx = 0\n",
"agg_explanation = agg_explainer.explain_instance(X_test.iloc[sample_idx])\n",
"\n",
"display_side_by_side([agg_explanation, get_ranked_explanation(agg_explanation)], captions=['Feature importance scores:', 'Feature importance ranking:'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Get information on the aggregate explainer's last explanation\n",
"With the `get_last_explanation_info()` method, you can get a dataframe that contains each of the aggregated explanation models' performances on each of the metrics used to evaluate them. You are also given the weight each explanation model got from the MCDM algorithm, which is passed on to the rank aggregation step."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" nrc | \n",
" sensitivity_spearman | \n",
" faithfulness_corr | \n",
" weight | \n",
"
\n",
" \n",
" \n",
" \n",
" | LimeWrapper | \n",
" 42.504547 | \n",
" 0.839113 | \n",
" 0.110158 | \n",
" 0.533547 | \n",
"
\n",
" \n",
" | ShapTabularTreeWrapper | \n",
" 43.531226 | \n",
" 0.964205 | \n",
" 0.167030 | \n",
" 0.438026 | \n",
"
\n",
" \n",
" | AnchorWrapper | \n",
" 42.491709 | \n",
" 0.570668 | \n",
" 0.448899 | \n",
" 0.585786 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" nrc sensitivity_spearman faithfulness_corr \\\n",
"LimeWrapper 42.504547 0.839113 0.110158 \n",
"ShapTabularTreeWrapper 43.531226 0.964205 0.167030 \n",
"AnchorWrapper 42.491709 0.570668 0.448899 \n",
"\n",
" weight \n",
"LimeWrapper 0.533547 \n",
"ShapTabularTreeWrapper 0.438026 \n",
"AnchorWrapper 0.585786 "
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"agg_explainer.get_last_explanation_info()"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
" LIME explanation:\n",
" \n",
" \n",
" | | \n",
" feature | \n",
" score | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" Checking_account_none | \n",
" 0.060765 | \n",
"
\n",
" \n",
" | 1 | \n",
" Duration | \n",
" 0.056665 | \n",
"
\n",
" \n",
" | 2 | \n",
" Checking_account_little | \n",
" 0.035393 | \n",
"
\n",
" \n",
" | 3 | \n",
" Age | \n",
" 0.028167 | \n",
"
\n",
" \n",
" | 4 | \n",
" Checking_account_moderate | \n",
" 0.017343 | \n",
"
\n",
" \n",
" | 5 | \n",
" Housing_own | \n",
" 0.013374 | \n",
"
\n",
" \n",
" | 6 | \n",
" Saving_accounts_little | \n",
" 0.009622 | \n",
"
\n",
" \n",
" | 7 | \n",
" Credit_amount | \n",
" 0.008884 | \n",
"
\n",
" \n",
" | 8 | \n",
" Housing_rent | \n",
" 0.008133 | \n",
"
\n",
" \n",
" | 9 | \n",
" Sex_male | \n",
" 0.007520 | \n",
"
\n",
" \n",
" | 10 | \n",
" Purpose_radio_TV | \n",
" 0.006844 | \n",
"
\n",
" \n",
" | 11 | \n",
" Purpose_car | \n",
" 0.006059 | \n",
"
\n",
" \n",
" | 12 | \n",
" Saving_accounts_none | \n",
" 0.005942 | \n",
"
\n",
" \n",
" | 13 | \n",
" Housing_free | \n",
" 0.005901 | \n",
"
\n",
" \n",
" | 14 | \n",
" Sex_female | \n",
" 0.004537 | \n",
"
\n",
" \n",
" | 15 | \n",
" Saving_accounts_rich | \n",
" 0.004407 | \n",
"
\n",
" \n",
" | 16 | \n",
" Purpose_education | \n",
" 0.003162 | \n",
"
\n",
" \n",
" | 17 | \n",
" Job_skilled | \n",
" 0.002704 | \n",
"
\n",
" \n",
" | 18 | \n",
" Saving_accounts_moderate | \n",
" 0.002680 | \n",
"
\n",
" \n",
" | 19 | \n",
" Purpose_vacation_others | \n",
" 0.002339 | \n",
"
\n",
" \n",
" | 20 | \n",
" Checking_account_rich | \n",
" 0.002247 | \n",
"
\n",
" \n",
" | 21 | \n",
" Job_unskilled_nonresident | \n",
" 0.001711 | \n",
"
\n",
" \n",
" | 22 | \n",
" Purpose_repairs | \n",
" 0.001627 | \n",
"
\n",
" \n",
" | 23 | \n",
" Purpose_furniture_equipment | \n",
" 0.001377 | \n",
"
\n",
" \n",
" | 24 | \n",
" Purpose_domestic_appliances | \n",
" 0.001172 | \n",
"
\n",
" \n",
" | 25 | \n",
" Job_highlyskilled | \n",
" 0.001144 | \n",
"
\n",
" \n",
" | 26 | \n",
" Saving_accounts_quite_rich | \n",
" 0.001032 | \n",
"
\n",
" \n",
" | 27 | \n",
" Job_unskilled_resident | \n",
" 0.000776 | \n",
"
\n",
" \n",
" | 28 | \n",
" Purpose_business | \n",
" 0.000121 | \n",
"
\n",
" \n",
"
\n",
" \n",
"\n",
" SHAP explanation:\n",
" \n",
" \n",
" | | \n",
" feature | \n",
" score | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" Duration | \n",
" 0.051965 | \n",
"
\n",
" \n",
" | 1 | \n",
" Checking_account_none | \n",
" 0.048818 | \n",
"
\n",
" \n",
" | 2 | \n",
" Age | \n",
" 0.044427 | \n",
"
\n",
" \n",
" | 3 | \n",
" Checking_account_little | \n",
" 0.030740 | \n",
"
\n",
" \n",
" | 4 | \n",
" Checking_account_moderate | \n",
" 0.025005 | \n",
"
\n",
" \n",
" | 5 | \n",
" Credit_amount | \n",
" 0.018809 | \n",
"
\n",
" \n",
" | 6 | \n",
" Saving_accounts_moderate | \n",
" 0.011132 | \n",
"
\n",
" \n",
" | 7 | \n",
" Purpose_furniture_equipment | \n",
" 0.009065 | \n",
"
\n",
" \n",
" | 8 | \n",
" Sex_female | \n",
" 0.007021 | \n",
"
\n",
" \n",
" | 9 | \n",
" Purpose_car | \n",
" 0.006882 | \n",
"
\n",
" \n",
" | 10 | \n",
" Housing_free | \n",
" 0.006844 | \n",
"
\n",
" \n",
" | 11 | \n",
" Saving_accounts_none | \n",
" 0.004482 | \n",
"
\n",
" \n",
" | 12 | \n",
" Sex_male | \n",
" 0.004218 | \n",
"
\n",
" \n",
" | 13 | \n",
" Job_unskilled_resident | \n",
" 0.004134 | \n",
"
\n",
" \n",
" | 14 | \n",
" Saving_accounts_little | \n",
" 0.003987 | \n",
"
\n",
" \n",
" | 15 | \n",
" Job_highlyskilled | \n",
" 0.002708 | \n",
"
\n",
" \n",
" | 16 | \n",
" Saving_accounts_quite_rich | \n",
" 0.001809 | \n",
"
\n",
" \n",
" | 17 | \n",
" Purpose_education | \n",
" 0.001744 | \n",
"
\n",
" \n",
" | 18 | \n",
" Job_skilled | \n",
" 0.001720 | \n",
"
\n",
" \n",
" | 19 | \n",
" Housing_own | \n",
" 0.001668 | \n",
"
\n",
" \n",
" | 20 | \n",
" Purpose_repairs | \n",
" 0.001397 | \n",
"
\n",
" \n",
" | 21 | \n",
" Purpose_vacation_others | \n",
" 0.000760 | \n",
"
\n",
" \n",
" | 22 | \n",
" Purpose_business | \n",
" 0.000601 | \n",
"
\n",
" \n",
" | 23 | \n",
" Saving_accounts_rich | \n",
" 0.000569 | \n",
"
\n",
" \n",
" | 24 | \n",
" Checking_account_rich | \n",
" 0.000486 | \n",
"
\n",
" \n",
" | 25 | \n",
" Purpose_radio_TV | \n",
" 0.000356 | \n",
"
\n",
" \n",
" | 26 | \n",
" Housing_rent | \n",
" 0.000178 | \n",
"
\n",
" \n",
" | 27 | \n",
" Purpose_domestic_appliances | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 28 | \n",
" Job_unskilled_nonresident | \n",
" 0.000000 | \n",
"
\n",
" \n",
"
\n",
" \n",
"\n",
" Anchor explanation:\n",
" \n",
" \n",
" | | \n",
" feature | \n",
" score | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" Purpose_furniture_equipment | \n",
" 0.813893 | \n",
"
\n",
" \n",
" | 1 | \n",
" Age | \n",
" 0.503277 | \n",
"
\n",
" \n",
" | 2 | \n",
" Duration | \n",
" 0.433814 | \n",
"
\n",
" \n",
" | 3 | \n",
" Sex_female | \n",
" 0.313237 | \n",
"
\n",
" \n",
" | 4 | \n",
" Housing_own | \n",
" 0.296199 | \n",
"
\n",
" \n",
" | 5 | \n",
" Checking_account_little | \n",
" 0.283093 | \n",
"
\n",
" \n",
" | 6 | \n",
" Saving_accounts_rich | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 7 | \n",
" Purpose_repairs | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 8 | \n",
" Purpose_radio_TV | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 9 | \n",
" Purpose_education | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 10 | \n",
" Purpose_domestic_appliances | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 11 | \n",
" Purpose_car | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 12 | \n",
" Purpose_business | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 13 | \n",
" Checking_account_rich | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 14 | \n",
" Checking_account_none | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 15 | \n",
" Checking_account_moderate | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 16 | \n",
" Saving_accounts_none | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 17 | \n",
" Saving_accounts_quite_rich | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 18 | \n",
" Credit_amount | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 19 | \n",
" Saving_accounts_moderate | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 20 | \n",
" Saving_accounts_little | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 21 | \n",
" Housing_rent | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 22 | \n",
" Housing_free | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 23 | \n",
" Job_unskilled_resident | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 24 | \n",
" Job_unskilled_nonresident | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 25 | \n",
" Job_skilled | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 26 | \n",
" Job_highlyskilled | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 27 | \n",
" Sex_male | \n",
" 0.000000 | \n",
"
\n",
" \n",
" | 28 | \n",
" Purpose_vacation_others | \n",
" 0.000000 | \n",
"
\n",
" \n",
"
\n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"display_side_by_side(agg_explainer.last_explanation_components, captions=['LIME explanation:', 'SHAP explanation:', 'Anchor explanation:'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Evaluating the aggregate explainer"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### The ExplanationModelEvaluator Class\n",
"This class holds all definitions for the metrics used to evaluate the explanation models. The aggregate explainer maintains an instance of this class in order to use its evaluations in the aggregation process. It is designed so that it can be used on any explainer that follows the interface and behavior conventions of the `explainers.py` file."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Using the internal ExplanationModelEvaluator instance\n",
"In order to be used, the ExplanationModelEvaluator class must be instantiated and its `init()` method must be called. This process, however, is somewhat time-consuming, since one of the metrics defined by this class relies on generating a noisy variation of the training data, and, to do that, an autoencoder is trained with tensorflow.\n",
"\n",
"However, this is usually not necessary, since the AggregateExplainer class maintains its own instance of the ExplanationModelEvaluator class, which can be used normally."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# ++ Usual instantiation of the ExplanationModelEvaluator class:\n",
"#\n",
"# evaluator = ExplanationModelEvaluator(clf, X_train, categorical_features)\n",
"# evaluator.init() # Takes some time to train the autoencoder\n",
"\n",
"# ++ Or, grab the one maintained by the AggregatedExplainer:\n",
"evaluator = agg_explainer.xai_evaluator"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### [WORKAROUND] Applying the sensitivity metric to the aggregate explainer:\n",
"One of the metrics defined in the ExplanationModelEvaluator class is the sensitivity metric. The way it works requires it to create several new instances of the explanation model being evaluated, since they each need to be fit to a different noisy variation of the training data. This process is very slow, and therefore multiprocessing is used in the `sensitivity()` function to distribute the workload. This, however, poses an issue when evaluating the sensitivity of the aggregate explainer model, since it may also use the sensitivity metric itself to perform the aggregation, which means a child process would have to create another child process, which usually is not allowed.\n",
"\n",
"As of now, in order to apply the sensitivity metric to the aggregate explainer, you must use a variation of its implementation that does the calculation without multiprocessing. A sequential version of the `sensitivity()` metric is provided by the `_sensitivity_sequential()` function."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9400656814449916"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"evaluator._sensitivity_sequential(\n",
" agg_explainer, \n",
" X_test.iloc[sample_idx],\n",
" extra_explainer_params={ # Must specify everything the explainer needs to be instantiated\n",
" \"explainer_types\": [LimeWrapper, ShapTabularTreeWrapper, AnchorWrapper],\n",
" \"evaluator\": agg_explainer.xai_evaluator # Remember to resue the same evaluator instance, otherwise the autoencoder will be retrained for every iteration\n",
" },\n",
" iterations=3,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Full evalution of the aggregate explainer"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here's one way of evaluating the aggregate explainer and comparing it to the explainers whose explanations were aggregated. In this example, the aggregate explainer was evaluated with the same metrics it used to internally evaluate each of the component models. The `get_last_explanation_info()` function was used to retrieve the metrics that were calculated internally, so they aren't calculated twice."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"faithfulness = evaluator.faithfullness_correlation(agg_explainer, X_test.iloc[sample_idx])\n",
"sensitivity = evaluator._sensitivity_sequential( # sequential version of sensitivity must be used at this time\n",
" agg_explainer, X_test.iloc[sample_idx],\n",
" extra_explainer_params={\n",
" \"explainer_types\": [LimeWrapper, ShapTabularTreeWrapper, AnchorWrapper],\n",
" \"evaluator\": agg_explainer.xai_evaluator\n",
" },\n",
" iterations=10\n",
" )\n",
"nrc = evaluator.nrc(agg_explainer, X_test.iloc[sample_idx])\n",
"\n",
"metrics = agg_explainer.get_last_explanation_info().drop(columns='weight')\n",
"\n",
"metrics.at[AggregatedExplainer.__name__, 'faithfulness_corr'] = faithfulness\n",
"metrics.at[AggregatedExplainer.__name__, 'sensitivity_spearman'] = sensitivity\n",
"metrics.at[AggregatedExplainer.__name__, 'nrc'] = nrc"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" nrc | \n",
" sensitivity_spearman | \n",
" faithfulness_corr | \n",
"
\n",
" \n",
" \n",
" \n",
" | LimeWrapper | \n",
" 46.152620 | \n",
" 0.859212 | \n",
" 0.355147 | \n",
"
\n",
" \n",
" | ShapTabularTreeWrapper | \n",
" 42.648201 | \n",
" 0.954843 | \n",
" 0.154678 | \n",
"
\n",
" \n",
" | AnchorWrapper | \n",
" 18.442814 | \n",
" 0.668667 | \n",
" 0.079319 | \n",
"
\n",
" \n",
" | AggregatedExplainer | \n",
" 44.579487 | \n",
" 0.913744 | \n",
" 0.320685 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" nrc sensitivity_spearman faithfulness_corr\n",
"LimeWrapper 46.152620 0.859212 0.355147\n",
"ShapTabularTreeWrapper 42.648201 0.954843 0.154678\n",
"AnchorWrapper 18.442814 0.668667 0.079319\n",
"AggregatedExplainer 44.579487 0.913744 0.320685"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"metrics"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Using the `xai_agg.exp_utils.evaluate_aggregate_explainer()` function\n",
"Utility function to evaluate the aggregate explainer, varying its settings. For each of the aggregate explainer's parameters (explainer components, mcdm algorighm, aggregation algorithm), the function accepts a list of possible values; it'll iterate over every possible value combination, checking n_instances, and will return the results as a list of lists of dataframes, one dataframe for each instance check, and one list of dataframes for each setting configuration."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from xai_agg.exp_utils import evaluate_aggregate_explainer\n",
"\n",
"results, metadata = evaluate_aggregate_explainer(\n",
" clf, X_train, X_test, categorical_features, # Model and data\n",
" explainer_components_sets=[[LimeWrapper, ShapTabularTreeWrapper, AnchorWrapper]], # Wrapped explainer sets to be tested\n",
" mcdm_algs=[pymcdm.methods.TOPSIS()], # MCDM algorithms to be tested\n",
" aggregation_algs=[\"wsum\"], # Aggregation algorithms to be tested\n",
" metrics_sets=[['nrc', 'sensitivity_spearman', 'faithfulness_corr']], # Metric sets to be tested\n",
" n_instances=1, # Number of instances per setting to run the evaluation on\n",
" mp_jobs=5 # Number of jobs to run in parallel (DECREASE THIS VALUE WHEN LOW RAM IS AVAILABLE)\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[[ nrc sensitivity_spearman faithfulness_corr\n",
" LimeWrapper 45.304455 0.838916 0.182748\n",
" ShapTabularTreeWrapper 44.518230 1.000000 0.240986\n",
" AnchorWrapper 35.929599 0.616926 0.326659\n",
" AggregateExplainer 48.324269 0.881232 0.286450]]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"{'indexes': array([110]),\n",
" 'configs': [{'explainer_components': [xai_agg.explainers.LimeWrapper,\n",
" xai_agg.explainers.ShapTabularTreeWrapper,\n",
" xai_agg.explainers.AnchorWrapper],\n",
" 'metrics': ['nrc', 'sensitivity_spearman', 'faithfulness_corr'],\n",
" 'mcdm_alg': ,\n",
" 'aggregation_alg': 'wsum'}]}"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"experiment_run = ExperimentRun(metadata, results)\n",
"\n",
"display(experiment_run.results)\n",
"display(experiment_run.metadata)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" nrc | \n",
" sensitivity_spearman | \n",
" faithfulness_corr | \n",
"
\n",
" \n",
" \n",
" \n",
" | AggregateExplainer | \n",
" 48.324269 | \n",
" 0.881232 | \n",
" 0.286450 | \n",
"
\n",
" \n",
" | AnchorWrapper | \n",
" 35.929599 | \n",
" 0.616926 | \n",
" 0.326659 | \n",
"
\n",
" \n",
" | LimeWrapper | \n",
" 45.304455 | \n",
" 0.838916 | \n",
" 0.182748 | \n",
"
\n",
" \n",
" | ShapTabularTreeWrapper | \n",
" 44.518230 | \n",
" 1.000000 | \n",
" 0.240986 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" nrc sensitivity_spearman faithfulness_corr\n",
"AggregateExplainer 48.324269 0.881232 0.286450\n",
"AnchorWrapper 35.929599 0.616926 0.326659\n",
"LimeWrapper 45.304455 0.838916 0.182748\n",
"ShapTabularTreeWrapper 44.518230 1.000000 0.240986"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Get mean results for a specific setting:\n",
"\n",
"desired_setting = 0\n",
"get_expconfig_mean_results(experiment_run, desired_setting)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}