Repository: onnx/sklearn-onnx

Issue:
Conversion of HistGradientBoosting fails with scikit-learn 0.24



Discussion:

Resolving patch:
diff --git a/skl2onnx/common/tree_ensemble.py b/skl2onnx/common/tree_ensemble.py
--- a/skl2onnx/common/tree_ensemble.py
+++ b/skl2onnx/common/tree_ensemble.py
@@ -208,7 +208,10 @@ def add_tree_to_attribute_pairs_hist_gradient_boosting(
         else:
             mode = 'BRANCH_LEQ'
             feat_id = node['feature_idx']
-            threshold = node['threshold']
+            try:
+                threshold = node['threshold']
+            except ValueError:
+                threshold = node['num_threshold']
             left_child_id = node['left']
             right_child_id = node['right']
             missing = node['missing_go_to_left']


Test patch:
diff --git a/docs/tests/test_documentation_examples.py b/docs/tests/test_documentation_examples.py
--- a/docs/tests/test_documentation_examples.py
+++ b/docs/tests/test_documentation_examples.py
@@ -7,6 +7,7 @@
 import sys
 import importlib
 import subprocess
+import numpy
 import onnxruntime
 
 
diff --git a/docs/tests/test_documentation_tutorial.py b/docs/tests/test_documentation_tutorial.py
--- a/docs/tests/test_documentation_tutorial.py
+++ b/docs/tests/test_documentation_tutorial.py
@@ -2,10 +2,13 @@
 Tests examples from the documentation.
 """
 import unittest
+from distutils.version import StrictVersion
 import os
 import sys
 import importlib
 import subprocess
+import numpy
+import onnxruntime
 
 
 def import_source(module_file_path, module_name):
diff --git a/tests/test_sklearn_random_forest_converters.py b/tests/test_sklearn_random_forest_converters.py
--- a/tests/test_sklearn_random_forest_converters.py
+++ b/tests/test_sklearn_random_forest_converters.py
@@ -693,7 +693,8 @@ def test_randomforestclassifier_decision_path(self):
         initial_types = [('input', FloatTensorType((None, X.shape[1])))]
         model_onnx = convert_sklearn(
             model, initial_types=initial_types,
-            options={id(model): {'decision_path': True, 'zipmap': False}})
+            options={id(model): {'decision_path': True, 'zipmap': False}},
+            target_opset=TARGET_OPSET)
         sess = InferenceSession(model_onnx.SerializeToString())
         res = sess.run(None, {'input': X.astype(numpy.float32)})
         pred = model.predict(X)
@@ -709,14 +710,15 @@ def test_randomforestclassifier_decision_path(self):
                      reason="Requires ONNX-ML extension.")
     @unittest.skipIf(TARGET_OPSET < 12, reason="LabelEncoder")
     def test_extratreesclassifier_decision_path(self):
-        model = ExtraTreesClassifier(max_depth=2, n_estimators=2)
+        model = ExtraTreesClassifier(max_depth=2, n_estimators=3)
         X, y = make_classification(10, n_features=4, random_state=42)
         X = X[:, :2]
         model.fit(X, y)
         initial_types = [('input', FloatTensorType((None, X.shape[1])))]
         model_onnx = convert_sklearn(
             model, initial_types=initial_types,
-            options={id(model): {'decision_path': True, 'zipmap': False}})
+            options={id(model): {'decision_path': True, 'zipmap': False}},
+            target_opset=TARGET_OPSET)
         sess = InferenceSession(model_onnx.SerializeToString())
         res = sess.run(None, {'input': X.astype(numpy.float32)})
         pred = model.predict(X)