Classifier

Inspector functionality specific to classification models

Binary Classification

import sklearn.datasets
from sklearn import metrics
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split

from model_inspector import get_inspector
X, y = sklearn.datasets.load_breast_cancer(return_X_y=True, as_frame=True)
X_train, X_test, y_train, y_test = train_test_split(X, y)
inspector = get_inspector(
    RandomForestClassifier().fit(X_train, y_train),
    X_test,
    y_test,
)
/Users/greg/repos/model_inspector/model_inspector/inspect/any_model.py:56: UserWarning: `model` does not have the `feature_names_in_`
                attribute, so we cannot confirm that `model`'s feature
                names match `X`'s column names. Proceed at your own
                risk!
                
  warnings.warn(

source

_BinInspector.calculate_metrics_by_thresh

 _BinInspector.calculate_metrics_by_thresh
                                            (metrics:Union[Callable,Sequen
                                            ce[Callable]], thresholds:Opti
                                            onal[Sequence]=None)

Calculate classification metrics as a function of threshold

Assumes that self.model has a .predict_proba() method. Uses self.y as ground-truth values, self.model.predict_proba(self.X)[:, 1] > thresh as predictions.

Parameters:

  • metrics: Callables that take y_true, y_pred as positional arguments and return a number. Must have a __name__ attribute.
  • thresholds: Sequence of float threshold values to use. By default uses 0 and the values that appear in y_prob[:, 1], which is a minimal set that covers all of the relevant possibilities. One reason to override that default would be to save time with a large dataset.

Returns: DataFrame with one column “thresh” indicating the thresholds used and an additional column for each input metric giving the value of that metric at that threshold.

metrics_by_thresh = inspector.calculate_metrics_by_thresh(
    metrics=[metrics.precision_score, metrics.recall_score, metrics.f1_score],
).iloc[
    :-1
]  # dropping last row where precision is undefined
with pd.option_context("display.max_rows", 10):
    display(metrics_by_thresh)  # noqa: F821
 43%|████▎     | 18/42 [00:00<00:00, 178.48it/s]/Users/greg/.pyenv/versions/model_inspector/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 due to no predicted samples. Use `zero_division` parameter to control this behavior.
  _warn_prf(average, modifier, msg_start, len(result))
100%|██████████| 42/42 [00:00<00:00, 232.76it/s]
thresh precision_score recall_score f1_score
0 0.00 0.713115 1.000000 0.832536
1 0.00 0.713115 1.000000 0.832536
2 0.01 0.737288 1.000000 0.848780
3 0.02 0.756522 1.000000 0.861386
4 0.04 0.783784 1.000000 0.878788
... ... ... ... ...
36 0.94 1.000000 0.747126 0.855263
37 0.96 1.000000 0.701149 0.824324
38 0.97 1.000000 0.643678 0.783217
39 0.98 1.000000 0.563218 0.720588
40 0.99 1.000000 0.459770 0.629921

41 rows × 4 columns

ax = metrics_by_thresh.plot(x="thresh")


source

_BinInspector.plot_pr_curve

 _BinInspector.plot_pr_curve
                              (ax:Optional[matplotlib.axes._axes.Axes]=Non
                              e, pos_label=None, sample_weight=None)

Plot the precision-recall curve.

Parameters:

  • ax: Matplotlib Axes object. Plot will be added to this object if provided; otherwise a new Axes object will be generated.

Remaining parameters are passed to model_inspector.tune.plot_pr_curve.

ax = inspector.plot_pr_curve()


source

_BinInspector.confusion_matrix

 _BinInspector.confusion_matrix (thresh:float=0.5, labels=None,
                                 sample_weight=None, normalize=None)

Get confusion matrix

Assumes that self.model has a .predict_proba() method. Uses self.y as ground-truth values, self.model.predict_proba(self.X)[:, 1] > thresh as predictions.

If output is not rendering properly when you reopen a notebook, make sure the notebook is trusted.

Parameters:

  • thresh: Probability threshold for counting a prediction as positive

Remaining parameters are passed to sklearn.metrics._classification.confusion_matrix.

inspector.confusion_matrix(
    thresh=metrics_by_thresh.loc[metrics_by_thresh.f1_score.idxmax(), "thresh"]
)
  Predicted 0 Predicted 1 Totals
Actual 0 53 3 56
Actual 1 1 86 87
Totals 54 89 143

Multiclass Classification

from functools import partial

from model_inspector.tune import calculate_metric_ignoring_nan, coverage
precision_ignoring_nan = partial(
    calculate_metric_ignoring_nan,
    metric=partial(metrics.precision_score, average="micro"),
)
precision_ignoring_nan.__name__ = "precision_ignoring_nan"

X, y = sklearn.datasets.load_iris(return_X_y=True, as_frame=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=2)
inspector = get_inspector(
    RandomForestClassifier().fit(X_train.iloc[:, [3]], y_train),
    X_test.iloc[:, [3]],
    y_test,
)
/Users/greg/repos/model_inspector/model_inspector/inspect/any_model.py:56: UserWarning: `model` does not have the `feature_names_in_`
                attribute, so we cannot confirm that `model`'s feature
                names match `X`'s column names. Proceed at your own
                risk!
                
  warnings.warn(

source

_MultiInspector.calculate_metrics_by_thresh

 _MultiInspector.calculate_metrics_by_thresh
                                              (metrics:Union[Callable,Sequ
                                              ence[Callable]], thresholds:
                                              Optional[Sequence]=None)

Calculate classification metrics as a function of threshold

Assumes that self.model has a .predict_proba() method. Uses self.y as ground-truth values, uses the value with the highest probability as the prediction if that probability exceeds the threshold, np.nan otherwise.

Parameters:

  • metrics: Callables that take y_true, y_pred as positional arguments and return a number. Must have a __name__ attribute and must be able to handle np.nan values.
  • thresholds: Sequence of float threshold values to use. By default uses 0 and all values that appear in y_prob, which is a minimal set that covers all of the relevant possibilities. One reason to override that default would be to save time with a large dataset.

Returns: DataFrame with one column “thresh” indicating the thresholds used and an additional column for each input metric giving the value of that metric at that threshold.

metrics_by_thresh = inspector.calculate_metrics_by_thresh(
    metrics=[coverage, precision_ignoring_nan],
).iloc[
    :-1
]  # dropping last row where precision is undefined
metrics_by_thresh
  0%|          | 0/13 [00:00<?, ?it/s]/Users/greg/.pyenv/versions/model_inspector/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 due to no predicted samples. Use `zero_division` parameter to control this behavior.
  _warn_prf(average, modifier, msg_start, len(result))
100%|██████████| 13/13 [00:00<00:00, 2202.71it/s]
thresh coverage precision_ignoring_nan
0 0.000000 1.000000 0.947368
1 0.000000 1.000000 0.947368
2 0.023326 1.000000 0.947368
3 0.032452 1.000000 0.947368
4 0.107819 1.000000 0.947368
5 0.162547 1.000000 0.947368
6 0.191166 1.000000 0.947368
7 0.808834 0.947368 0.944444
8 0.837453 0.921053 0.942857
9 0.892181 0.815789 0.935484
10 0.967548 0.789474 0.966667
11 0.976674 0.736842 1.000000
ax = metrics_by_thresh.iloc[:-1].plot(x="thresh")


source

_MultiInspector.confusion_matrix

 _MultiInspector.confusion_matrix (cmap:str|Colormap='PuBu', low:float=0,
                                   high:float=0, axis:Axis|None=0,
                                   subset:Subset|None=None,
                                   text_color_threshold:float=0.408,
                                   vmin:float|None=None,
                                   vmax:float|None=None,
                                   gmap:Sequence|None=None)

Get confusion matrix

Uses self.y as ground-truth values, self.model.predict(self.X) as predictions.

If output is not rendering properly when you reopen a notebook, make sure the notebook is trusted.

Remaining parameters are passed to pandas.io.formats.style.background_gradient.

inspector.confusion_matrix()
  Predicted 0 Predicted 1 Predicted 2 Totals
Actual 0 16 0 0 16
Actual 1 0 10 1 11
Actual 2 0 1 10 11
Totals 16 11 11 38