Open In Colab

Residual Analysis (Classification)

Evaluate model residuals.

Installation

# To install the required package, use the following command:
# !pip install modeva

Authentication

# To get authentication, use the following command: (To get full access please replace the token to your own token)
# from modeva.utils.authenticate import authenticate
# authenticate(auth_code='eaaa4301-b140-484c-8e93-f9f633c8bacb')

Import modeva modules

from modeva import DataSet
from modeva import TestSuite
from modeva.models import MoLGBMClassifier

Load BikeSharing Dataset

ds = DataSet()
ds.load(name="TaiwanCredit")
ds.set_random_split()
ds.set_target("FlagDefault")

Fit a LGBM model

model = MoLGBMClassifier(name="LGBM-2", max_depth=2, verbose=-1, random_state=0)
model.fit(ds.train_x, ds.train_y.ravel())
MoLGBMClassifier(boosting_type='gbdt', class_weight=None, colsample_bytree=1.0,
                 importance_type='split', learning_rate=0.1, max_depth=2,
                 min_child_samples=20, min_child_weight=0.001,
                 min_split_gain=0.0, n_estimators=100, n_jobs=None,
                 num_leaves=31, objective=None, random_state=0, reg_alpha=0.0,
                 reg_lambda=0.0, subsample=1.0, subsample_for_bin=200000,
                 subsample_freq=0, verbose=-1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.


Analyzes residuals feature importance

ts = TestSuite(ds, model)
results = ts.diagnose_residual_interpret(dataset="train")
results.plot()


Visualize the residual against predictor

results = ts.diagnose_residual_analysis(features="PAY_1", dataset="train")
results.plot()


Visualize the residual against response variable

results = ts.diagnose_residual_analysis(features="FlagDefault", dataset="train")
results.plot()


Visualize the residual against model prediction (predict proba)

results = ts.diagnose_residual_analysis(use_prediction=True, dataset="train")
results.plot()


Interpret residual by a XGB depth-2 model

results = ts.diagnose_residual_interpret(dataset='test', n_estimators=100, max_depth=2)

XGB-2 feature performance

results.plot("feature_importance")


XGB-2 effect performance

results.plot("effect_importance")


Further interpretation (main effect plot)

ts_residual = results.value["TestSuite"]
ts_residual.interpret_effects("PAY_1", dataset="test").plot()


Further interpretation (local interpretation)

ts_residual.interpret_local_fi(sample_index=20).plot()


Random forest-based residual clustering analysis (absolute residual)

results = ts.diagnose_residual_cluster(
    dataset="test",
    response_type="abs_residual",
    metric="AUC",
    n_clusters=10,
    cluster_method="rf",
    sample_size=2000,
    n_estimators=100,
    max_depth=5,
)
results.table
AUC Size abs_residual
8 0.7154 546.0 0.4159
1 0.6771 505.0 0.4157
7 0.7873 303.0 0.3967
3 0.5774 395.0 0.3713
0 0.5578 828.0 0.3080
4 0.5983 580.0 0.2636
5 0.6240 397.0 0.2324
6 0.5773 353.0 0.2108
2 0.5649 572.0 0.1948
9 0.6507 1521.0 0.1457


Residual value for each cluster

results.plot("cluster_residual")


Performance metric for each cluster

results.plot("cluster_performance")


Feature importance of the random forest model

results.plot("feature_importance")


Analyze data drift for a specific cluster

data_results = ds.data_drift_test(
    **results.value["clusters"][0]["data_info"],
    distance_metric="PSI",
    psi_method="uniform",
    psi_bins=10
)
data_results.plot("summary")


data_results.plot(name=('density', 'PAY_1'))


Random forest-based residual clustering analysis (perturbed residual)

results = ts.diagnose_residual_cluster(
    dataset="test",
    response_type="abs_residual_perturb",
    metric="AUC",
    n_clusters=10,
    cluster_method="rf",
    sample_size=2000,
    n_estimators=100,
    max_depth=5,
)
results.table
AUC Size abs_residual_perturb
8 0.6163 402.0 0.4647
0 0.5702 267.0 0.4251
4 0.7641 451.0 0.3942
6 0.5864 1374.0 0.3819
7 0.5843 324.0 0.3788
5 0.5081 207.0 0.3488
9 0.5652 816.0 0.3040
3 0.6097 518.0 0.2948
1 0.6311 1305.0 0.2389
2 0.5840 336.0 0.1384


Random forest-based residual clustering analysis (prediction interval width)

results = ts.diagnose_residual_cluster(
    dataset="test",
    response_type="pi_width",
    metric="AUC",
    n_clusters=10,
    cluster_method="rf",
    sample_size=2000,
    n_estimators=100,
    max_depth=5,
)
results.table
AUC Size pi_width
3 0.5111 62.0 1.9839
5 0.4744 73.0 1.9589
0 0.7062 436.0 1.9472
6 0.5538 68.0 1.2941
2 0.5236 110.0 1.2000
4 0.4581 94.0 1.1809
7 0.5564 56.0 1.1786
1 0.6386 355.0 1.0873
8 0.5405 109.0 1.0459
9 0.6352 1637.0 1.0006


Compare residuals cluster of multiple models

benchmark = MoLGBMClassifier(name="LGBM-5", max_depth=5, verbose=-1, random_state=0)
benchmark.fit(ds.train_x, ds.train_y.ravel())

tsc = TestSuite(ds, models=[model, benchmark])
results = tsc.compare_residual_cluster(dataset="test")
results.table
LGBM-2 LGBM-5
AUC size AUC size
0 0.2120 268.0 0.2768 268.0
7 0.5834 784.0 0.5862 784.0
2 0.5985 644.0 0.6451 644.0
9 0.3919 455.0 0.4526 455.0
3 0.3846 643.0 0.4567 643.0
8 0.3664 700.0 0.4727 700.0
6 0.4594 562.0 0.5297 562.0
1 0.2993 705.0 0.4142 705.0
5 0.3790 794.0 0.3205 794.0
4 NaN 445.0 NaN 445.0


results.plot("cluster_performance")


Total running time of the script: (0 minutes 36.145 seconds)

Gallery generated by Sphinx-Gallery