diff --git a/python/interpret-core/interpret/utils/_compressed_dataset.py b/python/interpret-core/interpret/utils/_compressed_dataset.py index 16d36fa59..e50cc1be3 100644 --- a/python/interpret-core/interpret/utils/_compressed_dataset.py +++ b/python/interpret-core/interpret/utils/_compressed_dataset.py @@ -5,7 +5,7 @@ import numpy as np -from ._clean_x import unify_columns, categorical_encode +from ._clean_x import categorical_encode, unify_columns from ._native import Native _log = logging.getLogger(__name__) diff --git a/python/interpret-core/interpret/utils/_native.py b/python/interpret-core/interpret/utils/_native.py index e181fe645..01c673935 100644 --- a/python/interpret-core/interpret/utils/_native.py +++ b/python/interpret-core/interpret/utils/_native.py @@ -8,7 +8,6 @@ import platform import struct import sys -import math from contextlib import AbstractContextManager from math import prod @@ -17,6 +16,14 @@ _log = logging.getLogger(__name__) +def _boolebm(val): + """Convert `bool` to `np.int32` used by libebm to represents `bool`.""" + if not isinstance(val, (bool, np.bool_)): + msg = f"Native EBM functions expect boolean, got f{type(val)}" + raise TypeError(msg) + return np.int32(val) + + class Native: # see notes in libebm.h on the maximum representable int64 in float64 format FLOAT64_TO_INT64_MAX = 9223372036854774784 @@ -574,7 +581,7 @@ def cut_quantile(self, X_col, min_samples_bin, is_rounded, max_cuts): X_col.shape[0], Native._make_pointer(X_col, np.float64), min_samples_bin, - is_rounded, + _boolebm(is_rounded), ct.byref(count_cuts), Native._make_pointer(cuts, np.float64), ) @@ -657,9 +664,9 @@ def measure_dataset_header(self, n_features, n_weights, n_targets): def measure_feature(self, n_bins, is_missing, is_unseen, is_nominal, bin_indexes): n_bytes = self._unsafe.MeasureFeature( n_bins, - is_missing, - is_unseen, - is_nominal, + _boolebm(is_missing), + _boolebm(is_unseen), + _boolebm(is_nominal), len(bin_indexes), Native._make_pointer(bin_indexes, np.int64), ) @@ -711,9 +718,9 @@ def fill_feature( ): return_code = self._unsafe.FillFeature( n_bins, - is_missing, - is_unseen, - is_nominal, + _boolebm(is_missing), + _boolebm(is_unseen), + _boolebm(is_nominal), len(bin_indexes), Native._make_pointer(bin_indexes, np.int64), dataset.nbytes,