Skip to content

Commit

Permalink
Improve error message in ColumnTransformer parser (#792)
Browse files Browse the repository at this point in the history
* Improves error message in ColumnTransformer parser
* fix attribute error
  • Loading branch information
xadupre authored Nov 25, 2021
1 parent 9330cde commit da34917
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 97 deletions.
15 changes: 13 additions & 2 deletions skl2onnx/_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,20 @@ def _parse_sklearn_simple_model(scope, model, inputs, custom_parsers=None,
variable = scope.declare_local_variable('variable', otype)
this_operator.outputs.append(variable)
else:
# We assume that all scikit-learn operator produce a single output.
if hasattr(model, 'get_feature_names_out'):
try:
out_names = model.get_feature_names_out()
except AttributeError:
# Catch a bug in scikit-learn.
out_names = None
this_operator.feature_names_out_ = out_names
if out_names is not None and len(out_names) == 0:
raise RuntimeError(
"get_feature_names_out() cannot return an empty value, "
"model is %r." % type(model))
input_type = guess_tensor_type(inputs[0].type)
variable = scope.declare_local_variable(
'variable', guess_tensor_type(inputs[0].type))
'variable', input_type)
this_operator.outputs.append(variable)

options = scope.get_options(model, dict(decision_path=False), fail=False)
Expand Down
12 changes: 9 additions & 3 deletions skl2onnx/_supported_operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


import warnings
import logging

# Calibrated classifier CV
from sklearn.calibration import CalibratedClassifierCV
Expand Down Expand Up @@ -241,6 +242,8 @@

from .common._registration import register_converter, register_shape_calculator

logger = logging.getLogger('skl2onnx')

# In most cases, scikit-learn operator produces only one output.
# However, each classifier has basically two outputs; one is the
# predicted label and the other one is the probabilities of all
Expand Down Expand Up @@ -505,9 +508,12 @@ def _get_sklearn_operator_name(model_type):
our conversion framework
"""
if model_type not in sklearn_operator_name_map:
# "No proper operator name found, it means a local operator.
return None
return sklearn_operator_name_map[model_type]
# No proper operator name found, it means a local operator.
alias = None
else:
alias = sklearn_operator_name_map[model_type]
logger.debug('[parsing] found alias=%r for type=%r.', alias, model_type)
return alias


def get_model_alias(model_type):
Expand Down
5 changes: 4 additions & 1 deletion skl2onnx/common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ def get_column_index(i, inputs):
"Unable to find column name %r among names %r. "
"Make sure the input names specified with parameter "
"initial_types fits the column names specified in the "
"pipeline to convert." % (i, [n.onnx_name for n in inputs]))
"pipeline to convert. This may happen because a "
"ColumnTransformer follows a transformer without "
"any mapped converter in a pipeline." % (
i, [n.onnx_name for n in inputs]))


def get_column_indices(indices, inputs, multiple):
Expand Down
111 changes: 24 additions & 87 deletions tests/test_sklearn_k_bins_discretiser_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,8 @@ def test_model_k_bins_discretiser_ordinal_uniform(self):
)
self.assertTrue(model_onnx is not None)
dump_data_and_model(
X.astype(np.float32),
model,
model_onnx,
basename="SklearnKBinsDiscretiserOrdinalUniform",
allow_failure="StrictVersion("
"onnxruntime.__version__)"
"<= StrictVersion('0.2.1')",
)
X.astype(np.float32), model, model_onnx,
basename="SklearnKBinsDiscretiserOrdinalUniform")

@unittest.skipIf(
KBinsDiscretizer is None,
Expand All @@ -67,14 +61,8 @@ def test_model_k_bins_discretiser_ordinal_quantile(self):
)
self.assertTrue(model_onnx is not None)
dump_data_and_model(
X.astype(np.float32),
model,
model_onnx,
basename="SklearnKBinsDiscretiserOrdinalQuantile",
allow_failure="StrictVersion("
"onnxruntime.__version__)"
"<= StrictVersion('0.2.1')",
)
X.astype(np.float32), model, model_onnx,
basename="SklearnKBinsDiscretiserOrdinalQuantile")

@unittest.skipIf(
KBinsDiscretizer is None,
Expand All @@ -98,14 +86,8 @@ def test_model_k_bins_discretiser_ordinal_kmeans(self):
)
self.assertTrue(model_onnx is not None)
dump_data_and_model(
X.astype(np.float32),
model,
model_onnx,
basename="SklearnKBinsDiscretiserOrdinalKMeans",
allow_failure="StrictVersion("
"onnxruntime.__version__)"
"<= StrictVersion('0.2.1')",
)
X.astype(np.float32), model, model_onnx,
basename="SklearnKBinsDiscretiserOrdinalKMeans")

@unittest.skipIf(
KBinsDiscretizer is None,
Expand All @@ -125,13 +107,8 @@ def test_model_k_bins_discretiser_onehot_dense_uniform(self):
)
self.assertTrue(model_onnx is not None)
dump_data_and_model(
X.astype(np.float32),
model,
model_onnx,
basename="SklearnKBinsDiscretiserOneHotDenseUniform",
allow_failure="StrictVersion(onnxruntime.__version__)"
"<= StrictVersion('0.2.1')",
)
X.astype(np.float32), model, model_onnx,
basename="SklearnKBinsDiscretiserOneHotDenseUniform")

@unittest.skipIf(
KBinsDiscretizer is None,
Expand All @@ -156,13 +133,8 @@ def test_model_k_bins_discretiser_onehot_dense_quantile(self):
)
self.assertTrue(model_onnx is not None)
dump_data_and_model(
X.astype(np.float32),
model,
model_onnx,
basename="SklearnKBinsDiscretiserOneHotDenseQuantile",
allow_failure="StrictVersion(onnxruntime.__version__)"
"<= StrictVersion('0.2.1')",
)
X.astype(np.float32), model, model_onnx,
basename="SklearnKBinsDiscretiserOneHotDenseQuantile")

@unittest.skipIf(
KBinsDiscretizer is None,
Expand All @@ -187,13 +159,8 @@ def test_model_k_bins_discretiser_onehot_dense_kmeans(self):
)
self.assertTrue(model_onnx is not None)
dump_data_and_model(
X.astype(np.float32),
model,
model_onnx,
basename="SklearnKBinsDiscretiserOneHotDenseKMeans",
allow_failure="StrictVersion(onnxruntime.__version__)"
"<= StrictVersion('0.2.1')",
)
X.astype(np.float32), model, model_onnx,
basename="SklearnKBinsDiscretiserOneHotDenseKMeans")

@unittest.skipIf(
KBinsDiscretizer is None,
Expand All @@ -212,13 +179,8 @@ def test_model_k_bins_discretiser_ordinal_uniform_int(self):
)
self.assertTrue(model_onnx is not None)
dump_data_and_model(
X.astype(np.int64),
model,
model_onnx,
basename="SklearnKBinsDiscretiserOrdinalUniformInt",
allow_failure="StrictVersion(onnxruntime.__version__)"
"<= StrictVersion('0.2.1')",
)
X.astype(np.int64), model, model_onnx,
basename="SklearnKBinsDiscretiserOrdinalUniformInt")

@unittest.skipIf(
KBinsDiscretizer is None,
Expand All @@ -241,13 +203,8 @@ def test_model_k_bins_discretiser_ordinal_quantile_int(self):
)
self.assertTrue(model_onnx is not None)
dump_data_and_model(
X.astype(np.int64),
model,
model_onnx,
basename="SklearnKBinsDiscretiserOrdinalQuantileInt",
allow_failure="StrictVersion(onnxruntime.__version__)"
"<= StrictVersion('0.2.1')",
)
X.astype(np.int64), model, model_onnx,
basename="SklearnKBinsDiscretiserOrdinalQuantileInt")

@unittest.skipIf(
KBinsDiscretizer is None,
Expand All @@ -268,13 +225,8 @@ def test_model_k_bins_discretiser_ordinal_kmeans_int(self):
)
self.assertTrue(model_onnx is not None)
dump_data_and_model(
X.astype(np.int64),
model,
model_onnx,
basename="SklearnKBinsDiscretiserOrdinalKMeansInt",
allow_failure="StrictVersion(onnxruntime.__version__)"
"<= StrictVersion('0.2.1')",
)
X.astype(np.int64), model, model_onnx,
basename="SklearnKBinsDiscretiserOrdinalKMeansInt")

@unittest.skipIf(
KBinsDiscretizer is None,
Expand All @@ -293,13 +245,8 @@ def test_model_k_bins_discretiser_onehot_dense_uniform_int(self):
)
self.assertTrue(model_onnx is not None)
dump_data_and_model(
X.astype(np.int64),
model,
model_onnx,
basename="SklearnKBinsDiscretiserOneHotDenseUniformInt",
allow_failure="StrictVersion(onnxruntime.__version__)"
"<= StrictVersion('0.2.1')",
)
X.astype(np.int64), model, model_onnx,
basename="SklearnKBinsDiscretiserOneHotDenseUniformInt")

@unittest.skipIf(
KBinsDiscretizer is None,
Expand All @@ -318,13 +265,8 @@ def test_model_k_bins_discretiser_onehot_dense_quantile_int(self):
)
self.assertTrue(model_onnx is not None)
dump_data_and_model(
X.astype(np.int64),
model,
model_onnx,
basename="SklearnKBinsDiscretiserOneHotDenseQuantileInt",
allow_failure="StrictVersion(onnxruntime.__version__)"
"<= StrictVersion('0.2.1')",
)
X.astype(np.int64), model, model_onnx,
basename="SklearnKBinsDiscretiserOneHotDenseQuantileInt")

@unittest.skipIf(
KBinsDiscretizer is None,
Expand All @@ -347,13 +289,8 @@ def test_model_k_bins_discretiser_onehot_dense_kmeans_int(self):
)
self.assertTrue(model_onnx is not None)
dump_data_and_model(
X.astype(np.int64),
model,
model_onnx,
basename="SklearnKBinsDiscretiserOneHotDenseKMeansInt",
allow_failure="StrictVersion(onnxruntime.__version__)"
"<= StrictVersion('0.2.1')",
)
X.astype(np.int64), model, model_onnx,
basename="SklearnKBinsDiscretiserOneHotDenseKMeansInt")


if __name__ == "__main__":
Expand Down
Loading

0 comments on commit da34917

Please sign in to comment.