diff --git a/README.md b/README.md
index 09b424b..6bc47e0 100644
--- a/README.md
+++ b/README.md
@@ -31,9 +31,7 @@ You can find the documentation at [https://ethicalml.github.io/xai/index.html](h
-# 0.0.5 - ALPHA Version
-
-This library is currently in early stage developments and hence it will be quite unstable due to the fast updates. It is important to bare this in mind if using it in production.
+# 0.1.0
If you want to see a fully functional demo in action clone this repo and run the Example Jupyter Notebook in the Examples folder.
@@ -84,7 +82,7 @@ ims = xai.imbalance_plot(df, "gender")
#### View imbalances for all categories across multiple columns
``` python
-im = xai.show_imbalance(df, "gender", "loan")
+im = xai.imbalance_plot(df, "gender", "loan")
```
diff --git a/env.yml b/env.yml
index 672f436..99f1841 100644
--- a/env.yml
+++ b/env.yml
@@ -3,16 +3,17 @@ channels:
- defaults
- conda-forge
dependencies:
- - python==3.7.3
+ - python
- jupyter
- - numpy==1.15.4
- - pandas==0.23.4
- - matplotlib==3.0.2
- - scikit-learn==0.20.1
+ - numpy
+ - pandas
+ - matplotlib
+ - scikit-learn
- seaborn
- spacy
- nb_conda
- keras
+ - tensorflow
- pip:
- black
- jupyterthemes # jt -t monokai -T -nfs 115 -cellw 98% -N -kl -ofs 11 -altmd
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..d24971a
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,975 @@
+```python
+import sys, os
+import pandas as pd
+import numpy as np
+from collections import defaultdict
+import matplotlib.pyplot as plt
+from sklearn.preprocessing import LabelEncoder, StandardScaler
+from sklearn.pipeline import make_pipeline
+
+# Use below for charts in dark jupyter theme
+
+THEME_DARK = False
+
+if THEME_DARK:
+ # This is used if Jupyter Theme dark is enabled.
+ # The theme chosen can be activated with jupyter theme as follows:
+ # >>> jt -t oceans16 -T -nfs 115 -cellw 98% -N -kl -ofs 11 -altmd
+ font_size = '20.0'
+ dark_theme_config = {
+ "ytick.color" : "w",
+ "xtick.color" : "w",
+ "text.color": "white",
+ 'font.size': font_size,
+ 'axes.titlesize': font_size,
+ 'axes.labelsize': font_size,
+ 'xtick.labelsize': font_size,
+ 'ytick.labelsize': font_size,
+ 'legend.fontsize': font_size,
+ 'figure.titlesize': font_size,
+ 'figure.figsize': [20, 7],
+ 'figure.facecolor': "#384151",
+ 'legend.facecolor': "#384151",
+ "axes.labelcolor" : "w",
+ "axes.edgecolor" : "w"
+ }
+ plt.rcParams.update(dark_theme_config)
+
+sys.path.append("..")
+
+import xai
+import xai.data
+```
+
+
+```python
+csv_path = 'data/adult.data'
+categorical_cols = ["gender", "workclass", "education", "education-num", "marital-status",
+ "occupation", "relationship", "ethnicity", "loan"]
+csv_columns = ["age", "workclass", "fnlwgt", "education", "education-num", "marital-status",
+ "occupation", "relationship", "ethnicity", "gender", "capital-gain", "capital-loss",
+ "hours-per-week", "loan"]
+```
+
+
+```python
+df = xai.data.load_census()
+df.tail()
+```
+
+
+
+
+
+
+
+
+
+ |
+ age |
+ workclass |
+ education |
+ education-num |
+ marital-status |
+ occupation |
+ relationship |
+ ethnicity |
+ gender |
+ capital-gain |
+ capital-loss |
+ hours-per-week |
+ loan |
+
+
+
+
+ 32556 |
+ 27 |
+ Private |
+ Assoc-acdm |
+ 12 |
+ Married-civ-spouse |
+ Tech-support |
+ Wife |
+ White |
+ Female |
+ 0 |
+ 0 |
+ 38 |
+ <=50K |
+
+
+ 32557 |
+ 40 |
+ Private |
+ HS-grad |
+ 9 |
+ Married-civ-spouse |
+ Machine-op-inspct |
+ Husband |
+ White |
+ Male |
+ 0 |
+ 0 |
+ 40 |
+ >50K |
+
+
+ 32558 |
+ 58 |
+ Private |
+ HS-grad |
+ 9 |
+ Widowed |
+ Adm-clerical |
+ Unmarried |
+ White |
+ Female |
+ 0 |
+ 0 |
+ 40 |
+ <=50K |
+
+
+ 32559 |
+ 22 |
+ Private |
+ HS-grad |
+ 9 |
+ Never-married |
+ Adm-clerical |
+ Own-child |
+ White |
+ Male |
+ 0 |
+ 0 |
+ 20 |
+ <=50K |
+
+
+ 32560 |
+ 52 |
+ Self-emp-inc |
+ HS-grad |
+ 9 |
+ Married-civ-spouse |
+ Exec-managerial |
+ Wife |
+ White |
+ Female |
+ 15024 |
+ 0 |
+ 40 |
+ >50K |
+
+
+
+
+
+
+
+
+```python
+target = "loan"
+protected = ["ethnicity", "gender", "age"]
+```
+
+
+```python
+df_groups = xai.imbalance_plot(df, "gender", categorical_cols=categorical_cols)
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_4_0.png)
+
+
+
+
+```python
+groups = xai.imbalance_plot(df, "gender", "loan", categorical_cols=categorical_cols)
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_5_0.png)
+
+
+
+
+```python
+bal_df = xai.balance(df, "gender", "loan", upsample=0.8, categorical_cols=categorical_cols)
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_6_0.png)
+
+
+
+
+```python
+groups = xai.group_by_columns(df, ["gender", "loan"], categorical_cols=categorical_cols)
+for group, group_df in groups:
+ print(group)
+ print(group_df["loan"].head(), "\n")
+```
+
+ (' Female', ' <=50K')
+ 4 <=50K
+ 5 <=50K
+ 6 <=50K
+ 12 <=50K
+ 21 <=50K
+ Name: loan, dtype: object
+
+ (' Female', ' >50K')
+ 8 >50K
+ 19 >50K
+ 52 >50K
+ 67 >50K
+ 84 >50K
+ Name: loan, dtype: object
+
+ (' Male', ' <=50K')
+ 0 <=50K
+ 1 <=50K
+ 2 <=50K
+ 3 <=50K
+ 13 <=50K
+ Name: loan, dtype: object
+
+ (' Male', ' >50K')
+ 7 >50K
+ 9 >50K
+ 10 >50K
+ 11 >50K
+ 14 >50K
+ Name: loan, dtype: object
+
+
+
+
+```python
+_ = xai.correlations(df, include_categorical=True, plot_type="matrix")
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_8_0.png)
+
+
+
+
+```python
+_ = xai.correlations(df, include_categorical=True)
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_9_0.png)
+
+
+
+
+```python
+proc_df = xai.normalize_numeric(bal_df)
+proc_df = xai.convert_categories(proc_df)
+x = proc_df.drop("loan", axis=1)
+y = proc_df["loan"]
+
+x_train, y_train, x_test, y_test, train_idx, test_idx = \
+ xai.balanced_train_test_split(
+ x, y, "gender",
+ min_per_group=300,
+ max_per_group=300,
+ categorical_cols=categorical_cols)
+
+x_train_display = bal_df[train_idx]
+x_test_display = bal_df[test_idx]
+
+print("Total number of examples: ", x_test.shape[0])
+
+df_test = x_test_display.copy()
+df_test["loan"] = y_test
+
+_= xai.imbalance_plot(df_test, "gender", "loan", categorical_cols=categorical_cols)
+```
+
+ Total number of examples: 1200
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_10_1.png)
+
+
+
+
+```python
+import sklearn
+from sklearn.model_selection import train_test_split
+from sklearn.metrics import classification_report, mean_squared_error, roc_curve, auc
+
+from tensorflow.keras.layers import Input, Dense, Flatten, \
+ Concatenate, concatenate, Dropout, Lambda, Embedding
+from tensorflow.keras.models import Model, Sequential
+
+def build_model(X):
+ input_els = []
+ encoded_els = []
+ dtypes = list(zip(X.dtypes.index, map(str, X.dtypes)))
+ for k,dtype in dtypes:
+ input_els.append(Input(shape=(1,)))
+ if dtype == "int8":
+ e = Flatten()(Embedding(X[k].max()+1, 1)(input_els[-1]))
+ else:
+ e = input_els[-1]
+ encoded_els.append(e)
+ encoded_els = concatenate(encoded_els)
+
+ layer1 = Dropout(0.5)(Dense(100, activation="relu")(encoded_els))
+ out = Dense(1, activation='sigmoid')(layer1)
+
+ # train model
+ model = Model(inputs=input_els, outputs=[out])
+ model.compile(optimizer="adam", loss='binary_crossentropy', metrics=['accuracy'])
+ return model
+
+
+def f_in(X, m=None):
+ """Preprocess input so it can be provided to a function"""
+ if m:
+ return [X.iloc[:m,i] for i in range(X.shape[1])]
+ else:
+ return [X.iloc[:,i] for i in range(X.shape[1])]
+
+def f_out(probs, threshold=0.5):
+ """Convert probabilities into classes"""
+ return list((probs >= threshold).astype(int).T[0])
+
+```
+
+
+```python
+model = build_model(x_train)
+
+model.fit(f_in(x_train), y_train, epochs=50, batch_size=512)
+```
+
+ Epoch 1/50
+ 99/99 [==============================] - 1s 3ms/step - loss: 0.6227 - accuracy: 0.6459
+ Epoch 2/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.4600 - accuracy: 0.7812
+ Epoch 3/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3968 - accuracy: 0.8153
+ Epoch 4/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3789 - accuracy: 0.8215
+ Epoch 5/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3751 - accuracy: 0.8237
+ Epoch 6/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3771 - accuracy: 0.8235
+ Epoch 7/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3730 - accuracy: 0.8254
+ Epoch 8/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3675 - accuracy: 0.8312
+ Epoch 9/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3685 - accuracy: 0.8281
+ Epoch 10/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3620 - accuracy: 0.8313
+ Epoch 11/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3687 - accuracy: 0.8297
+ Epoch 12/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3698 - accuracy: 0.8292
+ Epoch 13/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3666 - accuracy: 0.8285
+ Epoch 14/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3649 - accuracy: 0.8305
+ Epoch 15/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3628 - accuracy: 0.8326
+ Epoch 16/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3669 - accuracy: 0.8306
+ Epoch 17/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3587 - accuracy: 0.8347
+ Epoch 18/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3639 - accuracy: 0.8306
+ Epoch 19/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3618 - accuracy: 0.8335
+ Epoch 20/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3628 - accuracy: 0.8315
+ Epoch 21/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3641 - accuracy: 0.8325
+ Epoch 22/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3634 - accuracy: 0.8310
+ Epoch 23/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3626 - accuracy: 0.8293
+ Epoch 24/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3659 - accuracy: 0.8298
+ Epoch 25/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3607 - accuracy: 0.8333
+ Epoch 26/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3600 - accuracy: 0.8321
+ Epoch 27/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3650 - accuracy: 0.8296
+ Epoch 28/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3626 - accuracy: 0.8317
+ Epoch 29/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3654 - accuracy: 0.8310
+ Epoch 30/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3659 - accuracy: 0.8322
+ Epoch 31/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3716 - accuracy: 0.8278
+ Epoch 32/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3631 - accuracy: 0.8326
+ Epoch 33/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3669 - accuracy: 0.8312
+ Epoch 34/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3604 - accuracy: 0.8325
+ Epoch 35/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3625 - accuracy: 0.8318
+ Epoch 36/50
+ 99/99 [==============================] - 0s 2ms/step - loss: 0.3605 - accuracy: 0.8326
+ Epoch 37/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3595 - accuracy: 0.8334
+ Epoch 38/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3653 - accuracy: 0.8316
+ Epoch 39/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3591 - accuracy: 0.8350
+ Epoch 40/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3602 - accuracy: 0.8337
+ Epoch 41/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3617 - accuracy: 0.8316
+ Epoch 42/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3624 - accuracy: 0.8320
+ Epoch 43/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3624 - accuracy: 0.8328
+ Epoch 44/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3602 - accuracy: 0.8326
+ Epoch 45/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3610 - accuracy: 0.8337
+ Epoch 46/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3626 - accuracy: 0.8323
+ Epoch 47/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3634 - accuracy: 0.8326
+ Epoch 48/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3614 - accuracy: 0.8328
+ Epoch 49/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3610 - accuracy: 0.8332
+ Epoch 50/50
+ 99/99 [==============================] - 0s 3ms/step - loss: 0.3590 - accuracy: 0.8332
+
+
+
+
+
+
+
+
+
+
+```python
+score = model.evaluate(f_in(x_test), y_test, verbose=1)
+print("Error %.4f: " % score[0])
+print("Accuracy %.4f: " % (score[1]*100))
+```
+
+ 38/38 [==============================] - 0s 1ms/step - loss: 0.3630 - accuracy: 0.8292
+ Error 0.3630:
+ Accuracy 82.9167:
+
+
+
+```python
+probabilities = model.predict(f_in(x_test))
+pred = f_out(probabilities)
+```
+
+
+```python
+_= xai.metrics_plot(
+ y_test,
+ probabilities)
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_15_0.png)
+
+
+
+
+```python
+df.head()
+```
+
+
+
+
+
+
+
+
+
+ |
+ age |
+ workclass |
+ education |
+ education-num |
+ marital-status |
+ occupation |
+ relationship |
+ ethnicity |
+ gender |
+ capital-gain |
+ capital-loss |
+ hours-per-week |
+ loan |
+
+
+
+
+ 0 |
+ 39 |
+ State-gov |
+ Bachelors |
+ 13 |
+ Never-married |
+ Adm-clerical |
+ Not-in-family |
+ White |
+ Male |
+ 2174 |
+ 0 |
+ 40 |
+ <=50K |
+
+
+ 1 |
+ 50 |
+ Self-emp-not-inc |
+ Bachelors |
+ 13 |
+ Married-civ-spouse |
+ Exec-managerial |
+ Husband |
+ White |
+ Male |
+ 0 |
+ 0 |
+ 13 |
+ <=50K |
+
+
+ 2 |
+ 38 |
+ Private |
+ HS-grad |
+ 9 |
+ Divorced |
+ Handlers-cleaners |
+ Not-in-family |
+ White |
+ Male |
+ 0 |
+ 0 |
+ 40 |
+ <=50K |
+
+
+ 3 |
+ 53 |
+ Private |
+ 11th |
+ 7 |
+ Married-civ-spouse |
+ Handlers-cleaners |
+ Husband |
+ Black |
+ Male |
+ 0 |
+ 0 |
+ 40 |
+ <=50K |
+
+
+ 4 |
+ 28 |
+ Private |
+ Bachelors |
+ 13 |
+ Married-civ-spouse |
+ Prof-specialty |
+ Wife |
+ Black |
+ Female |
+ 0 |
+ 0 |
+ 40 |
+ <=50K |
+
+
+
+
+
+
+
+
+```python
+_ = xai.metrics_plot(
+ y_test,
+ probabilities,
+ df=x_test_display,
+ cross_cols=["gender", "ethnicity"],
+ categorical_cols=categorical_cols)
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_17_0.png)
+
+
+
+
+```python
+_ = [xai.metrics_plot(
+ y_test,
+ probabilities,
+ df=x_test_display,
+ cross_cols=[p],
+ categorical_cols=categorical_cols) for p in protected]
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_18_0.png)
+
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_18_1.png)
+
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_18_2.png)
+
+
+
+
+```python
+xai.confusion_matrix_plot(y_test, pred)
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_19_0.png)
+
+
+
+
+```python
+xai.confusion_matrix_plot(y_test, pred, scaled=False)
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_20_0.png)
+
+
+
+
+```python
+_ = xai.roc_plot(y_test, probabilities)
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_21_0.png)
+
+
+
+
+```python
+_ = [xai.roc_plot(
+ y_test,
+ probabilities,
+ df=x_test_display,
+ cross_cols=[p],
+ categorical_cols=categorical_cols) for p in protected]
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_22_0.png)
+
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_22_1.png)
+
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_22_2.png)
+
+
+
+
+```python
+_= xai.pr_plot(y_test, probabilities)
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_23_0.png)
+
+
+
+
+```python
+_ = [xai.pr_plot(
+ y_test,
+ probabilities,
+ df=x_test_display,
+ cross_cols=[p],
+ categorical_cols=categorical_cols) for p in protected]
+```
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_24_0.png)
+
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_24_1.png)
+
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_24_2.png)
+
+
+
+
+```python
+d = xai.smile_imbalance(
+ y_test,
+ probabilities)
+```
+
+ /home/alejandro/miniconda3/lib/python3.7/site-packages/pandas/core/indexing.py:671: SettingWithCopyWarning:
+ A value is trying to be set on a copy of a slice from a DataFrame
+
+ See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
+ self._setitem_with_indexer(indexer, value)
+ WARNING:root:No categorical_cols passed so inferred using np.object, np.int8 and np.bool: Index(['target', 'manual-review'], dtype='object'). If you see an error these are not correct, please provide them as a string array as: categorical_cols=['col1', 'col2', ...]
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_25_1.png)
+
+
+
+
+```python
+d[["correct", "incorrect"]].sum().plot.bar()
+```
+
+
+
+
+
+
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_26_1.png)
+
+
+
+
+```python
+d = xai.smile_imbalance(
+ y_test,
+ probabilities,
+ threshold=0.75,
+ display_breakdown=True)
+```
+
+ WARNING:root:No categorical_cols passed so inferred using np.object, np.int8 and np.bool: Index(['target', 'manual-review'], dtype='object'). If you see an error these are not correct, please provide them as a string array as: categorical_cols=['col1', 'col2', ...]
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_27_1.png)
+
+
+
+
+```python
+display_bars = ["true-positives", "true-negatives",
+ "false-positives", "false-negatives"]
+d[display_bars].sum().plot.bar()
+```
+
+
+
+
+
+
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_28_1.png)
+
+
+
+
+```python
+d = xai.smile_imbalance(
+ y_test,
+ probabilities,
+ bins=9,
+ threshold=0.75,
+ manual_review=0.00001,
+ display_breakdown=False)
+```
+
+ WARNING:root:No categorical_cols passed so inferred using np.object, np.int8 and np.bool: Index(['target', 'manual-review'], dtype='object'). If you see an error these are not correct, please provide them as a string array as: categorical_cols=['col1', 'col2', ...]
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_29_1.png)
+
+
+
+
+```python
+d[["correct", "incorrect", "manual-review"]].sum().plot.bar()
+```
+
+
+
+
+
+
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_30_1.png)
+
+
+
+
+```python
+def get_avg(x, y):
+ return model.evaluate(f_in(x), y, verbose=0)[1]
+
+imp = xai.feature_importance(x_test, y_test, get_avg)
+
+imp.head()
+```
+
+
+
+
+
+
+
+
+
+ |
+ age |
+ workclass |
+ education |
+ education-num |
+ marital-status |
+ occupation |
+ relationship |
+ ethnicity |
+ gender |
+ capital-gain |
+ capital-loss |
+ hours-per-week |
+
+
+
+
+ 0 |
+ 0.01825 |
+ 0.002167 |
+ 0.000833 |
+ 0.046 |
+ 0.065667 |
+ 0.019083 |
+ 0.02425 |
+ 0.00275 |
+ 0.000833 |
+ 0.05075 |
+ 0.007833 |
+ 0.014417 |
+
+
+
+
+
+
+
+
+
+![png](XAI%20Tabular%20Data%20Example%20Usage_files/XAI%20Tabular%20Data%20Example%20Usage_31_1.png)
+
+
+
+
+```python
+
+```
diff --git a/examples/XAI Tabular Data Example Usage.ipynb b/examples/XAI Tabular Data Example Usage.ipynb
index efe1d47..bedb1a3 100644
--- a/examples/XAI Tabular Data Example Usage.ipynb
+++ b/examples/XAI Tabular Data Example Usage.ipynb
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
@@ -50,7 +50,7 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
@@ -64,7 +64,7 @@
},
{
"cell_type": "code",
- "execution_count": 14,
+ "execution_count": 17,
"metadata": {
"scrolled": true
},
@@ -213,7 +213,7 @@
"32560 0 40 >50K "
]
},
- "execution_count": 14,
+ "execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
@@ -225,7 +225,7 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
@@ -235,14 +235,14 @@
},
{
"cell_type": "code",
- "execution_count": 24,
+ "execution_count": 19,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYcAAAEoCAYAAACzVD1FAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAH4FJREFUeJzt3Xt4VNW9//H3N+HayjFWgwXiBZsIBAIRwk1QUORqDVgBQVsuWjiiSLGXI6f6Kz5ij9Bqa71h4YiCRaNiBbQUTkTxVkGC2iIgDQqFQB4uQUTEAJH1+2N2phPWhARymcB8Xs8zz8ys2XvNd4dhPrP32rPGnHOIiIhESoh1ASIiUvcoHERExKNwEBERj8JBREQ8CgcREfEoHERExKNwEBERj8JBREQ8CgcREfEoHERExFMv1gWcrHPOOcddeOGFsS5DROSUsmbNmj3OueSKljtlw+HCCy8kLy8v1mWIiJxSzOxflVlOh5VERMSjcBAREY/CQUREPKfsmEM0R44coaCggOLi4liXIlKjGjVqREpKCvXr1491KXKaOq3CoaCggCZNmnDhhRdiZrEuR6RGOOcoKiqioKCAli1bxrocOU2dVoeViouLOfvssxUMclozM84++2ztIUuNOq3CAVAwSFzQ61xq2mkXDrFUVFREZmYmmZmZfPe736VFixZkZmaSlJREenp6tT/fihUr+P73v39C6/Tu3Tvq90OefvppJk6cWOH6AwYMICkpyXvezZs307VrV9LS0rj++us5fPgwAFu3buWKK67gkksuoX379ixZsgSAw4cPM3bsWDIyMujQoQMrVqwoU2OrVq3Cf8tdu3ZFreX+++8nNTWVVq1asWzZsnD70qVLadWqFampqUyfPr3cbZk8eTJvvfUWAGPGjKFly5bh5/zoo4+A0CGcSZMmkZqaSvv27fnggw+i9rVmzRoyMjJITU1l0qRJlP42+969e+nbty9paWn07duXzz//HICXXnqJtm3bctlll1FUVATAp59+yogRI8J9Hj58mMsvv5ySkpJyt0GkppxWYw6xdvbZZ4ffVO655x7OOOMMfv7zn7Nly5ZKvYmXlJRQr17d/if5xS9+wcGDB/njH/9Ypv3OO+/kjjvuYMSIEdxyyy08+eSTTJgwgfvuu4/hw4czYcIE1q9fz6BBg9iyZQuzZ88GYO3atezatYuBAweyevVqEhJCn1fmz59PVlZWuXWsX7+enJwc1q1bx44dO7jqqqv45z//CcBtt91Gbm4uKSkpdO7cmezsbC+c9+7dy8qVK3nooYfCbb/97W8ZOnRomeX++te/kp+fT35+PqtWrWLChAmsWrXKq2fChAnMmjWLbt26MWjQIJYuXcrAgQOZPn06ffr0YcqUKUyfPp3p06czY8YMHnzwQVauXElOTg7PPvsst99+O3fffTfTpk0L99mgQQP69OnD888/z4033liZf54T0rHr49XeZzz7YNWtsS6hWmnPoZZ88803jBs3jrZt29KvXz++/vprIPQp+Ze//CW9evXiD3/4A7t37+a6666jc+fOdO7cmXfffReAN998M/yp9pJLLuHLL78E4MCBAwwdOpTWrVtz4403hj+xLl++nEsuuYSMjAxuuukmDh065NX01FNPcfHFF9OrV6/w81SkT58+NGnSpEybc47XX389/MY6evRoFi5cCIQOf+zfvx+AL774gubNmwOhN/c+ffoA0LRpU5KSkk7oG++LFi1ixIgRNGzYkJYtW5Kamsr777/P+++/T2pqKhdddBENGjRgxIgRLFq0yFt/wYIFDBgwoFLPM2rUKMyMbt26sW/fPgoLC8ssU1hYyP79++nevTtmxqhRo8Lbv2jRIkaPHu39XRISEjh06BAHDx6kfv36vP322zRr1oy0tLQyfQ8ZMoT58+dX+u8iUl3q9sfUqpg8GYJP8dUmMxMiPmmeiPz8fJ577jlmz57N8OHDeemll/jhD38IwL59+3jzzTcBuOGGG7jjjjvo2bMnW7dupX///mzYsIEHHniAxx57jB49enDgwAEaNWoEwIcffsi6deto3rw5PXr04N133yUrK4sxY8awfPlyLr74YkaNGsXMmTOZPHlyuJ7CwkKmTp3KmjVrOPPMM8OHfgAWL15MXl4e9957b6W2raioiKSkpPBeT0pKCtu3bwdCe1D9+vXjkUce4auvvuK1114DoEOHDuE3+G3btrFmzRq2bdtGly5dABg7diyJiYlcd9113H333d4x9u3bt9OtW7fw/cjnPO+888q0R/uk/+6773p7CXfddRf33nsvffr0Yfr06TRs2JDt27d7/W3fvp1mzZqVqSUlJSVqLTt37gwv26xZs/AhsqlTp9K/f3+aN2/On/70J4YP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\n",
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYMAAAEkCAYAAADNfV1EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAeqElEQVR4nO3df5yNdf7/8cdrBo02G2mSTEWRjDAxfpSSUkjfhkqibmv0g4oK23dv2a1Nt9Xelm/ajVJ9tOTHFiqfom7FilIpMUrJSKOoRhMaK1nGmPH6/nGuOZ1hhsHMnDHneb/d5jbXeZ/rel+vaxzzPNd1vc97zN0REZHYFhftAkREJPoUBiIiojAQERGFgYiIoDAQEREUBiIiAtSIdgFH69RTT/XGjRtHuwwRkePKqlWrfnL3xAPbj9swaNy4MRkZGdEuQ0TkuGJm35bUrstEIiKiMBAREYWBiIhwHN8zKMm+ffvIzs4mLy8v2qWIVKiEhASSkpKoWbNmtEuRaqJahUF2djZ16tShcePGmFm0yxGpEO5Obm4u2dnZNGnSJNrlSDVRrS4T5eXlUb9+fQWBVGtmRv369XUGLOWqWoUBoCCQmKDXuZS3ahcGIiJy5KrVPYNoy83NpVu3bgD8+OOPxMfHk5iYyKZNmzjjjDPIzMws1/29++67jB8/njfeeKPM23Tt2pXx48eTmpparH3atGlkZGTw1FNPHXL7nj17snz5ci655JJi+924cSP9+/cnNzeXdu3aMXPmTGrVqsV3331Heno6O3bsoLCwkLFjx9KrVy/y8/O58847ycjIIC4ujgkTJtC1a9dwjTk5OdSuXRuAf//735x22mkH1fK3v/2NKVOmEB8fz8SJE+nRowcACxYsYPjw4RQWFnLHHXcwatSoEo9lxIgRXH/99XTp0oVBgwaxdOlSTj755PDPIyUlBXdn+PDhvPnmm5x44olMmzaNtm3bHtTXqlWrGDRoEHv27KFXr15MmDABM2P79u3cdNNNbNq0icaNG/PSSy9Rr1495s6dy8MPP8wpp5zCa6+9Rv369fn666/505/+xJw5cwDIz8/nyiuvZMmSJdSoUf7/Vdt2fLrc+4xln3w8NNolHBOdGZSj+vXrs3r1alavXs1dd93FyJEjw4/j4g7/oy4oKKiEKo/NH/7wB2bOnHlQ+wMPPMDIkSPZsGED9erVY8qUKQA8+uij9OvXj08//ZTZs2czdGjoP8xzzz0HwJo1a1i0aBH3338/+/fvD/f3wgsvhH92JQVBZmYms2fPZu3atSxYsIChQ4dSWFhIYWEhw4YN46233iIzM5NZs2aVGMK5ubksX76cLl26hNsee+yx8D5TUlIAeOutt8jKyiIrK4vJkydz9913l/hzufvuu3nuuefC6y5YsACAsWPH0q1bN7KysujWrRtjx44F4Mknn2TlypXceeedvPjiiwA89NBDPProo+E+a9WqRbdu3cLhIFKRqm8YjBgBXbuW79eIEUddTmFhIYMHD6Zly5Z0796dPXv2AKF3wSNGjCA1NZUJEyawbds2brjhBtq3b0/79u1ZtmwZAEuXLiUlJYWUlBQuvPBCfvnlFwB27dpF3759Of/887nlllso+jOmixcv5sILL6RVq1bcdttt7N2796Cann/+ec477zw6dOgQ3s/hdOvWjTp16hRrc3eWLFlC3759AUhPT+e1114DQte2d+7cCcDPP//MGWecAYR+mV9xxRUAnHbaadStW/eIpheZN28e/fv354QTTqBJkyY0bdqUFStWsGLFCpo2bco555xDrVq16N+/P/PmzTto+7lz59KzZ88y7WfgwIGYGZ06dWLHjh3k5OQUWycnJ4edO3fSqVMnzIyBAweGj3/evHmkp6cf9HOJi4tj79697N69m5o1a/L+++9z+umn06xZs2J99+nThxdeeKHMPxeRo1V9w6CKycrKYtiwYaxdu5a6desyd+7c8HP5+flkZGRw//33M3z4cEaOHMnKlSuZO3cud9xxBwDjx49n0qRJrF69mvfffz98CeXTTz/liSeeIDMzk2+++YZly5aRl5fHoEGDmDNnDmvWrKGgoIBnnnmmWD05OTmMHj2aZcuW8cEHHxR79zx//nwefvjhMh9bbm4udevWDV/KSEpKYvPmzQA88sgj/Otf/yIpKYlevXrx5JNPAtCmTRvmz59PQUEBGzduZNWqVXz//ffhPm+99VZSUlIYM2YMJf2d7s2bN3PmmWeGHxfts7T2Ay1btox27doVa3vwwQdp3bo1I0eODIdnWfrbvHkzSUlJJa6zZcsWGjZsCMDpp5/Oli1bAPjjH//IlVdeyeuvv86AAQMYM2YMf/7znw+q84ILLmDlypUHtYuUt+p7z+CJJ6JdQTFNmjQJX3po164dmzZtCj930003hZfffvvtYr+Yd+7cya5du+jcuTO///3vueWWW7j++uvDv3w6dOgQXk5JSWHTpk3UqVOHJk2acN555wGhd6STJk1iRMSZzccff0zXrl1JTEwM1/DVV18BkJaWRlpaWrkc96xZsxg0aBD3338/H330Eb/73e/44osvuO2221i3bh2pqamcffbZXHzxxcTHxwOhS0SNGjXil19+4YYbbmDmzJkMHDiwXOopkpOTEz52CN1/OP3008nPz2fIkCGMGzfuiAKxLMwsPAroqquu4qqrrgJgxowZ9OrVi6+++orx48dTr149JkyYwIknnkh8fDy1atXil19+OeiMTKQ86cygkpxwwgnh5fj4+GL3B37zm9+El/fv38/y5cvD1643b97MSSedxKhRo/jnP//Jnj176Ny5M19++eVh+60s9evXZ8eOHeF9Z2dn06hRIwCmTJlCv379ALjooovIy8vjp59+okaNGvzjH/9g9erVzJs3jx07doTDq2jbOnXqcPPNN7NixYqD9tmoUaNiZxJF+yyt/UC1a9cuNk6/YcOGmBknnHACt956a3ifZemvUaNGZGdnl7hOgwYNwpeVcnJyDrr/sXv3bqZNm8awYcMYPXo006dP55JLLil2aWjv3r0kJCQcdAwi5UlhUMV07949fCkFYPXq1QB8/fXXtGrVigceeID27duHw6AkzZs3Z9OmTWzYsAGAmTNnctlllxVbp2PHjixdupTc3Fz27dvHyy+/fNQ1mxmXX345r7zyCgDTp0+nd+/eAJx11lksXrwYgHXr1pGXl0diYiK7d+/mv//9LwCLFi2iRo0aJCcnU1BQwE8//QSEphd54403uOCCCw7aZ1paGrNnz2bv3r1s3LiRrKwsOnToQPv27cnKymLjxo3k5+cze/bsEs9yWrRoEf75AOFf2O7Oa6+9Ft5nWloaM2bMwN1Zvnw5J598cviyT5GGDRvy29/+luXLl+PuzJgxI3z8aWlpTJ8+/aCfS5HHHnuM++67j5o1a7Jnzx7MjLi4OHbv3g2ELsGdeuqpmnZCKpzCoIqZOHEiGRkZtG7dmuTkZJ599lkAnnjiCS644AJat25NzZo1ufrqq0vtIyEhgeeff54bb7yRVq1aERcXx1133VVsnYYNG/LII49w0UUX0blzZ1q0aBF+7lD3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\n",
"text/plain": [
"