Importing Models From Libraries
PyXAI can generate models for you. Indeed, it provides dedicated functions that simplify this task. However, if your model has already been trained, you may want to import it into PyXAI in order to extract explanations. This page explains how to perform such a task.
Procedure
Consider the following source code to create a RandomForestClassifier using Scikit-learn:
from sklearn import datasets
from sklearn.ensemble import RandomForestClassifier
model_rf = RandomForestClassifier(random_state=0)
data = datasets.load_breast_cancer(as_frame=True)
X = data.data.to_numpy()
Y = data.target.to_numpy()
feature_names = data.feature_names
model_rf.fit(X, Y);
You can import this ML model using the import_models method of the ModelIO class:
Here is a table summarizing the library compatibility of import_models:
| Type | Scikit-learn | Xgboost | LightGBM |
|---|---|---|---|
| Decision Tree | DecisionTreeClassifier | ||
| Random Forest | RandomForestClassifier | ||
| Boosted Tree | XGBClassifier XGBRegressor | LGBMRegressor |
from pyxai import Learning, Explainer
learner, model = Learning.ModelIO.import_models(model_rf, instances_type='tabular')
learner.feature_names = feature_names
Then, you can get explanations by executing:
instance, prediction = learner.get_instances(dataset=data.frame, model=model, n=1)
print("instance:", instance)
print("prediction:", prediction)
--------------- Instances ----------------
data:
mean radius mean texture mean perimeter mean area mean smoothness
0 17.99 10.38 122.80 1001.0 0.11840 \
1 20.57 17.77 132.90 1326.0 0.08474
2 19.69 21.25 130.00 1203.0 0.10960
3 11.42 20.38 77.58 386.1 0.14250
4 20.29 14.34 135.10 1297.0 0.10030
.. ... ... ... ... ...
564 21.56 22.39 142.00 1479.0 0.11100
565 20.13 28.25 131.20 1261.0 0.09780
566 16.60 28.08 108.30 858.1 0.08455
567 20.60 29.33 140.10 1265.0 0.11780
568 7.76 24.54 47.92 181.0 0.05263
mean compactness mean concavity mean concave points mean symmetry
0 0.27760 0.30010 0.14710 0.2419 \
1 0.07864 0.08690 0.07017 0.1812
2 0.15990 0.19740 0.12790 0.2069
3 0.28390 0.24140 0.10520 0.2597
4 0.13280 0.19800 0.10430 0.1809
.. ... ... ... ...
564 0.11590 0.24390 0.13890 0.1726
565 0.10340 0.14400 0.09791 0.1752
566 0.10230 0.09251 0.05302 0.1590
567 0.27700 0.35140 0.15200 0.2397
568 0.04362 0.00000 0.00000 0.1587
mean fractal dimension ... worst texture worst perimeter worst area
0 0.07871 ... 17.33 184.60 2019.0 \
1 0.05667 ... 23.41 158.80 1956.0
2 0.05999 ... 25.53 152.50 1709.0
3 0.09744 ... 26.50 98.87 567.7
4 0.05883 ... 16.67 152.20 1575.0
.. ... ... ... ... ...
564 0.05623 ... 26.40 166.10 2027.0
565 0.05533 ... 38.25 155.00 1731.0
566 0.05648 ... 34.12 126.70 1124.0
567 0.07016 ... 39.42 184.60 1821.0
568 0.05884 ... 30.37 59.16 268.6
worst smoothness worst compactness worst concavity
0 0.16220 0.66560 0.7119 \
1 0.12380 0.18660 0.2416
2 0.14440 0.42450 0.4504
3 0.20980 0.86630 0.6869
4 0.13740 0.20500 0.4000
.. ... ... ...
564 0.14100 0.21130 0.4107
565 0.11660 0.19220 0.3215
566 0.11390 0.30940 0.3403
567 0.16500 0.86810 0.9387
568 0.08996 0.06444 0.0000
worst concave points worst symmetry worst fractal dimension target
0 0.2654 0.4601 0.11890 0
1 0.1860 0.2750 0.08902 0
2 0.2430 0.3613 0.08758 0
3 0.2575 0.6638 0.17300 0
4 0.1625 0.2364 0.07678 0
.. ... ... ... ...
564 0.2216 0.2060 0.07115 0
565 0.1628 0.2572 0.06637 0
566 0.1418 0.2218 0.07820 0
567 0.2650 0.4087 0.12400 0
568 0.0000 0.2871 0.07039 1
[569 rows x 31 columns]
-------------- Information ---------------
Dataset name: pandas.core.frame.DataFrame
nFeatures (nAttributes, with the labels): 31
nInstances (nObservations): 569
nLabels: 2
number of instances selected: 1
----------------------------------------------
instance: [1.799e+01 1.038e+01 1.228e+02 1.001e+03 1.184e-01 2.776e-01 3.001e-01
1.471e-01 2.419e-01 7.871e-02 1.095e+00 9.053e-01 8.589e+00 1.534e+02
6.399e-03 4.904e-02 5.373e-02 1.587e-02 3.003e-02 6.193e-03 2.538e+01
1.733e+01 1.846e+02 2.019e+03 1.622e-01 6.656e-01 7.119e-01 2.654e-01
4.601e-01 1.189e-01]
prediction: 0
explainer = Explainer.initialize(model, instance=instance)
direct = explainer.direct_reason()
print("len direct reason:", len(direct))
sufficient = explainer.sufficient_reason()
print("len sufficient reason:", len(sufficient))
print("to_features:", explainer.to_features(sufficient))
len direct reason: 294
len sufficient reason: 159
to_features: ('mean radius > 15.045000076293945', 'mean texture <= 11.585000038146973', 'mean perimeter > 96.57999801635742', 'mean area > 694.5', 'mean smoothness > 0.09075499698519707', 'mean compactness > 0.09524999931454659', 'mean concavity > 0.17409999668598175', 'mean concave points > 0.07939000055193901', 'mean symmetry > 0.12639999762177467', 'radius error > 0.7730999886989594', 'texture error > 0.7377500236034393', 'perimeter error > 2.76200008392334', 'area error > 33.064998626708984', 'smoothness error in ]0.005567499902099371, 0.009928999934345484]', 'compactness error > 0.00834800023585558', 'concavity error in ]0.018459999933838844, 0.2157999947667122]', 'fractal dimension error in ]0.0030724999960511923, 0.012140000239014626]', 'worst radius > 17.72499942779541', 'worst texture in ]15.434999942779541, 18.289999961853027]', 'worst perimeter > 120.70000076293945', 'worst area > 953.7000122070312', 'worst smoothness > 0.1363999992609024', 'worst concavity > 0.4524500072002411', 'worst concave points > 0.16029999405145645', 'worst symmetry > 0.37139999866485596', 'worst fractal dimension > 0.10035499930381775')
Setting
learner.feature_namesallows theto_featuresmethod to display the correct feature names. If not set, the feature names will be of the form f1, f2, f3, …, f30, where the numbers correspond to the rank of the feature in the dataset.
Load/Save From Libraries
The creation of ML models and the calculation of explanations are done by two different programs. You can save them using the first one and load them using the second one.
Scikit-learn
After importing a Scikit-learn model into PyXAI using import_models, you can save it with save and reload it later with load.
from pyxai import Learning
from sklearn import datasets
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier()
X, Y = datasets.load_breast_cancer(return_X_y=True)
rf.fit(X, Y)
learner, model = Learning.ModelIO.import_models(rf, instances_type='tabular')
Learning.ModelIO.save(model, "my_models/")
You can reload this model in another program using load:
from pyxai import Learning
learner, model = Learning.ModelIO.load("my_models/")
XGBoost
After importing an XGBoost model into PyXAI using import_models, you can save it with save and reload it later with load. See the XGBoost documentation for the native format.
from pyxai import Learning
from sklearn import datasets
from xgboost import XGBClassifier
X, Y = datasets.load_iris(return_X_y=True)
bt = XGBClassifier(eval_metric="mlogloss")
bt.fit(X, Y)
learner, model = Learning.ModelIO.import_models(bt, instances_type='tabular')
Learning.ModelIO.save(model, "my_models/")
You can reload this model in another program using load:
from pyxai import Learning
learner, model = Learning.ModelIO.load("my_models/")
LightGBM
After importing a LightGBM model into PyXAI using import_models, you can save it with save and reload it later with load. See the LightGBM documentation for the native format.
from pyxai import Learning
from sklearn import datasets
import lightgbm
X, Y = datasets.load_iris(return_X_y=True)
lgbm = lightgbm.LGBMRegressor(n_estimators=5, random_state=0)
lgbm.fit(X, Y)
learner, model = Learning.ModelIO.import_models(lgbm, instances_type='tabular')
Learning.ModelIO.save(model, "my_models/")
You can reload this model in another program using load:
from pyxai import Learning
learner, model = Learning.ModelIO.load("my_models/")
Example with cross-validation
This example shows how to import models and compute explanations. We start by implementing a function to process the dataset:
import pandas
import numpy
def load_dataset(dataset):
data = pandas.read_csv(dataset).copy()
# extract labels
labels = data[data.columns[-1]]
labels = numpy.array(labels)
# remove the label of each instance
data = data.drop(columns=[data.columns[-1]])
# extract the feature names
feature_names = list(data.columns)
return data.values, labels, feature_names
Then, we implement a function performing cross-validation. More precisely, we use the Leave One Group Out cross-validator of Scikit-learn and a lightgbm.LGBMRegressor from the LightGBM library:
import functools
import random
import operator
import lightgbm
from sklearn.model_selection import LeaveOneGroupOut
def cross_validation(X, Y, n_trees=100, n_forests=2) :
n_instance = len(Y)
quotient = n_instance // n_forests
remain = n_instance % n_forests
# Groups creation
groups = [quotient*[i] for i in range(1,n_forests+1)]
groups = functools.reduce(operator.iconcat, groups, [])
groups += [i for i in range(1,remain+1)]
random.shuffle(groups)
# Variable definition
loo = LeaveOneGroupOut()
forests = []
i = 0
for index_training, index_test in loo.split(X, Y, groups=groups):
if i < n_forests:
i += 1
# Creation of instances (X) and labels (Y) according to the index of loo.split()
# for both training and test set
x_train = [X[x] for x in index_training]
y_train = [Y[x] for x in index_training]
x_test = [X[x] for x in index_test]
y_test = [Y[x] for x in index_test]
# Training phase
learner = lightgbm.LGBMRegressor(n_estimators=5, random_state=0)
learner.fit(x_train, y_train)
# Get the classifier prediction of the test set
y_predict = learner.predict(x_test)
forests.append((learner, index_training, index_test))
return forests
Finally, we use the two previous functions and import the models into PyXAI to compute explanations.
from pyxai import Learning, Explainer
data, labels, feature_names = load_dataset("../dataset/winequality-red.csv")
results = cross_validation(data, labels, n_trees=5)
models = [result[0] for result in results]
training_indexes = [result[1] for result in results]
test_indexes = [result[2] for result in results]
learner, models = Learning.ModelIO.import_models(models, instances_type='tabular')
for i, model in enumerate(models):
instances = learner.get_instances(dataset="../dataset/winequality-red.csv", model=model, n=2, indexes=Learning.TEST, test_indexes=test_indexes[i])
for (instance, prediction_classifier) in instances:
explainer = Explainer.initialize(model, instance=instance)
prediction = model.predict_instance(instance)
print("prediction:", prediction)
direct = explainer.direct_reason()
print("len direct reason:", len(direct))
explainer.set_interval(prediction - 0.2, prediction + 0.2)
ts = explainer.tree_specific_reason()
print("len tree_specific_reason:", len(ts))
print("---------------------------")
With PyXAI, you can also generate your own models. See the Generating Models page for more information.