예제 #1
0
class TestOneVsRestClassifierConverter(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ova(self):
        model = OneVsRestClassifier(LogisticRegression())
        dump_multiple_classification(
            model,
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ova_02(self):
        model = OneVsRestClassifier(LogisticRegression())
        dump_multiple_classification(
            model,
            first_class=2,
            suffix="F2",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ova_string(self):
        model = OneVsRestClassifier(LogisticRegression())
        dump_multiple_classification(
            model,
            verbose=False,
            label_string=True,
            suffix="String",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )
예제 #2
0
class TestSklearnDictVectorizerConverter(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_dict_vectorizer(self):
        model = DictVectorizer()
        data = [{"amy": 1.0, "chin": 200.0}, {"nice": 3.0, "amy": 1.0}]
        model.fit_transform(data)
        model_onnx = convert_sklearn(model, "dictionary vectorizer", [(
            "input",
            DictionaryType(StringTensorType([1]), FloatTensorType([1])),
        )])
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            data,
            model,
            model_onnx,
            basename="SklearnDictVectorizer-OneOff-SkipDim1",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.1.3') or "
            "StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3.0')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_dict_vectorizer_sort_false(self):
        model = DictVectorizer(sparse=False, sort=False)
        data = [{1: 1.0, 2: 200.0}, {1: 3.0, 3: 1.0}]
        model.fit_transform(data)
        model_onnx = convert_sklearn(
            model,
            "dictionary vectorizer",
            [(
                "input",
                DictionaryType(Int64TensorType([1]), FloatTensorType([1])),
            )],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            data,
            model,
            model_onnx,
            basename="SklearnDictVectorizerSortFalse-OneOff-SkipDim1",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.1.3') or "
            "StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3.0')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_dict_vectorizer_issue(self):
        key_value_map = [{1: 'A', 2: 'B'}, {1: 'C', 3: 'D'}, {1: 'C', 3: 'A'}]
        model = DictVectorizer(sparse=False).fit(key_value_map)
        with self.assertRaises(RuntimeError):
            convert_sklearn(model, 'dv',
                            [("input",
                              DictionaryType(Int64TensorType([1]),
                                             StringTensorType([1])))])
class TestSklearnDecisionTreeModels(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_decision_tree_classifier(self):
        model = DecisionTreeClassifier()
        dump_one_class_classification(
            model,
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure=
            "StrictVersion(onnx.__version__) < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")
        dump_binary_classification(
            model,
            allow_failure=
            "StrictVersion(onnx.__version__) < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")
        dump_multiple_classification(
            model,
            allow_failure=
            "StrictVersion(onnx.__version__) < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")

    def test_decision_tree_regressor(self):
        model = DecisionTreeRegressor()
        dump_single_regression(
            model,
            allow_failure=
            "StrictVersion(onnx.__version__) < StrictVersion('1.2')")
        dump_multiple_regression(
            model,
            allow_failure=
            "StrictVersion(onnx.__version__) < StrictVersion('1.2')")
예제 #4
0
class TestSklearnDictVectorizerConverter(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_dict_vectorizer(self):
        model = DictVectorizer()
        data = [{"amy": 1.0, "chin": 200.0}, {"nice": 3.0, "amy": 1.0}]
        model.fit_transform(data)
        model_onnx = convert_sklearn(
            model,
            "dictionary vectorizer",
            [(
                "input",
                DictionaryType(StringTensorType([1]), FloatTensorType([1])),
            )],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            data,
            model,
            model_onnx,
            basename="SklearnDictVectorizer-OneOff-SkipDim1",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.1.3') or "
            "StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3.0')",
        )
class TestSklearnGradientBoostingModels(unittest.TestCase):

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gradient_boosting_classifier(self):
        model = GradientBoostingClassifier(n_estimators=3)
        dump_binary_classification(model)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gradient_boosting_classifier_multi(self):
        model = GradientBoostingClassifier(n_estimators=3)
        dump_multiple_classification(model,
                                     allow_failure="StrictVersion(onnxruntime.__version__)"
                                                   "<= StrictVersion('0.3.0')")

    def _fit_regression_model(self, model):
        X, y = make_regression(n_features=4, random_state=42)
        model.fit(X, y)
        return model, X.astype(np.float32)

    def test_gradient_boosting_regressor_ls_loss(self):
        model, X = self._fit_regression_model(GradientBoostingRegressor(n_estimators=3, loss='ls'))
        model_onnx = convert_sklearn(model, 'gradient boosting regression', [('input', FloatTensorType([1, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(X, model, model_onnx, basename="SklearnGradientBoostingRegressionLsLoss")

    def test_gradient_boosting_regressor_lad_loss(self):
        model, X = self._fit_regression_model(GradientBoostingRegressor(n_estimators=3, loss='lad'))
        model_onnx = convert_sklearn(model, 'gradient boosting regression', [('input', FloatTensorType([1, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(X, model, model_onnx, basename="SklearnGradientBoostingRegressionLadLoss")

    def test_gradient_boosting_regressor_huber_loss(self):
        model, X = self._fit_regression_model(GradientBoostingRegressor(n_estimators=3, loss='huber'))
        model_onnx = convert_sklearn(model, 'gradient boosting regression', [('input', FloatTensorType([1, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(X, model, model_onnx, basename="SklearnGradientBoostingRegressionHuberLoss")

    def test_gradient_boosting_regressor_quantile_loss(self):
        model, X = self._fit_regression_model(GradientBoostingRegressor(n_estimators=3, loss='quantile'))
        model_onnx = convert_sklearn(model, 'gradient boosting regression', [('input', FloatTensorType([1, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(X, model, model_onnx, basename="SklearnGradientBoostingRegressionQuantileLoss")
예제 #6
0
class TestSklearnDictVectorizerConverter(unittest.TestCase):

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_dict_vectorizer(self):
        model = DictVectorizer()
        data = [{'amy': 1., 'chin': 200.}, {'nice': 3., 'amy': 1.}]
        model.fit_transform(data)
        model_onnx = convert_sklearn(model, 'dictionary vectorizer',
                                     [('input', DictionaryType(StringTensorType([1]), FloatTensorType([1])))])
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(data, model, model_onnx, basename="SklearnDictVectorizer-OneOff-SkipDim1",
                            allow_failure="StrictVersion(onnxruntime.__version__) <= StrictVersion('0.1.3') or StrictVersion(onnx.__version__) < StrictVersion('1.3.0')")
class TestSklearnFunctionTransformerConverter(unittest.TestCase):
    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer introduced in 0.20",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_function_transformer(self):
        def convert_dataframe_schema(df, drop=None):
            inputs = []
            for k, v in zip(df.columns, df.dtypes):
                if drop is not None and k in drop:
                    continue
                if v == "int64":
                    t = Int64TensorType([1, 1])
                elif v == "float64":
                    t = FloatTensorType([1, 1])
                else:
                    t = StringTensorType([1, 1])
                inputs.append((k, t))
            return inputs

        data = load_iris()
        X = data.data[:, :2]
        y = data.target
        data = pandas.DataFrame(X, columns=["X1", "X2"])

        pipe = Pipeline(steps=[
            (
                "select",
                ColumnTransformer([("id", FunctionTransformer(),
                                    ["X1", "X2"])]),
            ),
            ("logreg", LogisticRegression()),
        ])
        pipe.fit(data[["X1", "X2"]], y)

        inputs = convert_dataframe_schema(data)
        model_onnx = convert_sklearn(pipe, "scikit-learn function_transformer",
                                     inputs)
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            data[:5],
            pipe,
            model_onnx,
            basename="SklearnFunctionTransformer-DF",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.3') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )
class TestSklearnTfidfVectorizerSparse(unittest.TestCase):

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(StrictVersion(onnx.__version__) <= StrictVersion('1.4.1'),
                     # issue with encoding
                     reason="https://github.com/onnx/onnx/pull/1734")
    def test_model_tfidf_transform_bug(self):        
        categories = ['alt.atheism', 'soc.religion.christian', 'comp.graphics', 'sci.med']
        twenty_train = fetch_20newsgroups(subset='train', categories=categories,
                                          shuffle=True, random_state=0)
        text_clf = Pipeline([('vect', CountVectorizer()), ('tfidf', TfidfTransformer())])
        twenty_train.data[0] = "bruît " + twenty_train.data[0]
        text_clf.fit(twenty_train.data, twenty_train.target)
        model_onnx = convert_sklearn(text_clf, name='DocClassifierCV-Tfidf',
                                     initial_types=[('input', StringTensorType())])
        dump_data_and_model(twenty_train.data[:10], text_clf, model_onnx,
                            basename="SklearnPipelineTfidfTransformer",
                            # Operator mul is not implemented in onnxruntime
                            allow_failure="StrictVersion(onnx.__version__) <= StrictVersion('1.4.1')")
class TestSklearnTfidfVectorizerSparse(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        StrictVersion(onnx.__version__) <= StrictVersion("1.4.1"),
        # issue with encoding
        reason="https://github.com/onnx/onnx/pull/1734")
    @unittest.skipIf(StrictVersion(ort.__version__) <= StrictVersion("0.2.1"),
                     reason="sparse not supported")
    def test_model_tfidf_transform_bug(self):
        categories = [
            "alt.atheism",
            "soc.religion.christian",
            "comp.graphics",
            "sci.med",
        ]
        twenty_train = fetch_20newsgroups(subset="train",
                                          categories=categories,
                                          shuffle=True,
                                          random_state=0)
        text_clf = Pipeline([("vect", CountVectorizer()),
                             ("tfidf", TfidfTransformer())])
        twenty_train.data[0] = "bruît " + twenty_train.data[0]
        text_clf.fit(twenty_train.data, twenty_train.target)
        model_onnx = convert_sklearn(text_clf,
                                     name="DocClassifierCV-Tfidf",
                                     initial_types=[("input",
                                                     StringTensorType([5]))],
                                     target_opset=TARGET_OPSET)
        dump_data_and_model(
            twenty_train.data[5:10],
            text_clf,
            model_onnx,
            basename="SklearnPipelineTfidfTransformer",
            # Operator mul is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " <= StrictVersion('1.5')",
        )
예제 #10
0
class TestSklearnPipeline(unittest.TestCase):
    def test_pipeline(self):
        data = numpy.array([[0, 0], [0, 0], [1, 1], [1, 1]],
                           dtype=numpy.float32)
        scaler = StandardScaler()
        scaler.fit(data)
        model = Pipeline([("scaler1", scaler), ("scaler2", scaler)])

        model_onnx = convert_sklearn(model, "pipeline",
                                     [("input", FloatTensorType([None, 2]))])
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(data,
                            model,
                            model_onnx,
                            basename="SklearnPipelineScaler")

    def test_combine_inputs(self):
        data = numpy.array(
            [[0.0, 0.0], [0.0, 0.0], [1.0, 1.0], [1.0, 1.0]],
            dtype=numpy.float32,
        )
        scaler = StandardScaler()
        scaler.fit(data)
        model = Pipeline([("scaler1", scaler), ("scaler2", scaler)])

        model_onnx = convert_sklearn(
            model,
            "pipeline",
            [
                ("input1", FloatTensorType([None, 1])),
                ("input2", FloatTensorType([None, 1])),
            ],
        )
        self.assertTrue(len(model_onnx.graph.node[-1].output) == 1)
        self.assertTrue(model_onnx is not None)
        data = {"input1": data[:, 0], "input2": data[:, 1]}
        dump_data_and_model(
            data,
            PipeConcatenateInput(model),
            model_onnx,
            basename="SklearnPipelineScaler11-OneOff",
        )

    def test_combine_inputs_union_in_pipeline(self):
        from sklearn.preprocessing import StandardScaler
        from sklearn.pipeline import Pipeline

        data = numpy.array(
            [[0.0, 0.0], [0.0, 0.0], [1.0, 1.0], [1.0, 1.0]],
            dtype=numpy.float32,
        )
        model = Pipeline([
            ("scaler1", StandardScaler()),
            (
                "union",
                FeatureUnion([
                    ("scaler2", StandardScaler()),
                    ("scaler3", MinMaxScaler()),
                ]),
            ),
        ])
        model.fit(data)
        model_onnx = convert_sklearn(
            model,
            "pipeline",
            [
                ("input1", FloatTensorType([None, 1])),
                ("input2", FloatTensorType([None, 1])),
            ],
        )
        self.assertTrue(len(model_onnx.graph.node[-1].output) == 1)
        self.assertTrue(model_onnx is not None)
        data = {"input1": data[:, 0], "input2": data[:, 1]}
        dump_data_and_model(
            data,
            PipeConcatenateInput(model),
            model_onnx,
            basename="SklearnPipelineScaler11Union-OneOff",
        )

    def test_combine_inputs_floats_ints(self):
        data = [[0, 0.0], [0, 0.0], [1, 1.0], [1, 1.0]]
        scaler = StandardScaler()
        scaler.fit(data)
        model = Pipeline([("scaler1", scaler), ("scaler2", scaler)])

        model_onnx = convert_sklearn(
            model,
            "pipeline",
            [
                ("input1", Int64TensorType([None, 1])),
                ("input2", FloatTensorType([None, 1])),
            ],
        )
        self.assertTrue(len(model_onnx.graph.node[-1].output) == 1)
        self.assertTrue(model_onnx is not None)
        data = numpy.array(data)
        data = {
            "input1": data[:, 0].astype(numpy.int64),
            "input2": data[:, 1].astype(numpy.float32),
        }
        dump_data_and_model(
            data,
            PipeConcatenateInput(model),
            model_onnx,
            basename="SklearnPipelineScalerMixed-OneOff",
        )

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(StrictVersion(ort_version) <= StrictVersion("0.4.0"),
                     reason="issues with shapes")
    def test_pipeline_column_transformer(self):

        iris = datasets.load_iris()
        X = iris.data[:, :3]
        y = iris.target
        X_train = pandas.DataFrame(X, columns=["vA", "vB", "vC"])
        X_train["vcat"] = X_train["vA"].apply(lambda x: "cat1"
                                              if x > 0.5 else "cat2")
        X_train["vcat2"] = X_train["vB"].apply(lambda x: "cat3"
                                               if x > 0.5 else "cat4")
        y_train = y % 2
        numeric_features = [0, 1, 2]  # ["vA", "vB", "vC"]
        categorical_features = [3, 4]  # ["vcat", "vcat2"]

        classifier = LogisticRegression(
            C=0.01,
            class_weight=dict(zip([False, True], [0.2, 0.8])),
            n_jobs=1,
            max_iter=10,
            solver="lbfgs",
            tol=1e-3,
        )

        numeric_transformer = Pipeline(steps=[
            ("imputer", SimpleImputer(strategy="median")),
            ("scaler", StandardScaler()),
        ])

        categorical_transformer = Pipeline(steps=[
            (
                "onehot",
                OneHotEncoder(sparse=True, handle_unknown="ignore"),
            ),
            (
                "tsvd",
                TruncatedSVD(n_components=1, algorithm="arpack", tol=1e-4),
            ),
        ])

        preprocessor = ColumnTransformer(transformers=[
            ("num", numeric_transformer, numeric_features),
            ("cat", categorical_transformer, categorical_features),
        ])

        model = Pipeline(steps=[("precprocessor",
                                 preprocessor), ("classifier", classifier)])

        model.fit(X_train, y_train)
        initial_type = [
            ("numfeat", FloatTensorType([None, 3])),
            ("strfeat", StringTensorType([None, 2])),
        ]

        X_train = X_train[:11]
        model_onnx = convert_sklearn(model, initial_types=initial_type)

        dump_data_and_model(
            X_train,
            model,
            model_onnx,
            basename="SklearnPipelineColumnTransformerPipeliner",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.3') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.4.0')",
        )

        if __name__ == "__main__":
            from onnx.tools.net_drawer import GetPydotGraph, GetOpNodeProducer

            pydot_graph = GetPydotGraph(
                model_onnx.graph,
                name=model_onnx.graph.name,
                rankdir="TP",
                node_producer=GetOpNodeProducer("docstring"),
            )
            pydot_graph.write_dot("graph.dot")

            import os

            os.system("dot -O -G=300 -Tpng graph.dot")

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        not check_scikit_version(),
        reason="Scikit 0.20 causes some mismatches",
    )
    def test_pipeline_column_transformer_titanic(self):

        # fit
        titanic_url = (
            "https://raw.githubusercontent.com/amueller/"
            "scipy-2017-sklearn/091d371/notebooks/datasets/titanic3.csv")
        data = pandas.read_csv(titanic_url)
        X = data.drop("survived", axis=1)
        y = data["survived"]

        # SimpleImputer on string is not available for string
        # in ONNX-ML specifications.
        # So we do it beforehand.
        for cat in ["embarked", "sex", "pclass"]:
            X[cat].fillna("missing", inplace=True)

        X_train, X_test, y_train, y_test = train_test_split(X,
                                                            y,
                                                            test_size=0.2)

        numeric_features = ["age", "fare"]
        numeric_transformer = Pipeline(steps=[
            ("imputer", SimpleImputer(strategy="median")),
            ("scaler", StandardScaler()),
        ])

        categorical_features = ["embarked", "sex", "pclass"]
        categorical_transformer = Pipeline(steps=[
            # --- SimpleImputer on string is not available
            # for string in ONNX-ML specifications.
            # ('imputer',
            #  SimpleImputer(strategy='constant', fill_value='missing')),
            ("onehot", OneHotEncoder(handle_unknown="ignore"))
        ])

        preprocessor = ColumnTransformer(transformers=[
            ("num", numeric_transformer, numeric_features),
            ("cat", categorical_transformer, categorical_features),
        ])

        clf = Pipeline(steps=[
            ("preprocessor", preprocessor),
            ("classifier", LogisticRegression(solver="lbfgs")),
        ])

        # inputs

        def convert_dataframe_schema(df, drop=None):
            inputs = []
            for k, v in zip(df.columns, df.dtypes):
                if drop is not None and k in drop:
                    continue
                if v == "int64":
                    t = Int64TensorType([None, 1])
                elif v == "float64":
                    t = FloatTensorType([None, 1])
                else:
                    t = StringTensorType([None, 1])
                inputs.append((k, t))
            return inputs

        to_drop = {
            "parch",
            "sibsp",
            "cabin",
            "ticket",
            "name",
            "body",
            "home.dest",
            "boat",
        }
        X_train = X_train.drop(to_drop, axis=1)
        X_test = X_test.drop(to_drop, axis=1)
        clf.fit(X_train, y_train)
        X_train["pclass"] = X_train["pclass"].astype(str)
        X_test["pclass"] = X_test["pclass"].astype(str)
        inputs = convert_dataframe_schema(X_train, to_drop)
        model_onnx = convert_sklearn(clf, "pipeline_titanic", inputs)

        dump_data_and_model(
            X_test[:5],
            clf,
            model_onnx,
            basename="SklearnPipelineColumnTransformerPipelinerTitanic-DF",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.3') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_column_transformer_weights(self):
        model, X = fit_classification_model(
            ColumnTransformer(
                [('pca', PCA(n_components=5), slice(0, 10)),
                 ('svd', TruncatedSVD(n_components=5), slice(10, 100))],
                transformer_weights={'pca': 2, 'svd': 3}), 3)
        model_onnx = convert_sklearn(
            model,
            "column transformer weights",
            [("input", FloatTensorType([None, X.shape[1]]))],
            dtype=numpy.float32,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnColumnTransformerWeights",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_column_transformer_drop(self):
        model, X = fit_classification_model(
            ColumnTransformer(
                [('pca', PCA(n_components=5), slice(0, 10)),
                 ('svd', TruncatedSVD(n_components=5), slice(80, 100))],
                remainder='drop'), 3)
        model_onnx = convert_sklearn(
            model,
            "column transformer drop",
            [("input", FloatTensorType([None, X.shape[1]]))],
            dtype=numpy.float32,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnColumnTransformerDrop",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_column_transformer_passthrough(self):
        model, X = fit_classification_model(
            ColumnTransformer(
                [('pca', PCA(n_components=5), slice(0, 10)),
                 ('svd', TruncatedSVD(n_components=5), slice(80, 100))],
                transformer_weights={'pca': 2, 'svd': 3},
                remainder='passthrough'), 3)
        model_onnx = convert_sklearn(
            model,
            "column transformer passthrough",
            [("input", FloatTensorType([None, X.shape[1]]))],
            dtype=numpy.float32,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnColumnTransformerPassthrough",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_column_transformer_passthrough_no_weights(self):
        model, X = fit_classification_model(
            ColumnTransformer(
                [('pca', PCA(n_components=5), slice(0, 10)),
                 ('svd', TruncatedSVD(n_components=5), slice(70, 80))],
                remainder='passthrough'), 3)
        model_onnx = convert_sklearn(
            model,
            "column transformer passthrough",
            [("input", FloatTensorType([None, X.shape[1]]))],
            dtype=numpy.float32,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnColumnTransformerPassthroughNoWeights",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )
class TestSklearnCalibratedClassifierCVConverters(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_calibrated_classifier_cv_float(self):
        data = load_iris()
        X, y = data.data, data.target
        clf = MultinomialNB().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method="sigmoid").fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn CalibratedClassifierCVMNB",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnCalibratedClassifierCVFloat",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_calibrated_classifier_cv_float_nozipmap(self):
        data = load_iris()
        X, y = data.data, data.target
        clf = MultinomialNB().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method="sigmoid").fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn CalibratedClassifierCVMNB",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET,
            options={id(model): {
                         'zipmap': False
                     }})
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnCalibratedClassifierCVFloatNoZipMap",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_calibrated_classifier_cv_int(self):
        data = load_digits()
        X, y = data.data, data.target
        clf = MultinomialNB().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method="sigmoid").fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn CalibratedClassifierCVMNB",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.int64),
            model,
            model_onnx,
            basename="SklearnCalibratedClassifierCVInt-Dec4",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        StrictVersion(onnxruntime.__version__) < StrictVersion("0.5.0"),
        reason="not available")
    def test_model_calibrated_classifier_cv_isotonic_float(self):
        data = load_iris()
        X, y = data.data, data.target
        clf = KNeighborsClassifier().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method="isotonic").fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn CalibratedClassifierCVKNN",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        try:
            dump_data_and_model(
                X.astype(np.float32),
                model,
                model_onnx,
                basename="SklearnCalibratedClassifierCVIsotonicFloat")
        except Exception as e:
            raise AssertionError(
                "Issue with model\n{}".format(model_onnx)) from e

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_calibrated_classifier_cv_binary(self):
        data = load_iris()
        X, y = data.data, data.target
        y[y > 1] = 1
        clf = MultinomialNB().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method="sigmoid").fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn CalibratedClassifierCV",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnCalibratedClassifierCVBinaryMNB",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        StrictVersion(onnxruntime.__version__) < StrictVersion("0.5.0"),
        reason="not available")
    def test_model_calibrated_classifier_cv_isotonic_binary(self):
        data = load_iris()
        X, y = data.data, data.target
        y[y > 1] = 1
        clf = KNeighborsClassifier().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method="isotonic").fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn CalibratedClassifierCV",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnCalibratedClassifierCVIsotonicBinaryKNN")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        StrictVersion(onnxruntime.__version__) < StrictVersion("0.5.0"),
        reason="not available")
    def test_model_calibrated_classifier_cv_logistic_regression(self):
        data = load_iris()
        X, y = data.data, data.target
        y[y > 1] = 1
        model = CalibratedClassifierCV(base_estimator=LogisticRegression(),
                                       method='sigmoid').fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "unused", [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnCalibratedClassifierCVBinaryLogReg",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        StrictVersion(onnxruntime.__version__) < StrictVersion("0.5.0"),
        reason="not available")
    def test_model_calibrated_classifier_cv_rf(self):
        data = load_iris()
        X, y = data.data, data.target
        y[y > 1] = 1
        model = CalibratedClassifierCV(
            base_estimator=RandomForestClassifier(n_estimators=2),
            method='sigmoid').fit(X, y)
        try:
            convert_sklearn(model, "unused",
                            [("input", FloatTensorType([None, X.shape[1]]))])
            raise AssertionError(
                "RandomForestClassifier has no decision_function")
        except RuntimeError as e:
            assert "cannot implement decision_function" in str(e)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        StrictVersion(onnxruntime.__version__) < StrictVersion("0.5.0"),
        reason="not available")
    @unittest.skipIf(apply_less is None, reason="onnxconverter-common old")
    def test_model_calibrated_classifier_cv_svc(self):
        data = load_iris()
        X, y = data.data, data.target
        model = CalibratedClassifierCV(base_estimator=SVC(),
                                       method='sigmoid').fit(X, y)
        model_onnx = convert_sklearn(
            model, "unused", [("input", FloatTensorType([None, X.shape[1]]))])
        assert model_onnx is not None
class TestSklearnPLSRegressionConverters(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_pls_regression(self):
        X = numpy.array(
            [[0., 0., 1.], [1., 0., 0.], [2., 2., 2.], [2., 5., 4.]],
            numpy.float32)
        Y = numpy.array([[0.1, -0.2], [0.9, 1.1], [6.2, 5.9], [11.9, 12.3]],
                        numpy.float32)
        pls2 = PLSRegression(n_components=2)
        pls2.fit(X, Y)
        model_onnx = convert_sklearn(
            pls2,
            "scikit-learn pls",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X,
            pls2,
            model_onnx,
            methods=['predict'],
            basename="SklearnPLSRegression",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_pls_regression64(self):
        X = numpy.array(
            [[0., 0., 1.], [1., 0., 0.], [2., 2., 2.], [2., 5., 4.]],
            numpy.float64)
        Y = numpy.array([[0.1, -0.2], [0.9, 1.1], [6.2, 5.9], [11.9, 12.3]],
                        numpy.float64)
        pls2 = PLSRegression(n_components=2)
        pls2.fit(X, Y)
        model_onnx = convert_sklearn(
            pls2,
            "scikit-learn pls64",
            [("input", DoubleTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X,
            pls2,
            model_onnx,
            methods=['predict'],
            basename="SklearnPLSRegression64",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_pls_regressionInt64(self):
        X = numpy.array(
            [[0., 0., 1.], [1., 0., 0.], [2., 2., 2.], [2., 5., 4.]],
            numpy.int64)
        Y = numpy.array([[0.1, -0.2], [0.9, 1.1], [6.2, 5.9], [11.9, 12.3]],
                        numpy.int64)
        pls2 = PLSRegression(n_components=2)
        pls2.fit(X, Y)
        model_onnx = convert_sklearn(
            pls2,
            "scikit-learn plsint64",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X,
            pls2,
            model_onnx,
            methods=['predict'],
            basename="SklearnPLSRegressionInt64",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')")
예제 #13
0
class TestVotingClassifierConverter(unittest.TestCase):
    def test_operator_mul(self):

        model = CustomTransform()
        Xd = numpy.array([[1, 2], [3, 4], [4, 5]])
        exp = model.transform(Xd)

        model_onnx = convert_sklearn(
            model,
            'CustomTransform', [('input', FloatTensorType([3, Xd.shape[1]]))],
            custom_shape_calculators={
                CustomTransform: custom_transform_shape_calculator
            },
            custom_conversion_functions={
                CustomTransform: custom_tranform_converter
            })
        dump_data_and_model(
            Xd.astype(numpy.float32),
            model,
            model_onnx,
            basename="CustomTransformerMul",
            allow_failure=
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_voting_hard_binary(self):
        model = VotingClassifier(voting='hard',
                                 flatten_transform=False,
                                 estimators=[
                                     ('lr', LogisticRegression()),
                                     ('lr2',
                                      LogisticRegression(fit_intercept=False))
                                 ])
        # predict_proba is not defined when voting is hard.
        dump_binary_classification(
            model,
            suffix='Hard-OneOffArray',
            comparable_outputs=[0],
            allow_failure=
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_voting_hard_binary_weights(self):
        model = VotingClassifier(voting='hard',
                                 flatten_transform=False,
                                 weights=numpy.array([1000, 1]),
                                 estimators=[
                                     ('lr', LogisticRegression()),
                                     ('lr2',
                                      LogisticRegression(fit_intercept=False))
                                 ])
        # predict_proba is not defined when voting is hard.
        dump_binary_classification(
            model,
            suffix='WeightsHard-OneOffArray',
            comparable_outputs=[0],
            allow_failure=
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_voting_soft_binary(self):
        model = VotingClassifier(voting='soft',
                                 flatten_transform=False,
                                 estimators=[
                                     ('lr', LogisticRegression()),
                                     ('lr2',
                                      LogisticRegression(fit_intercept=False))
                                 ])
        dump_binary_classification(
            model,
            suffix='Soft-OneOffArray',
            comparable_outputs=[0, 1],
            allow_failure=
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_voting_soft_binary_weighted(self):
        model = VotingClassifier(voting='soft',
                                 flatten_transform=False,
                                 weights=numpy.array([1.8, 0.2]),
                                 estimators=[
                                     ('lr', LogisticRegression()),
                                     ('lr2',
                                      LogisticRegression(fit_intercept=False))
                                 ])
        dump_binary_classification(
            model,
            suffix='WeightedSoft-OneOffArray',
            allow_failure=
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_voting_hard_multi(self):
        # predict_proba is not defined when voting is hard.
        model = VotingClassifier(voting='hard',
                                 flatten_transform=False,
                                 estimators=[('lr', LogisticRegression()),
                                             ('lr2', DecisionTreeClassifier())
                                             ])
        dump_multiple_classification(
            model,
            suffix='Hard-OneOffArray',
            comparable_outputs=[0],
            allow_failure=
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_voting_hard_multi_weighted(self):
        # predict_proba is not defined when voting is hard.
        model = VotingClassifier(voting='hard',
                                 flatten_transform=False,
                                 weights=numpy.array([1000, 1]),
                                 estimators=[('lr', LogisticRegression()),
                                             ('lr2', DecisionTreeClassifier())
                                             ])
        dump_multiple_classification(
            model,
            suffix='WeightedHard-OneOffArray',
            comparable_outputs=[0],
            allow_failure=
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_voting_soft_multi(self):
        model = VotingClassifier(voting='soft',
                                 flatten_transform=False,
                                 estimators=[('lr', LogisticRegression()),
                                             ('lr2', LogisticRegression())])
        dump_multiple_classification(
            model,
            suffix='Soft-OneOffArray',
            allow_failure=
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_voting_soft_multi_weighted(self):
        model = VotingClassifier(voting='soft',
                                 flatten_transform=False,
                                 weights=numpy.array([1.8, 0.2]),
                                 estimators=[('lr', LogisticRegression()),
                                             ('lr2', LogisticRegression())])
        dump_multiple_classification(
            model,
            suffix='WeightedSoft-OneOffArray',
            allow_failure=
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_voting_soft_multi_weighted4(self):
        model = VotingClassifier(voting='soft',
                                 flatten_transform=False,
                                 weights=numpy.array([2.7, 0.3, 0.5, 0.5]),
                                 estimators=[('lr', LogisticRegression()),
                                             ('lra', LogisticRegression()),
                                             ('lrb', LogisticRegression()),
                                             ('lr2', LogisticRegression())])
        dump_multiple_classification(
            model,
            suffix='Weighted4Soft-OneOffArray',
            allow_failure=
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_voting_soft_multi_weighted42(self):
        model = VotingClassifier(voting='soft',
                                 flatten_transform=False,
                                 weights=numpy.array([27, 0.3, 0.5, 0.5]),
                                 estimators=[('lr', LogisticRegression()),
                                             ('lra', LogisticRegression()),
                                             ('lrb', LogisticRegression()),
                                             ('lr2', LogisticRegression())])
        dump_multiple_classification(
            model,
            suffix='Weighted42Soft-OneOffArray',
            allow_failure=
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1')")
class TestGLMClassifierConverter(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_binary_class(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(max_iter=100), 2)
        model_onnx = convert_sklearn(
            model,
            "logistic regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionBinary",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )
        if StrictVersion(ort_version) >= StrictVersion("1.0.0"):
            sess = InferenceSession(model_onnx.SerializeToString())
            out = sess.get_outputs()
            lb = out[0].type
            sh = out[0].shape
            self.assertEqual(str(lb), "tensor(int64)")
            self.assertEqual(sh, [None])

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_binary_class_string(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(max_iter=100),
            2,
            label_string=True)
        model_onnx = convert_sklearn(
            model,
            "logistic regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionBinary",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )
        if StrictVersion(ort_version) >= StrictVersion("1.0.0"):
            sess = InferenceSession(model_onnx.SerializeToString())
            out = sess.get_outputs()
            lb = out[0].type
            sh = out[0].shape
            self.assertEqual(str(lb), "tensor(string)")
            self.assertEqual(sh, [None])

    def test_model_logistic_regression_int(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(max_iter=100), 3, is_int=True)
        model_onnx = convert_sklearn(
            model,
            "logistic regression",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionInt",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    def test_model_logistic_regression_bool(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(max_iter=100), 3, is_bool=True)
        model_onnx = convert_sklearn(
            model,
            "logistic regression",
            [("input", BooleanTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionBool",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_linear_discriminant_analysis(self):
        X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
        y = np.array([1, 1, 1, 2, 2, 2])
        X_test = np.array([[-0.8, -1], [-2, -1]], dtype=np.float32)
        model = LinearDiscriminantAnalysis().fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "linear model",
            [("input", FloatTensorType([None, X_test.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnLinearDiscriminantAnalysisBin-Dec3",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_linear_discriminant_analysis_decfunc(self):
        X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
        y = np.array([1, 1, 1, 2, 2, 2])
        X_test = np.array([[-0.8, -1], [0, 1]], dtype=np.float32)
        model = LinearDiscriminantAnalysis().fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "linear model",
            [("input", FloatTensorType([None, X_test.shape[1]]))],
            options={id(model): {
                         'raw_scores': True
                     }},
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnLinearDiscriminantAnalysisBinRawScore-Out0",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
            methods=['predict', 'decision_function'])

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_linear_discriminant_analysis_decfunc3(self):
        X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
        y = np.array([1, 1, 1, 2, 2, 3])
        X_test = np.array([[-0.8, -1], [0, 1]], dtype=np.float32)
        model = LinearDiscriminantAnalysis().fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "linear model",
            [("input", FloatTensorType([None, X_test.shape[1]]))],
            options={id(model): {
                         'raw_scores': True
                     }},
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnLinearDiscriminantAnalysisBinRawScore3-Out0",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
            methods=['predict', 'decision_function'])

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_cv_binary_class(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegressionCV(max_iter=100), 2)
        model_onnx = convert_sklearn(
            model,
            "logistic regression cv",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticCVRegressionBinary",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_cv_int(self):
        try:
            model, X = fit_classification_model(
                linear_model.LogisticRegressionCV(max_iter=100),
                7,
                is_int=True)
        except AttributeError:
            # AttributeError: 'str' object has no attribute 'decode'
            # Bug fixed in scikit-learn 0.24 due to a warning using encoding.
            return
        model_onnx = convert_sklearn(
            model,
            "logistic regression cv",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionCVInt",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_cv_bool(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegressionCV(max_iter=100), 3, is_bool=True)
        model_onnx = convert_sklearn(
            model,
            "logistic regression cv",
            [("input", BooleanTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionCVBool",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_binary_class_nointercept(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(fit_intercept=False,
                                            max_iter=10000), 2)
        model_onnx = convert_sklearn(
            model, "logistic regression",
            [("input", FloatTensorType([None, X.shape[1]]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionBinaryNoIntercept",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(max_iter=10000), 4)
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMulti",
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_nocl(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(max_iter=10000),
            4,
            label_string=True)
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options={id(model): {
                         'nocl': True
                     }})
        self.assertIsNotNone(model_onnx)
        sonx = str(model_onnx)
        assert 'classlabels_strings' not in sonx
        assert 'cl0' not in sonx
        dump_data_and_model(X,
                            model,
                            model_onnx,
                            classes=model.classes_,
                            basename="SklearnLogitisticRegressionMultiNoCl",
                            allow_failure="StrictVersion(onnx.__version__)"
                            " < StrictVersion('1.2') or "
                            "StrictVersion(onnxruntime.__version__)"
                            " <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_ovr(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(multi_class='ovr', max_iter=10000),
            3)
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMulti",
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_multinomial(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(multi_class="multinomial",
                                            solver="lbfgs",
                                            max_iter=10000), 4)
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMulti",
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_no_intercept(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(fit_intercept=False,
                                            max_iter=10000), 3)
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMultiNoIntercept",
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_lbfgs(self):
        penalty = ('l2'
                   if _sklearn_version() < StrictVersion('0.21.0') else 'none')
        model, X = fit_classification_model(
            linear_model.LogisticRegression(solver='lbfgs',
                                            penalty=penalty,
                                            max_iter=10000), 5)
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMultiLbfgs",
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_liblinear_l1(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(solver='liblinear',
                                            penalty='l1',
                                            max_iter=10000), 4)
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMultiLiblinearL1",
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_saga_elasticnet(self):
        if _sklearn_version() < StrictVersion('0.21.0'):
            model, X = fit_classification_model(
                linear_model.LogisticRegression(solver='saga', max_iter=10000),
                3)
        else:
            model, X = fit_classification_model(
                linear_model.LogisticRegression(solver='saga',
                                                penalty='elasticnet',
                                                l1_ratio=0.1,
                                                max_iter=10000), 3)
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMultiSagaElasticnet",
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_linear_svc_binary_class(self):
        model, X = fit_classification_model(LinearSVC(max_iter=10000), 2)
        model_onnx = convert_sklearn(
            model, "linear SVC",
            [("input", FloatTensorType([None, X.shape[1]]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLinearSVCBinary-NoProb",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_linear_svc_multi_class(self):
        model, X = fit_classification_model(LinearSVC(max_iter=100), 5)
        model_onnx = convert_sklearn(
            model,
            "multi-class linear SVC",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLinearSVCMulti",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_linear_svc_int(self):
        model, X = fit_classification_model(LinearSVC(max_iter=100),
                                            5,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "multi-class linear SVC",
            [("input", Int64TensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLinearSVCInt",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_linear_svc_bool(self):
        model, X = fit_classification_model(LinearSVC(max_iter=100),
                                            5,
                                            is_bool=True)
        model_onnx = convert_sklearn(
            model,
            "multi-class linear SVC",
            [("input", BooleanTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnLinearSVCBool",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_ridge_classifier_binary(self):
        model, X = fit_classification_model(linear_model.RidgeClassifier(), 2)
        model_onnx = convert_sklearn(
            model,
            "binary ridge classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRidgeClassifierBin",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_ridge_classifier_binary_nozipmap(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(max_iter=10000), 2)

        model_onnx = convert_sklearn(
            model, "binary ridge classifier",
            [("input", FloatTensorType([None, X.shape[1]]))])
        assert 'zipmap' in str(model_onnx).lower()

        options = {id(model): {'zipmap': True}}
        model_onnx = convert_sklearn(
            model,
            "binary ridge classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options=options)
        assert 'zipmap' in str(model_onnx).lower()

        options = {id(model): {'zipmap': False}}
        model_onnx = convert_sklearn(
            model,
            "binary ridge classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options=options)
        assert 'zipmap' not in str(model_onnx).lower()

        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRidgeClassifierNZMBin",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_ridge_classifier_binary_mispelled_zipmap(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(max_iter=10000), 2)

        options = {id(model): {'zipmap ': True}}
        try:
            convert_sklearn(model,
                            "binary ridge classifier",
                            [("input", FloatTensorType([None, X.shape[1]]))],
                            options=options)
            raise AssertionError("Expecting an error.")
        except NameError as e:
            assert "Option 'zipmap ' not in" in str(e)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_ridge_classifier_binary_mispelled_zipmap_wrong_value(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(max_iter=10000), 2)

        options = {id(model): {'zipmap': 'True'}}
        try:
            convert_sklearn(model,
                            "binary ridge classifier",
                            [("input", FloatTensorType([None, X.shape[1]]))],
                            options=options)
            raise AssertionError("Expecting an error.")
        except ValueError as e:
            assert "Unexpected value ['True'] for option 'zipmap'" in str(e)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_ridge_classifier_multi_class(self):
        model, X = fit_classification_model(linear_model.RidgeClassifier(), 5)
        model_onnx = convert_sklearn(
            model,
            "multi-class ridge classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRidgeClassifierMulti",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_ridge_classifier_int(self):
        model, X = fit_classification_model(linear_model.RidgeClassifier(),
                                            5,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "multi-class ridge classifier",
            [("input", Int64TensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRidgeClassifierInt",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_ridge_classifier_bool(self):
        model, X = fit_classification_model(linear_model.RidgeClassifier(),
                                            4,
                                            is_bool=True)
        model_onnx = convert_sklearn(
            model,
            "multi-class ridge classifier",
            [("input", BooleanTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRidgeClassifierBool",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_ridge_classifier_cv_binary(self):
        model, X = fit_classification_model(linear_model.RidgeClassifierCV(),
                                            2)
        model_onnx = convert_sklearn(
            model,
            "binary ridge classifier cv",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRidgeClassifierCVBin",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_ridge_classifier_cv_int(self):
        model, X = fit_classification_model(linear_model.RidgeClassifierCV(),
                                            2,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "binary ridge classifier cv",
            [("input", Int64TensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRidgeClassifierCVInt",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_ridge_classifier_cv_bool(self):
        model, X = fit_classification_model(linear_model.RidgeClassifierCV(),
                                            2,
                                            is_bool=True)
        model_onnx = convert_sklearn(
            model,
            "binary ridge classifier cv",
            [("input", BooleanTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRidgeClassifierCVBool",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_ridge_classifier_cv_multi_class(self):
        model, X = fit_classification_model(linear_model.RidgeClassifierCV(),
                                            5)
        model_onnx = convert_sklearn(
            model,
            "multi-class ridge classifier cv",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRidgeClassifierCVMulti",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_binary_class_decision_function(self):
        model, X = fit_classification_model(
            linear_model.LogisticRegression(max_iter=10000), 2)
        model_onnx = convert_sklearn(
            model,
            "logistic regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options={linear_model.LogisticRegression: {
                'raw_scores': True
            }})
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X[:5],
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionBinaryRawScore",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.3') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
            methods=['predict', 'decision_function_binary'])

    @unittest.skip(reason="Scikit-learn doesn't return multi-label output.")
    def test_model_ridge_classifier_cv_multilabel(self):
        model, X_test = fit_multilabel_classification_model(
            linear_model.RidgeClassifierCV(random_state=42))
        model_onnx = convert_sklearn(
            model,
            "scikit-learn RidgeClassifierCV",
            [("input", FloatTensorType([None, X_test.shape[1]]))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnRidgeClassifierCVMultiLabel",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(StrictVersion(onnx.__version__) < StrictVersion('1.6'),
                     reason="Requires onnx 1.6")
    def test_model_classifier_multi_zipmap_columns(self):
        model, X = fit_classification_model(linear_model.LogisticRegression(),
                                            3,
                                            n_features=4,
                                            label_string=True)
        model_onnx = convert_sklearn(
            model,
            "multi-class ridge classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options={linear_model.LogisticRegression: {
                'zipmap': 'columns'
            }},
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        sess = InferenceSession(model_onnx.SerializeToString())
        names = [_.name for _ in sess.get_outputs()]
        self.assertEqual(['output_label', 'scl0', 'scl1', 'scl2'], names)
        xt = X[:10].astype(np.float32)
        got = sess.run(None, {'input': xt})
        prob = model.predict_proba(xt)
        for i in range(prob.shape[1]):
            assert_almost_equal(prob[:, i], got[i + 1])

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(StrictVersion(onnx.__version__) < StrictVersion('1.6'),
                     reason="Requires onnx 1.6")
    def test_model_classifier_multi_class_string_zipmap_columns(self):
        model, X = fit_classification_model(linear_model.LogisticRegression(),
                                            3,
                                            n_features=4,
                                            label_string=False)
        model_onnx = convert_sklearn(
            model,
            "multi-class ridge classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options={linear_model.LogisticRegression: {
                'zipmap': 'columns'
            }},
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        sess = InferenceSession(model_onnx.SerializeToString())
        names = [_.name for _ in sess.get_outputs()]
        self.assertEqual(['output_label', 'i0', 'i1', 'i2'], names)
        xt = X[:10].astype(np.float32)
        got = sess.run(None, {'input': xt})
        prob = model.predict_proba(xt)
        for i in range(prob.shape[1]):
            assert_almost_equal(prob[:, i], got[i + 1])
class TestSklearnCalibratedClassifierCVConverters(unittest.TestCase):

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_calibrated_classifier_cv_float(self):
        data = load_iris()
        X, y = data.data, data.target
        clf = LinearSVC(C=0.001).fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method='sigmoid').fit(X, y)
        model_onnx = convert_sklearn(
            model, 'scikit-learn CalibratedClassifierCV',
            [('input', FloatTensorType(X.shape))])
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.float32), model, model_onnx,
            basename="SklearnCalibratedClassifierCVFloat",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_calibrated_classifier_cv_int(self):
        data = load_digits()
        X, y = data.data, data.target
        clf = LinearSVC(C=0.001).fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method='sigmoid').fit(X, y)
        model_onnx = convert_sklearn(
            model, 'scikit-learn CalibratedClassifierCV',
            [('input', Int64TensorType(X.shape))])
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.int64), model, model_onnx,
            basename="SklearnCalibratedClassifierCVInt",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_calibrated_classifier_cv_isotonic_float(self):
        data = load_iris()
        X, y = data.data, data.target
        clf = KNeighborsClassifier().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method='isotonic').fit(X, y)
        model_onnx = convert_sklearn(
            model, 'scikit-learn CalibratedClassifierCV',
            [('input', FloatTensorType([1, X.shape[1]]))])
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.float32), model, model_onnx,
            basename="SklearnCalibratedClassifierCVIsotonicFloat-OneOffArray",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1') or "
            "StrictVersion(onnx.__version__) == StrictVersion('1.4.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_calibrated_classifier_cv_binary(self):
        data = load_iris()
        X, y = data.data, data.target
        y[y > 1] = 1
        clf = LinearSVC(C=0.001).fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method='sigmoid').fit(X, y)
        model_onnx = convert_sklearn(
            model, 'scikit-learn CalibratedClassifierCV',
            [('input', FloatTensorType(X.shape))])
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.float32), model, model_onnx,
            basename="SklearnCalibratedClassifierCVBinary",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_calibrated_classifier_cv_isotonic_binary(self):
        data = load_iris()
        X, y = data.data, data.target
        y[y > 1] = 1
        clf = KNeighborsClassifier().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method='isotonic').fit(X, y)
        model_onnx = convert_sklearn(
            model, 'scikit-learn CalibratedClassifierCV',
            [('input', FloatTensorType([1, X.shape[1]]))])
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.float32), model, model_onnx,
            basename="SklearnCalibratedClassifierCVIsotonicBinary-OneOffArray",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1') or "
            "StrictVersion(onnx.__version__) == StrictVersion('1.4.1')")
class TestSklearnPipeline(unittest.TestCase):
    def test_pipeline(self):
        data = numpy.array([[0, 0], [0, 0], [1, 1], [1, 1]],
                           dtype=numpy.float32)
        scaler = StandardScaler()
        scaler.fit(data)
        model = Pipeline([("scaler1", scaler), ("scaler2", scaler)])

        model_onnx = convert_sklearn(model, "pipeline",
                                     [("input", FloatTensorType([None, 2]))])
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(data,
                            model,
                            model_onnx,
                            basename="SklearnPipelineScaler")

    def test_combine_inputs(self):
        data = numpy.array(
            [[0.0, 0.0], [0.0, 0.0], [1.0, 1.0], [1.0, 1.0]],
            dtype=numpy.float32,
        )
        scaler = StandardScaler()
        scaler.fit(data)
        model = Pipeline([("scaler1", scaler), ("scaler2", scaler)])

        model_onnx = convert_sklearn(
            model,
            "pipeline",
            [
                ("input1", FloatTensorType([None, 1])),
                ("input2", FloatTensorType([None, 1])),
            ],
        )
        self.assertTrue(len(model_onnx.graph.node[-1].output) == 1)
        self.assertTrue(model_onnx is not None)
        data = {
            "input1": data[:, 0].reshape((-1, 1)),
            "input2": data[:, 1].reshape((-1, 1)),
        }
        dump_data_and_model(
            data,
            PipeConcatenateInput(model),
            model_onnx,
            basename="SklearnPipelineScaler11",
        )

    @unittest.skipIf(
        StrictVersion(ort_version) <= StrictVersion('0.4.0'),
        reason="onnxruntime too old")
    def test_combine_inputs_union_in_pipeline(self):
        from sklearn.preprocessing import StandardScaler
        from sklearn.pipeline import Pipeline

        data = numpy.array(
            [[0.0, 0.0], [0.0, 0.0], [1.0, 1.0], [1.0, 1.0]],
            dtype=numpy.float32,
        )
        model = Pipeline([
            ("scaler1", StandardScaler()),
            (
                "union",
                FeatureUnion([
                    ("scaler2", StandardScaler()),
                    ("scaler3", MinMaxScaler()),
                ]),
            ),
        ])
        model.fit(data)
        model_onnx = convert_sklearn(
            model,
            "pipeline",
            [
                ("input1", FloatTensorType([None, 1])),
                ("input2", FloatTensorType([None, 1])),
            ],
        )
        self.assertTrue(len(model_onnx.graph.node[-1].output) == 1)
        self.assertTrue(model_onnx is not None)
        data = {
            "input1": data[:, 0].reshape((-1, 1)),
            "input2": data[:, 1].reshape((-1, 1)),
        }
        dump_data_and_model(
            data,
            PipeConcatenateInput(model),
            model_onnx,
            basename="SklearnPipelineScaler11Union",
        )

    def test_combine_inputs_floats_ints(self):
        data = [[0, 0.0], [0, 0.0], [1, 1.0], [1, 1.0]]
        scaler = StandardScaler()
        scaler.fit(data)
        model = Pipeline([("scaler1", scaler), ("scaler2", scaler)])

        model_onnx = convert_sklearn(
            model,
            "pipeline",
            [
                ("input1", Int64TensorType([None, 1])),
                ("input2", FloatTensorType([None, 1])),
            ],
        )
        self.assertTrue(len(model_onnx.graph.node[-1].output) == 1)
        self.assertTrue(model_onnx is not None)
        data = numpy.array(data)
        data = {
            "input1": data[:, 0].reshape((-1, 1)).astype(numpy.int64),
            "input2": data[:, 1].reshape((-1, 1)).astype(numpy.float32),
        }
        dump_data_and_model(
            data,
            PipeConcatenateInput(model),
            model_onnx,
            basename="SklearnPipelineScalerMixed",
        )

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(StrictVersion(ort_version) <= StrictVersion("0.4.0"),
                     reason="issues with shapes")
    def test_pipeline_column_transformer(self):

        iris = datasets.load_iris()
        X = iris.data[:, :3]
        y = iris.target
        X_train = pandas.DataFrame(X, columns=["vA", "vB", "vC"])
        X_train["vcat"] = X_train["vA"].apply(lambda x: "cat1"
                                              if x > 0.5 else "cat2")
        X_train["vcat2"] = X_train["vB"].apply(lambda x: "cat3"
                                               if x > 0.5 else "cat4")
        y_train = y % 2
        numeric_features = [0, 1, 2]  # ["vA", "vB", "vC"]
        categorical_features = [3, 4]  # ["vcat", "vcat2"]

        classifier = LogisticRegression(
            C=0.01,
            class_weight=dict(zip([False, True], [0.2, 0.8])),
            n_jobs=1,
            max_iter=10,
            solver="lbfgs",
            tol=1e-3,
        )

        numeric_transformer = Pipeline(steps=[
            ("imputer", SimpleImputer(strategy="median")),
            ("scaler", StandardScaler()),
        ])

        categorical_transformer = Pipeline(steps=[
            (
                "onehot",
                OneHotEncoder(sparse=True, handle_unknown="ignore"),
            ),
            (
                "tsvd",
                TruncatedSVD(n_components=1, algorithm="arpack", tol=1e-4),
            ),
        ])

        preprocessor = ColumnTransformer(transformers=[
            ("num", numeric_transformer, numeric_features),
            ("cat", categorical_transformer, categorical_features),
        ])

        model = Pipeline(steps=[("precprocessor",
                                 preprocessor), ("classifier", classifier)])

        model.fit(X_train, y_train)
        initial_type = [
            ("numfeat", FloatTensorType([None, 3])),
            ("strfeat", StringTensorType([None, 2])),
        ]

        X_train = X_train[:11]
        model_onnx = convert_sklearn(model, initial_types=initial_type)

        dump_data_and_model(
            X_train,
            model,
            model_onnx,
            basename="SklearnPipelineColumnTransformerPipeliner",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.3') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.4.0')",
        )

        if __name__ == "__main__":
            from onnx.tools.net_drawer import GetPydotGraph, GetOpNodeProducer

            pydot_graph = GetPydotGraph(
                model_onnx.graph,
                name=model_onnx.graph.name,
                rankdir="TP",
                node_producer=GetOpNodeProducer("docstring"),
            )
            pydot_graph.write_dot("graph.dot")

            import os

            os.system("dot -O -G=300 -Tpng graph.dot")

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        not check_scikit_version(),
        reason="Scikit 0.20 causes some mismatches",
    )
    def test_pipeline_column_transformer_titanic(self):

        # fit
        titanic_url = (
            "https://raw.githubusercontent.com/amueller/"
            "scipy-2017-sklearn/091d371/notebooks/datasets/titanic3.csv")
        data = pandas.read_csv(titanic_url)
        X = data.drop("survived", axis=1)
        y = data["survived"]

        # SimpleImputer on string is not available for string
        # in ONNX-ML specifications.
        # So we do it beforehand.
        for cat in ["embarked", "sex", "pclass"]:
            X[cat].fillna("missing", inplace=True)

        X_train, X_test, y_train, y_test = train_test_split(
            X, y, test_size=0.2)

        numeric_features = ["age", "fare"]
        numeric_transformer = Pipeline(steps=[
            ("imputer", SimpleImputer(strategy="median")),
            ("scaler", StandardScaler()),
        ])

        categorical_features = ["embarked", "sex", "pclass"]
        categorical_transformer = Pipeline(steps=[
            # --- SimpleImputer on string is not available
            # for string in ONNX-ML specifications.
            # ('imputer',
            #  SimpleImputer(strategy='constant', fill_value='missing')),
            ("onehot", OneHotEncoder(handle_unknown="ignore"))
        ])

        preprocessor = ColumnTransformer(transformers=[
            ("num", numeric_transformer, numeric_features),
            ("cat", categorical_transformer, categorical_features),
        ])

        clf = Pipeline(steps=[
            ("preprocessor", preprocessor),
            # ("classifier", LogisticRegression(solver="lbfgs")),
        ])

        # inputs

        def convert_dataframe_schema(df, drop=None):
            inputs = []
            for k, v in zip(df.columns, df.dtypes):
                if drop is not None and k in drop:
                    continue
                if v == 'int64':
                    t = Int64TensorType([None, 1])
                elif v == "float64":
                    t = FloatTensorType([None, 1])
                else:
                    t = StringTensorType([None, 1])
                inputs.append((k, t))
            return inputs

        to_drop = {
            "parch",
            "sibsp",
            "cabin",
            "ticket",
            "name",
            "body",
            "home.dest",
            "boat",
        }

        X_train = X_train.copy()
        X_test = X_test.copy()
        X_train['pclass'] = X_train['pclass'].astype(numpy.int64)
        X_test['pclass'] = X_test['pclass'].astype(numpy.int64)
        X_train = X_train.drop(to_drop, axis=1)
        X_test = X_test.drop(to_drop, axis=1)

        clf.fit(X_train, y_train)
        inputs = convert_dataframe_schema(X_train, to_drop)
        model_onnx = convert_sklearn(clf, "pipeline_titanic", inputs)

        data = X_test[:5]
        pred = clf.transform(data)
        data_types = {
            'pclass': numpy.int64,
            'age': numpy.float32,
            'sex': numpy.str,
            'fare': numpy.float32,
            'embarked': numpy.str,
        }
        inputs = {k: data[k].values.astype(data_types[k]).reshape(-1, 1)
                  for k in data.columns}
        sess = InferenceSession(model_onnx.SerializeToString())
        run = sess.run(None, inputs)
        got = run[-1]
        assert_almost_equal(pred, got, decimal=5)

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_column_transformer_weights(self):
        model, X = fit_classification_model(
            ColumnTransformer(
                [('pca', PCA(n_components=5), slice(0, 10)),
                 ('svd', TruncatedSVD(n_components=5), slice(10, 100))],
                transformer_weights={'pca': 2, 'svd': 3}), 3, n_features=100)
        model_onnx = convert_sklearn(
            model,
            "column transformer weights",
            [("input", FloatTensorType([None, X.shape[1]]))],
            dtype=numpy.float32,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnColumnTransformerWeights-Dec4",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_column_transformer_drop(self):
        model, X = fit_classification_model(
            ColumnTransformer(
                [('pca', PCA(n_components=5), slice(0, 10)),
                 ('svd', TruncatedSVD(n_components=5), slice(80, 100))],
                remainder='drop'), 3, n_features=100)
        model_onnx = convert_sklearn(
            model,
            "column transformer drop",
            [("input", FloatTensorType([None, X.shape[1]]))],
            dtype=numpy.float32,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnColumnTransformerDrop",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_column_transformer_passthrough(self):
        model, X = fit_classification_model(
            ColumnTransformer(
                [('pca', PCA(n_components=5), slice(0, 10)),
                 ('svd', TruncatedSVD(n_components=5), slice(80, 100))],
                transformer_weights={'pca': 2, 'svd': 3},
                remainder='passthrough'), 3, n_features=100)
        model_onnx = convert_sklearn(
            model,
            "column transformer passthrough",
            [("input", FloatTensorType([None, X.shape[1]]))],
            dtype=numpy.float32,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnColumnTransformerPassthrough",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_column_transformer_passthrough_no_weights(self):
        model, X = fit_classification_model(
            ColumnTransformer(
                [('pca', PCA(n_components=5), slice(0, 10)),
                 ('svd', TruncatedSVD(n_components=5), slice(70, 80))],
                remainder='passthrough'), 3, n_features=100)
        model_onnx = convert_sklearn(
            model,
            "column transformer passthrough",
            [("input", FloatTensorType([None, X.shape[1]]))],
            dtype=numpy.float32,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnColumnTransformerPassthroughNoWeights",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    def test_pipeline_dataframe(self):
        text = """
                fixed_acidity,volatile_acidity,citric_acid,residual_sugar,chlorides,free_sulfur_dioxide,total_sulfur_dioxide,density,pH,sulphates,alcohol,quality,color
                7.4,0.7,0.0,1.9,0.076,11.0,34.0,0.9978,3.51,0.56,9.4,5,red
                7.8,0.88,0.0,2.6,0.098,25.0,67.0,0.9968,3.2,0.68,9.8,5,red
                7.8,0.76,0.04,2.3,0.092,15.0,54.0,0.997,3.26,0.65,9.8,5,red
                11.2,0.28,0.56,1.9,0.075,17.0,60.0,0.998,3.16,0.58,9.8,6,red
                """.replace("                ", "")
        X_train = pandas.read_csv(StringIO(text))
        for c in X_train.columns:
            if c != 'color':
                X_train[c] = X_train[c].astype(numpy.float32)
        numeric_features = [c for c in X_train if c != 'color']

        pipe = Pipeline([
            ("prep", ColumnTransformer([
                ("color", Pipeline([
                    ('one', OneHotEncoder()),
                    ('select', ColumnTransformer(
                        [('sel1', 'passthrough', [0])]))
                ]), ['color']),
                ("others", "passthrough", numeric_features)
            ])),
        ])

        init_types = [
            ('fixed_acidity', FloatTensorType(shape=[None, 1])),
            ('volatile_acidity', FloatTensorType(shape=[None, 1])),
            ('citric_acid', FloatTensorType(shape=[None, 1])),
            ('residual_sugar', FloatTensorType(shape=[None, 1])),
            ('chlorides', FloatTensorType(shape=[None, 1])),
            ('free_sulfur_dioxide', FloatTensorType(shape=[None, 1])),
            ('total_sulfur_dioxide', FloatTensorType(shape=[None, 1])),
            ('density', FloatTensorType(shape=[None, 1])),
            ('pH', FloatTensorType(shape=[None, 1])),
            ('sulphates', FloatTensorType(shape=[None, 1])),
            ('alcohol', FloatTensorType(shape=[None, 1])),
            ('quality', FloatTensorType(shape=[None, 1])),
            ('color', StringTensorType(shape=[None, 1]))
        ]

        pipe.fit(X_train)
        model_onnx = convert_sklearn(pipe, initial_types=init_types)
        oinf = InferenceSession(model_onnx.SerializeToString())

        pred = pipe.transform(X_train)
        inputs = {c: X_train[c].values for c in X_train.columns}
        inputs = {c: v.reshape((v.shape[0], 1)) for c, v in inputs.items()}
        onxp = oinf.run(None, inputs)
        got = onxp[0]
        assert_almost_equal(pred, got)
class TestSklearnCalibratedClassifierCVConverters(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_calibrated_classifier_cv_float(self):
        data = load_iris()
        X, y = data.data, data.target
        clf = MultinomialNB().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method="sigmoid").fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn CalibratedClassifierCV",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnCalibratedClassifierCVFloat",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_calibrated_classifier_cv_int(self):
        data = load_digits()
        X, y = data.data, data.target
        clf = MultinomialNB().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method="sigmoid").fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn CalibratedClassifierCV",
            [("input", Int64TensorType([None, X.shape[1]]))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.int64),
            model,
            model_onnx,
            basename="SklearnCalibratedClassifierCVInt-Dec4",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        StrictVersion(onnxruntime.__version__) < StrictVersion("0.5.0"),
        reason="not available")
    def test_model_calibrated_classifier_cv_isotonic_float(self):
        data = load_iris()
        X, y = data.data, data.target
        clf = KNeighborsClassifier().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method="isotonic").fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn CalibratedClassifierCV",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnCalibratedClassifierCVIsotonicFloat")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_calibrated_classifier_cv_binary(self):
        data = load_iris()
        X, y = data.data, data.target
        y[y > 1] = 1
        clf = MultinomialNB().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method="sigmoid").fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn CalibratedClassifierCV",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnCalibratedClassifierCVBinary",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        StrictVersion(onnxruntime.__version__) < StrictVersion("0.5.0"),
        reason="not available")
    def test_model_calibrated_classifier_cv_isotonic_binary(self):
        data = load_iris()
        X, y = data.data, data.target
        y[y > 1] = 1
        clf = KNeighborsClassifier().fit(X, y)
        model = CalibratedClassifierCV(clf, cv=2, method="isotonic").fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn CalibratedClassifierCV",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        try:
            self.assertTrue(model_onnx is not None)
            dump_data_and_model(
                X.astype(np.float32),
                model,
                model_onnx,
                basename="SklearnCalibratedClassifierCVIsotonicBinary")
        except Exception as e:
            raise AssertionError("Issue with model\n{}".format(
                str(model_onnx))) from e
예제 #18
0
class TestGLMClassifierConverter(unittest.TestCase):
    def _fit_model_binary_classification(self, model):
        iris = datasets.load_iris()
        X = iris.data[:, :3]
        y = iris.target
        y[y == 2] = 1
        model.fit(X, y)
        return model, X

    def _fit_model_multiclass_classification(self, model):
        iris = datasets.load_iris()
        X = iris.data[:, :3]
        y = iris.target
        model.fit(X, y)
        return model, X

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_binary_class(self):
        model, X = self._fit_model_binary_classification(
            linear_model.LogisticRegression())
        model_onnx = convert_sklearn(model, "logistic regression",
                                     [("input", FloatTensorType([1, 3]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionBinary",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.3') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_binary_class_nointercept(self):
        model, X = self._fit_model_binary_classification(
            linear_model.LogisticRegression(fit_intercept=False))
        model_onnx = convert_sklearn(model, "logistic regression",
                                     [("input", FloatTensorType([1, 3]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionBinaryNoIntercept",
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.3') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class(self):
        model, X = self._fit_model_multiclass_classification(
            linear_model.LogisticRegression())
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([1, 3]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMulti",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_ovr(self):
        model, X = self._fit_model_multiclass_classification(
            linear_model.LogisticRegression(multi_class='ovr'))
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([1, 3]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMulti",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_multinomial(self):
        model, X = self._fit_model_multiclass_classification(
            linear_model.LogisticRegression(
                multi_class="multinomial", solver="lbfgs"))
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([1, 3]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMulti",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_no_intercept(self):
        model, X = self._fit_model_multiclass_classification(
            linear_model.LogisticRegression(fit_intercept=False))
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([1, 3]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMultiNoIntercept",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_lbfgs(self):
        penalty = (
            'l2'
            if _sklearn_version() < StrictVersion('0.21.0')
            else 'none')
        model, X = self._fit_model_multiclass_classification(
            linear_model.LogisticRegression(solver='lbfgs', penalty=penalty))
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([1, 3]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMultiLbfgs",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_liblinear_l1(self):
        model, X = self._fit_model_multiclass_classification(
            linear_model.LogisticRegression(solver='liblinear', penalty='l1'))
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([1, 3]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMultiLiblinearL1",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_logistic_regression_multi_class_saga_elasticnet(self):
        if _sklearn_version() < StrictVersion('0.21.0'):
            model, X = self._fit_model_multiclass_classification(
                linear_model.LogisticRegression(solver='saga'))
        else:
            model, X = self._fit_model_multiclass_classification(
                linear_model.LogisticRegression(
                    solver='saga', penalty='elasticnet', l1_ratio=0.1))
        model_onnx = convert_sklearn(
            model,
            "multi-class logistic regression",
            [("input", FloatTensorType([1, 3]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnLogitisticRegressionMultiSagaElasticnet",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_linear_svc_binary_class(self):
        model, X = self._fit_model_binary_classification(LinearSVC())
        model_onnx = convert_sklearn(model, "linear SVC",
                                     [("input", FloatTensorType([1, 3]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnLinearSVCBinary-NoProb",
            allow_failure="StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_linear_svc_multi_class(self):
        model, X = self._fit_model_multiclass_classification(LinearSVC())
        model_onnx = convert_sklearn(
            model,
            "multi-class linear SVC",
            [("input", FloatTensorType([1, 3]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnLinearSVCMulti",
            allow_failure="StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )
예제 #19
0
class TestSklearnPipelineWithinPipeline(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_pipeline_pca_pipeline_minmax(self):
        model = Pipeline(
            memory=None,
            steps=[
                (
                    "PCA",
                    PCA(
                        copy=True,
                        iterated_power="auto",
                        n_components=0.15842105263157896,
                        random_state=None,
                        tol=0.0,
                        svd_solver="auto",
                        whiten=False,
                    ),
                ),
                (
                    "Pipeline",
                    Pipeline(
                        memory=None,
                        steps=[(
                            "MinMax scaler",
                            MinMaxScaler(
                                copy=True,
                                feature_range=(0, 3.7209871159509307),
                            ),
                        )],
                    ),
                ),
            ],
        )

        data = np.array([[0, 0], [0, 0], [1, 1], [1, 1]], dtype=np.float32)
        y = [0, 0, 1, 1]
        model.fit(data, y)
        model_onnx = convert_sklearn(
            model,
            "pipelinewithinpipeline",
            [("input", FloatTensorType(data.shape))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            data,
            model,
            model_onnx,
            basename="SklearnPipelinePcaPipelineMinMax",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_pipeline_pca_pipeline_none_lin(self):
        model = Pipeline(
            memory=None,
            steps=[
                (
                    "PCA",
                    PCA(
                        copy=True,
                        iterated_power="auto",
                        n_components=0.15842105263157896,
                        random_state=None,
                        tol=0.0,
                        svd_solver="auto",
                        whiten=False,
                    ),
                ),
                (
                    "Pipeline",
                    Pipeline(
                        memory=None,
                        steps=[
                            (
                                "MinMax scaler",
                                MinMaxScaler(
                                    copy=True,
                                    feature_range=(0, 3.7209871159509307),
                                ),
                            ),
                            ("logreg", LogisticRegression(solver="liblinear")),
                        ],
                    ),
                ),
            ],
        )

        data = np.array([[0, 0], [0, 0], [1, 1], [1, 1]], dtype=np.float32)
        y = [0, 0, 1, 1]
        model.fit(data, y)
        model_onnx = convert_sklearn(
            model,
            "pipelinewithinpipeline",
            [("input", FloatTensorType(data.shape))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            data,
            model,
            model_onnx,
            basename="SklearnPipelinePcaPipelineMinMaxLogReg",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_pipeline_pca_pipeline_multinomial(self):
        model = Pipeline(
            memory=None,
            steps=[
                (
                    "PCA",
                    PCA(
                        copy=True,
                        iterated_power="auto",
                        n_components=2,
                        random_state=None,
                        svd_solver="auto",
                        tol=0.0,
                        whiten=False,
                    ),
                ),
                (
                    "Pipeline",
                    Pipeline(
                        memory=None,
                        steps=[
                            (
                                "MinMax scaler",
                                MinMaxScaler(
                                    copy=True,
                                    feature_range=(0, 3.7209871159509307),
                                ),
                            ),
                            (
                                "MultinomialNB",
                                MultinomialNB(
                                    alpha=0.7368421052631579,
                                    class_prior=None,
                                    fit_prior=True,
                                ),
                            ),
                        ],
                    ),
                ),
            ],
        )

        data = np.array(
            [[0, 0, 0], [0, 0, 0.1], [1, 1, 1.1], [1, 1.1, 1]],
            dtype=np.float32,
        )
        y = [0, 0, 1, 1]
        model.fit(data, y)
        model_onnx = convert_sklearn(model,
                                     "pipelinewithinpipeline",
                                     [("input", FloatTensorType(data.shape))],
                                     target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            data,
            model,
            model_onnx,
            basename="SklearnPipelinePcaPipelineMinMaxNB2",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_pipeline_pca_pipeline_multinomial_none(self):
        model = Pipeline(
            memory=None,
            steps=[
                (
                    "PCA",
                    PCA(
                        copy=True,
                        iterated_power="auto",
                        n_components=0.15842105263157896,
                        random_state=None,
                        tol=0.0,
                        svd_solver="auto",
                        whiten=False,
                    ),
                ),
                (
                    "Pipeline",
                    Pipeline(
                        memory=None,
                        steps=[
                            (
                                "MinMax scaler",
                                MinMaxScaler(
                                    copy=True,
                                    feature_range=(0, 3.7209871159509307),
                                ),
                            ),
                            (
                                "MultinomialNB",
                                MultinomialNB(
                                    alpha=0.7368421052631579,
                                    class_prior=None,
                                    fit_prior=True,
                                ),
                            ),
                        ],
                    ),
                ),
            ],
        )

        data = np.array([[0, 0], [0, 0], [1, 1], [1, 1]], dtype=np.float32)
        y = [0, 0, 1, 1]
        model.fit(data, y)
        model_onnx = convert_sklearn(model,
                                     "pipelinewithinpipeline",
                                     [("input", FloatTensorType(data.shape))],
                                     target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            data,
            model,
            model_onnx,
            basename="SklearnPipelinePcaPipelineMinMaxNBNone",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(
        ColumnTransformer is None,
        reason="ColumnTransformer not available in 0.19",
    )
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_pipeline_column_transformer_pipeline_imputer_scaler_lr(self):
        X = np.array([[1, 2], [3, np.nan], [3, 0]], dtype=np.float32)
        y = np.array([1, 0, 1])
        model = Pipeline([
            (
                "ct",
                ColumnTransformer([
                    (
                        "pipeline1",
                        Pipeline([
                            ("imputer", SimpleImputer()),
                            ("scaler", StandardScaler()),
                        ]),
                        [0],
                    ),
                    (
                        "pipeline2",
                        Pipeline([
                            ("imputer", SimpleImputer()),
                            ("scaler", RobustScaler()),
                        ]),
                        [1],
                    ),
                ]),
            ),
            ("lr", LogisticRegression(solver="liblinear")),
        ])
        model.fit(X, y)
        model_onnx = convert_sklearn(
            model,
            "pipelinewithinpipeline",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnPipelineCTPipelineImputerScalerLR",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )
예제 #20
0
class TestSklearnGradientBoostingModels(unittest.TestCase):

    def setUp(self):
        log = getLogger('skl2onnx')
        log.disabled = True

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        StrictVersion(__version__) <= StrictVersion(THRESHOLD),
        reason="Depends on PR #1015 onnxruntime.")
    def test_gradient_boosting_classifier1Deviance(self):
        model = GradientBoostingClassifier(n_estimators=1, max_depth=2)
        X, y = make_classification(10, n_features=4, random_state=42)
        X = X[:, :2]
        model.fit(X, y)

        for cl in [None, 0.231, 1e-6, 0.9]:
            if cl is not None:
                model.init_.class_prior_ = np.array([cl, cl])
            initial_types = [('input', FloatTensorType((None, X.shape[1])))]
            model_onnx = convert_sklearn(model, initial_types=initial_types)
            if "Regressor" in str(model_onnx):
                raise AssertionError(str(model_onnx))
            sess = InferenceSession(model_onnx.SerializeToString())
            res = sess.run(None, {'input': X.astype(np.float32)})
            pred = model.predict_proba(X)
            delta = abs(res[1][0][0] - pred[0, 0])
            if delta > 1e-5:
                rows = ["diff", str(delta),
                        "X", str(X),
                        "base_values_", str(model.init_.class_prior_),
                        "predicted_label", str(model.predict(X)),
                        "expected", str(pred),
                        "onnxruntime", str(DataFrame(res[1])),
                        "model", str(model_onnx)]
                raise AssertionError("\n---\n".join(rows))
        dump_binary_classification(
            model, suffix="1Deviance",
            allow_failure="StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('%s')" % THRESHOLD)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gradient_boosting_classifier3(self):
        model = GradientBoostingClassifier(n_estimators=3)
        dump_binary_classification(
            model, suffix="3",
            allow_failure="StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('%s')" % THRESHOLD)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gradient_boosting_classifier_multi(self):
        model = GradientBoostingClassifier(n_estimators=3)
        dump_multiple_classification(
            model,
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('%s')" % THRESHOLD,
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gradient_boosting_binary_classification(self):
        model, X = fit_classification_model(
            GradientBoostingClassifier(n_estimators=3), 2)
        model_onnx = convert_sklearn(
            model,
            "gradient boosting classifier",
            [("input", FloatTensorType([None, X.shape[1]]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingBinaryClassifier",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gradient_boosting_binary_classification_init_zero(self):
        model, X = fit_classification_model(
            GradientBoostingClassifier(n_estimators=4, init='zero'), 2)
        model_onnx = convert_sklearn(
            model,
            "gradient boosting classifier",
            [("input", FloatTensorType([None, X.shape[1]]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingBinaryClassifierInitZero",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gradient_boosting_multiclass_classification(self):
        model, X = fit_classification_model(
            GradientBoostingClassifier(n_estimators=4), 5)
        model_onnx = convert_sklearn(
            model,
            "gradient boosting classifier",
            [("input", FloatTensorType([None, X.shape[1]]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingMultiClassClassifier",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gradient_boosting_int(self):
        model, X = fit_classification_model(
            GradientBoostingClassifier(n_estimators=4), 5, is_int=True)
        model_onnx = convert_sklearn(
            model, "gradient boosting classifier",
            [("input", Int64TensorType([None, X.shape[1]]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingInt",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gradient_boosting_bool(self):
        model, X = fit_classification_model(
            GradientBoostingClassifier(n_estimators=4), 5, is_bool=True)
        model_onnx = convert_sklearn(
            model, "gradient boosting classifier",
            [("input", BooleanTensorType([None, X.shape[1]]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingBool",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gradient_boosting_multiclass_decision_function(self):
        model, X = fit_classification_model(
            GradientBoostingClassifier(n_estimators=4), 5)
        options = {id(model): {'raw_scores': True}}
        model_onnx = convert_sklearn(
            model,
            "gradient boosting classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options=options,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingMultiClassDecisionFunction",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
            methods=['predict', 'decision_function'],
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gradient_boosting_multiclass_classification_init_zero(self):
        model, X = fit_classification_model(
            GradientBoostingClassifier(n_estimators=4, init='zero'), 4)
        model_onnx = convert_sklearn(
            model,
            "gradient boosting classifier",
            [("input", FloatTensorType([None, X.shape[1]]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingMultiClassClassifierInitZero",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    def test_gradient_boosting_regressor_ls_loss(self):
        model, X = fit_regression_model(
            GradientBoostingRegressor(n_estimators=3, loss="ls"))
        model_onnx = convert_sklearn(
            model,
            "gradient boosting regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingRegressionLsLoss",
            allow_failure="StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')"
        )

    def test_gradient_boosting_regressor_lad_loss(self):
        model, X = fit_regression_model(
            GradientBoostingRegressor(n_estimators=3, loss="lad"))
        model_onnx = convert_sklearn(
            model,
            "gradient boosting regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingRegressionLadLoss",
            allow_failure="StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')"
        )

    def test_gradient_boosting_regressor_huber_loss(self):
        model, X = fit_regression_model(
            GradientBoostingRegressor(n_estimators=3, loss="huber"))
        model_onnx = convert_sklearn(
            model,
            "gradient boosting regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingRegressionHuberLoss",
            allow_failure="StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')"
        )

    def test_gradient_boosting_regressor_quantile_loss(self):
        model, X = fit_regression_model(
            GradientBoostingRegressor(n_estimators=3, loss="quantile"))
        model_onnx = convert_sklearn(
            model,
            "gradient boosting regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingRegressionQuantileLoss",
            allow_failure="StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')"
        )

    def test_gradient_boosting_regressor_int(self):
        model, X = fit_regression_model(
            GradientBoostingRegressor(random_state=42), is_int=True)
        model_onnx = convert_sklearn(
            model, "gradient boosting regression",
            [("input", Int64TensorType([None, X.shape[1]]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingRegressionInt-Dec4",
            allow_failure="StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')"
        )

    def test_gradient_boosting_regressor_zero_init(self):
        model, X = fit_regression_model(
            GradientBoostingRegressor(n_estimators=30, init="zero",
                                      random_state=42))
        model_onnx = convert_sklearn(
            model,
            "gradient boosting regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingRegressionZeroInit-Dec4",
            allow_failure="StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')"
        )

    @unittest.skipIf(
        StrictVersion(__version__) <= StrictVersion(THRESHOLD),
        reason="Depends on PR #1015 onnxruntime.")
    def test_gradient_boosting_regressor_learning_rate(self):
        X, y = make_classification(
            n_features=100, n_samples=1000, n_classes=2, n_informative=8)
        X_train, X_test, y_train, _ = train_test_split(
            X, y, test_size=0.5, random_state=42)
        model = GradientBoostingClassifier().fit(X_train, y_train)
        onnx_model = convert_sklearn(
            model, 'lr2', [('input', FloatTensorType(X_test.shape))])
        sess = InferenceSession(onnx_model.SerializeToString())
        res = sess.run(None, input_feed={'input': X_test.astype(np.float32)})
        r1 = np.mean(
            np.isclose(model.predict_proba(X_test),
                       list(map(lambda x: list(map(lambda y: x[y], x)),
                                res[1])), atol=1e-4))
        r2 = np.mean(res[0] == model.predict(X_test))
        assert r1 == r2

    def test_gradient_boosting_regressor_bool(self):
        model, X = fit_regression_model(
            GradientBoostingRegressor(random_state=42), is_bool=True)
        model_onnx = convert_sklearn(
            model, "gradient boosting regressor",
            [("input", BooleanTensorType([None, X.shape[1]]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X, model, model_onnx,
            basename="SklearnGradientBoostingRegressorBool-Dec4",
            allow_failure="StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')")
예제 #21
0
class TestSklearnCustomNMF(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(StrictVersion(onnx.__version__) <= StrictVersion("1.4.1"),
                     reason="not available")
    def test_custom_nmf(self):

        mat = np.array([[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0],
                        [1, 0, 0, 0], [1, 0, 0, 0]], dtype=np.float64)
        mat[:mat.shape[1], :] += np.identity(mat.shape[1])

        mod = NMF(n_components=2)
        W = mod.fit_transform(mat)
        H = mod.components_

        def predict(W, H, row_index, col_index):
            return np.dot(W[row_index, :], H[:, col_index])

        pred = mod.inverse_transform(W)

        exp = []
        got = []
        for i in range(mat.shape[0]):
            for j in range(mat.shape[1]):
                exp.append((i, j, pred[i, j]))
                got.append((i, j, predict(W, H, i, j)))

        max_diff = max(abs(e[2] - o[2]) for e, o in zip(exp, got))
        assert max_diff <= 1e-5

        def nmf_to_onnx(W, H):
            """
            The function converts a NMF described by matrices
            *W*, *H* (*WH* approximate training data *M*).
            into a function which takes two indices *(i, j)*
            and returns the predictions for it. It assumes
            these indices applies on the training data.
            """
            col = OnnxArrayFeatureExtractor(H, 'col')
            row = OnnxArrayFeatureExtractor(W.T, 'row')
            dot = OnnxMul(col, row)
            res = OnnxReduceSum(dot, output_names="rec")
            indices_type = np.array([0], dtype=np.int64)
            onx = res.to_onnx(inputs={'col': indices_type,
                                      'row': indices_type},
                              outputs=[('rec', FloatTensorType((None, 1)))])
            return onx

        model_onnx = nmf_to_onnx(W, H)
        sess = InferenceSession(model_onnx.SerializeToString())

        def predict_onnx(sess, row_indices, col_indices):
            res = sess.run(None,
                           {'col': col_indices,
                            'row': row_indices})
            return res

        onnx_preds = []
        for i in range(mat.shape[0]):
            for j in range(mat.shape[1]):
                row_indices = np.array([i], dtype=np.int64)
                col_indices = np.array([j], dtype=np.int64)
                pred = predict_onnx(sess, row_indices, col_indices)[0]
                onnx_preds.append((i, j, pred[0, 0]))

        max_diff = max(abs(e[2] - o[2]) for e, o in zip(exp, onnx_preds))
        assert max_diff <= 1e-5
예제 #22
0
class TestNearestNeighbourConverter(unittest.TestCase):
    def _fit_model_binary_classification(self, model):
        iris = datasets.load_iris()
        X = iris.data[:, :3]
        y = iris.target
        y[y == 2] = 1
        model.fit(X, y)
        return model, X

    def _fit_model_multiclass_classification(self, model):
        iris = datasets.load_iris()
        X = iris.data[:, :3]
        y = iris.target
        model.fit(X, y)
        return model, X

    def _fit_model(self, model, n_targets=1):
        X, y = datasets.make_regression(n_features=4,
                                        random_state=0,
                                        n_targets=n_targets)
        model.fit(X, y)
        return model, X

    def test_model_knn_regressor(self):
        model, X = self._fit_model(KNeighborsRegressor(n_neighbors=2))
        model_onnx = convert_sklearn(model, "KNN regressor",
                                     [("input", FloatTensorType([None, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32)[:7],
            model,
            model_onnx,
            basename="SklearnKNeighborsRegressor-OneOffArray",
            allow_failure="StrictVersion(onnxruntime.__version__) "
            "<= StrictVersion('0.2.1') or "
            "StrictVersion(onnx.__version__) == StrictVersion('1.4.1')",
        )

    def test_model_knn_regressor2_1(self):
        model, X = self._fit_model(KNeighborsRegressor(n_neighbors=1),
                                   n_targets=2)
        model_onnx = convert_sklearn(model, "KNN regressor",
                                     [("input", FloatTensorType([None, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32)[:2],
            model,
            model_onnx,
            basename="SklearnKNeighborsRegressor2-OneOffArray",
            allow_failure="StrictVersion(onnxruntime.__version__) "
            "<= StrictVersion('0.2.1') or "
            "StrictVersion(onnx.__version__) == StrictVersion('1.4.1')",
        )

    def test_model_knn_regressor2_2(self):
        model, X = self._fit_model(KNeighborsRegressor(n_neighbors=2),
                                   n_targets=2)
        model_onnx = convert_sklearn(model, "KNN regressor",
                                     [("input", FloatTensorType([None, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32)[:2],
            model,
            model_onnx,
            basename="SklearnKNeighborsRegressor2-OneOffArray",
            allow_failure="StrictVersion(onnxruntime.__version__) "
            "<= StrictVersion('0.2.1') or "
            "StrictVersion(onnx.__version__) == StrictVersion('1.4.1')",
        )

    def test_model_knn_regressor_weights_distance(self):
        model, X = self._fit_model(KNeighborsRegressor(weights="distance"))
        model_onnx = convert_sklearn(model, "KNN regressor",
                                     [("input", FloatTensorType([None, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32)[:7],
            model,
            model_onnx,
            basename="SklearnKNeighborsRegressorWeightsDistance-OneOffArray",
            allow_failure="StrictVersion(onnxruntime.__version__) <= "
            "StrictVersion('0.2.1') or "
            "StrictVersion(onnx.__version__) == StrictVersion('1.4.1')",
        )

    def test_model_knn_regressor_metric_cityblock(self):
        model, X = self._fit_model(KNeighborsRegressor(metric="cityblock"))
        model_onnx = convert_sklearn(model, "KNN regressor",
                                     [("input", FloatTensorType([None, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32)[:7],
            model,
            model_onnx,
            basename="SklearnKNeighborsRegressorMetricCityblock-OneOffArray",
            allow_failure="StrictVersion(onnxruntime.__version__) <= "
            "StrictVersion('0.2.1') or "
            "StrictVersion(onnx.__version__) == StrictVersion('1.4.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_knn_classifier_binary_class(self):
        model, X = self._fit_model_binary_classification(
            KNeighborsClassifier())
        model_onnx = convert_sklearn(
            model,
            "KNN classifier binary",
            [("input", FloatTensorType([None, 3]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnKNeighborsClassifierBinary-OneOffArray",
            allow_failure="StrictVersion(onnx.__version__) "
            "== StrictVersion('1.1.2') or "
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1') "
            "or StrictVersion(onnx.__version__) == StrictVersion('1.4.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_knn_classifier_multi_class(self):
        model, X = self._fit_model_multiclass_classification(
            KNeighborsClassifier())
        model_onnx = convert_sklearn(
            model,
            "KNN classifier multi-class",
            [("input", FloatTensorType([None, 3]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32),
            model,
            model_onnx,
            basename="SklearnKNeighborsClassifierMulti-OneOffArray",
            allow_failure="StrictVersion(onnx.__version__) "
            "== StrictVersion('1.1.2') or "
            "StrictVersion(onnxruntime.__version__) <= StrictVersion('0.2.1') "
            "or StrictVersion(onnx.__version__) == StrictVersion('1.4.1')",
        )

    def test_model_knn_classifier_weights_distance(self):
        model, X = self._fit_model_multiclass_classification(
            KNeighborsClassifier(weights='distance'))
        model_onnx = convert_sklearn(model, 'KNN classifier',
                                     [('input', FloatTensorType([None, 3]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32)[:7],
            model,
            model_onnx,
            basename="SklearnKNeighborsClassifierWeightsDistance-OneOffArray",
            allow_failure="StrictVersion(onnxruntime.__version__) <= "
            "StrictVersion('0.2.1') or "
            "StrictVersion(onnx.__version__) == StrictVersion('1.4.1')")

    def test_model_knn_classifier_metric_cityblock(self):
        model, X = self._fit_model_multiclass_classification(
            KNeighborsClassifier(metric='cityblock'))
        model_onnx = convert_sklearn(model, 'KNN classifier',
                                     [('input', FloatTensorType([None, 3]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(numpy.float32)[:7],
            model,
            model_onnx,
            basename="SklearnKNeighborsClassifierMetricCityblock-OneOffArray",
            allow_failure="StrictVersion(onnxruntime.__version__) <= "
            "StrictVersion('0.2.1') or "
            "StrictVersion(onnx.__version__) == StrictVersion('1.4.1')")

    def test_model_knn_regressor_int(self):
        model, X = self._fit_model(KNeighborsRegressor())
        X = X.astype(numpy.int64)
        model_onnx = convert_sklearn(
            model,
            "KNN regressor",
            [("input", Int64TensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnGradientBoostingRegressionInt-OneOffArray",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')")
class TestSGDClassifierConverter(unittest.TestCase):

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_binary_class_hinge(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='hinge', random_state=42), 2)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD binary classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierBinaryHinge-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_multi_class_hinge(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='hinge', random_state=42), 5)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD multi-class classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierMultiHinge-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_binary_class_log(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='log', random_state=42), 2)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD binary classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierBinaryLog-Dec4",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_multi_class_log(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='log', random_state=42), 5)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD multi-class classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        X = np.array([X[1], X[1]])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierMultiLog",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_binary_class_log_l1_no_intercept(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='log', penalty='l1', fit_intercept=False,
                          random_state=42), 2)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD binary classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierBinaryLogL1NoIntercept-Dec4",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_multi_class_log_l1_no_intercept(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='log', penalty='l1', fit_intercept=False,
                          random_state=42), 5)
        X = np.array([X[4], X[4]])
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD multi-class classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierMultiLogL1NoIntercept-Dec4",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_binary_class_elasticnet_power_t(self):
        model, X = fit_classification_model(
            SGDClassifier(penalty='elasticnet', l1_ratio=0.3,
                          power_t=2, random_state=42), 2)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD binary classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierBinaryElasticnetPowerT-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_multi_class_elasticnet_power_t(self):
        model, X = fit_classification_model(
            SGDClassifier(penalty='elasticnet', l1_ratio=0.3,
                          power_t=2, random_state=42), 5)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD multi-class classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierMultiElasticnetPowerT-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_binary_class_modified_huber(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='modified_huber', random_state=42), 2)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD binary classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierBinaryModifiedHuber-Dec4",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.6.0')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_binary_class_squared_hinge(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='squared_hinge', random_state=42), 2)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD binary classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierBinarySquaredHinge-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_multi_class_squared_hinge(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='squared_hinge', random_state=42), 5)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD multi-class classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierMultiSquaredHinge-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_binary_class_perceptron(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='perceptron', random_state=42), 2)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD binary classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierBinaryPerceptron-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_multi_class_preceptron(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='perceptron', random_state=42), 5)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD multi-class classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnSGDClassifierMultiPerceptron-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_binary_class_hinge_int(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='hinge', random_state=42), 2, is_int=True)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD binary classifier",
            [("input", Int64TensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnSGDClassifierBinaryHingeInt-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_multi_class_hinge_int(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='hinge', random_state=42), 5, is_int=True)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD multi-class classifier",
            [("input", Int64TensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnSGDClassifierMultiHingeInt-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_binary_class_log_int(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='log', random_state=42), 2, is_int=True)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD binary classifier",
            [("input", Int64TensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnSGDClassifierBinaryLogInt",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_sgd_multi_class_log_int(self):
        model, X = fit_classification_model(
            SGDClassifier(loss='log', random_state=42), 5, is_int=True)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn SGD multi-class classifier",
            [("input", Int64TensorType([None, X.shape[1]]))],
        )
        X = X[6:8]
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnSGDClassifierMultiLogInt",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )
예제 #24
0
class TestSklearnAdaBoostModels(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_classifier_samme_r(self):
        model, X_test = fit_classification_model(
            AdaBoostClassifier(n_estimators=10,
                               algorithm="SAMME.R",
                               random_state=42,
                               base_estimator=DecisionTreeClassifier(
                                   max_depth=2, random_state=42)), 3)
        model_onnx = convert_sklearn(
            model,
            "AdaBoost classification",
            [("input", FloatTensorType((None, X_test.shape[1])))],
            target_opset=10)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnAdaBoostClassifierSAMMER",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_classifier_samme_r_decision_function(self):
        model, X_test = fit_classification_model(
            AdaBoostClassifier(n_estimators=10,
                               algorithm="SAMME.R",
                               random_state=42,
                               base_estimator=DecisionTreeClassifier(
                                   max_depth=2, random_state=42)), 4)
        options = {id(model): {'raw_scores': True}}
        model_onnx = convert_sklearn(
            model,
            "AdaBoost classification",
            [("input", FloatTensorType((None, X_test.shape[1])))],
            target_opset=10,
            options=options,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnAdaBoostClassifierSAMMERDecisionFunction",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
            methods=['predict', 'decision_function'],
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_classifier_samme_r_logreg(self):
        model, X_test = fit_classification_model(
            AdaBoostClassifier(
                n_estimators=5,
                algorithm="SAMME.R",
                base_estimator=LogisticRegression(solver='liblinear')), 4)
        model_onnx = convert_sklearn(
            model,
            "AdaBoost classification",
            [("input", FloatTensorType((None, X_test.shape[1])))],
            target_opset=10)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnAdaBoostClassifierSAMMERLogReg",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_classifier_samme(self):
        model, X_test = fit_classification_model(
            AdaBoostClassifier(n_estimators=5,
                               algorithm="SAMME",
                               random_state=42,
                               base_estimator=DecisionTreeClassifier(
                                   max_depth=6, random_state=42)), 2)
        model_onnx = convert_sklearn(
            model,
            "AdaBoostClSamme",
            [("input", FloatTensorType((None, X_test.shape[1])))],
            target_opset=10,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnAdaBoostClassifierSAMMEDT",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)"
            "< StrictVersion('0.5.0')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_classifier_samme_decision_function(self):
        model, X_test = fit_classification_model(
            AdaBoostClassifier(n_estimators=5,
                               algorithm="SAMME",
                               random_state=42,
                               base_estimator=DecisionTreeClassifier(
                                   max_depth=6, random_state=42)), 2)
        options = {id(model): {'raw_scores': True}}
        model_onnx = convert_sklearn(
            model,
            "AdaBoostClSamme",
            [("input", FloatTensorType((None, X_test.shape[1])))],
            target_opset=10,
            options=options,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnAdaBoostClassifierSAMMEDTDecisionFunction",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)"
            "< StrictVersion('0.5.0')",
            methods=['predict', 'decision_function_binary'],
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_classifier_lr(self):
        model, X_test = fit_classification_model(AdaBoostClassifier(
            learning_rate=0.3, random_state=42),
                                                 3,
                                                 is_int=True)
        model_onnx = convert_sklearn(
            model,
            "AdaBoost classification",
            [("input", Int64TensorType((None, X_test.shape[1])))],
            target_opset=10)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnAdaBoostClassifierLR",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_classifier_bool(self):
        model, X_test = fit_classification_model(
            AdaBoostClassifier(random_state=42), 3, is_bool=True)
        model_onnx = convert_sklearn(
            model,
            "AdaBoost classification",
            [("input", BooleanTensorType((None, X_test.shape[1])))],
            target_opset=10,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnAdaBoostClassifierBool",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_regressor(self):
        model, X = fit_regression_model(AdaBoostRegressor(n_estimators=5))
        model_onnx = convert_sklearn(
            model,
            "AdaBoost regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=10)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnAdaBoostRegressor-Dec4",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) "
            "< StrictVersion('0.5.0') or "
            "StrictVersion(onnx.__version__) "
            "== StrictVersion('1.4.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_regressor_lreg(self):
        model, X = fit_regression_model(
            AdaBoostRegressor(n_estimators=5,
                              base_estimator=LinearRegression()))
        model_onnx = convert_sklearn(
            model,
            "AdaBoost regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=10)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnAdaBoostRegressorLReg-Dec4",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) "
            "< StrictVersion('0.5.0') or "
            "StrictVersion(onnx.__version__) "
            "== StrictVersion('1.4.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_regressor_int(self):
        model, X = fit_regression_model(AdaBoostRegressor(n_estimators=5),
                                        is_int=True)
        model_onnx = convert_sklearn(
            model,
            "AdaBoost regression",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=10)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnAdaBoostRegressorInt-Dec4",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) "
            "< StrictVersion('0.5.0') or "
            "StrictVersion(onnx.__version__) "
            "== StrictVersion('1.4.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_regressor_lr10(self):
        model, X = fit_regression_model(
            AdaBoostRegressor(learning_rate=0.5, random_state=42))
        model_onnx = convert_sklearn(
            model,
            "AdaBoost regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=10)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(X,
                            model,
                            model_onnx,
                            basename="SklearnAdaBoostRegressorLR-Dec4",
                            allow_failure="StrictVersion("
                            "onnxruntime.__version__) "
                            "< StrictVersion('0.5.0') or "
                            "StrictVersion(onnx.__version__) "
                            "== StrictVersion('1.4.1')",
                            verbose=False)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnxruntime.__version__) < StrictVersion("0.5.9999")),
        reason="not available")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_regressor_lr11(self):
        model, X = fit_regression_model(
            AdaBoostRegressor(learning_rate=0.5, random_state=42))
        if onnx_opset_version() < 11:
            try:
                convert_sklearn(
                    model, "AdaBoost regression",
                    [("input", FloatTensorType([None, X.shape[1]]))])
            except RuntimeError:
                return
        model_onnx = convert_sklearn(
            model,
            "AdaBoost regression",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(X,
                            model,
                            model_onnx,
                            basename="SklearnAdaBoostRegressorLR-Dec4",
                            allow_failure="StrictVersion("
                            "onnxruntime.__version__) "
                            "< StrictVersion('0.5.9999') or "
                            "StrictVersion(onnx.__version__) "
                            "== StrictVersion('1.4.1')",
                            verbose=False)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        (StrictVersion(onnx.__version__) < StrictVersion("1.5.0")),
        reason="not available")
    def test_ada_boost_regressor_bool(self):
        model, X = fit_regression_model(AdaBoostRegressor(learning_rate=0.5,
                                                          random_state=42),
                                        is_bool=True)
        model_onnx = convert_sklearn(
            model,
            "AdaBoost regression",
            [("input", BooleanTensorType([None, X.shape[1]]))],
            target_opset=10,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnAdaBoostRegressorBool",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) "
            "< StrictVersion('0.5.0') or "
            "StrictVersion(onnx.__version__) "
            "== StrictVersion('1.4.1')",
            verbose=False,
        )
예제 #25
0
class TestSklearnTreeEnsembleModels(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_random_forest_classifier(self):
        model = RandomForestClassifier(n_estimators=3)
        dump_one_class_classification(
            model,
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2')"
            " or StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )
        dump_binary_classification(
            model,
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2')"
            " or StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )
        dump_multiple_classification(
            model,
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2')"
            " or StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_random_forest_classifier_mismatched_estimator_counts(self):
        model = RandomForestClassifier(n_estimators=3)
        X = [[0, 1], [1, 1], [2, 0]]
        X = numpy.array(X, dtype=numpy.float32)
        y = ['A', 'B', 'A']
        model.fit(X, y)
        # Training code can manipulate n_estimators causing
        # n_estimators != len(estimators_). So simulate that here.
        model.n_estimators += 1
        model_onnx, prefix = convert_model(
            model, 'binary classifier',
            [('input', FloatTensorType([None, 2]))])
        dump_data_and_model(X,
                            model,
                            model_onnx,
                            basename=prefix + "Bin" +
                            model.__class__.__name__ +
                            '_mismatched_estimator_counts')

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_random_forest_regressor_mismatches(self):
        iris = load_iris()
        X, y = iris.data, iris.target
        X_train, X_test, y_train, _ = train_test_split(X, y, random_state=13)
        X_test = X_test.astype(numpy.float32)
        clr = RandomForestRegressor(n_jobs=1, n_estimators=100)
        clr.fit(X_train, y_train)
        clr.fit(X, y)
        model_onnx, prefix = convert_model(
            clr, 'reg', [('input', FloatTensorType([None, 4]))])
        dump_data_and_model(X_test,
                            clr,
                            model_onnx,
                            basename=prefix + "RegMis" +
                            clr.__class__.__name__ +
                            '_mismatched_estimator_counts')

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_random_forest_regressor(self):
        model = RandomForestRegressor(n_estimators=3)
        dump_single_regression(
            model,
            allow_failure=("StrictVersion(onnxruntime.__version__)"
                           " <= StrictVersion('0.2.1')"),
        )
        dump_multiple_regression(
            model,
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    def test_random_forest_regressor_mismatched_estimator_counts(self):
        model = RandomForestRegressor(n_estimators=3)
        X = [[0, 1], [1, 1], [2, 0]]
        X = numpy.array(X, dtype=numpy.float32)
        y = numpy.array([100, -10, 50], dtype=numpy.float32)
        model.fit(X, y)
        # Training code can manipulate n_estimators causing
        # n_estimators != len(estimators_). So simulate that here.
        model.n_estimators += 1
        model_onnx, prefix = convert_model(
            model, 'single regressor', [('input', FloatTensorType([None, 2]))])
        dump_data_and_model(X,
                            model,
                            model_onnx,
                            basename=prefix + "Reg" +
                            model.__class__.__name__ +
                            "_mismatched_estimator_counts")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_extra_trees_classifier(self):
        model = ExtraTreesClassifier(n_estimators=3)
        dump_one_class_classification(
            model,
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )
        dump_binary_classification(
            model,
            allow_failure=(
                "StrictVersion(onnx.__version__) < StrictVersion('1.2') or "
                "StrictVersion(onnxruntime.__version__)"
                " <= StrictVersion('0.2.1')"),
        )
        dump_multiple_classification(
            model,
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure=(
                "StrictVersion(onnx.__version__) < StrictVersion('1.2') or "
                "StrictVersion(onnxruntime.__version__)"
                " <= StrictVersion('0.2.1')"),
        )

    def test_extra_trees_regressor(self):
        model = ExtraTreesRegressor(n_estimators=3)
        dump_single_regression(
            model,
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )
        dump_multiple_regression(
            model,
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_multi_class_nocl(self):
        model, X = fit_classification_model(
            RandomForestClassifier(random_state=42), 2, label_string=True)
        model_onnx = convert_sklearn(
            model,
            "multi-class nocl",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options={id(model): {
                         'nocl': True
                     }})
        self.assertIsNotNone(model_onnx)
        sonx = str(model_onnx)
        assert 'classlabels_strings' not in sonx
        assert 'cl0' not in sonx
        dump_data_and_model(X,
                            model,
                            model_onnx,
                            classes=model.classes_,
                            basename="SklearnRFMultiNoCl",
                            verbose=False,
                            allow_failure="StrictVersion(onnx.__version__)"
                            " < StrictVersion('1.2') or "
                            "StrictVersion(onnxruntime.__version__)"
                            " <= StrictVersion('0.2.1')")

    def test_random_forest_classifier_int(self):
        model, X = fit_classification_model(RandomForestClassifier(
            n_estimators=5, random_state=42),
                                            3,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "random forest classifier",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRandomForestClassifierInt",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    def test_extra_trees_classifier_int(self):
        model, X = fit_classification_model(ExtraTreesClassifier(
            n_estimators=5, random_state=42),
                                            4,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "extra trees classifier",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnExtraTreesClassifierInt",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    def test_random_forest_classifier_bool(self):
        model, X = fit_classification_model(RandomForestClassifier(
            n_estimators=5, random_state=42),
                                            3,
                                            is_bool=True)
        model_onnx = convert_sklearn(
            model,
            "random forest classifier",
            [("input", BooleanTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRandomForestClassifierBool",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    def test_extra_trees_classifier_bool(self):
        model, X = fit_classification_model(ExtraTreesClassifier(
            n_estimators=5, random_state=42),
                                            2,
                                            is_bool=True)
        model_onnx = convert_sklearn(
            model,
            "extra trees regression",
            [("input", BooleanTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnExtraTreesClassifierBool",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    def common_test_model_hgb_regressor(self, add_nan=False):
        model = HistGradientBoostingRegressor(max_iter=5, max_depth=2)
        X, y = make_regression(n_features=10,
                               n_samples=1000,
                               n_targets=1,
                               random_state=42)
        if add_nan:
            rows = numpy.random.randint(0, X.shape[0] - 1, X.shape[0] // 3)
            cols = numpy.random.randint(0, X.shape[1] - 1, X.shape[0] // 3)
            X[rows, cols] = numpy.nan

        X_train, X_test, y_train, _ = train_test_split(X,
                                                       y,
                                                       test_size=0.5,
                                                       random_state=42)
        model.fit(X_train, y_train)

        model_onnx = convert_sklearn(
            model, "unused", [("input", FloatTensorType([None, X.shape[1]]))])
        self.assertIsNotNone(model_onnx)
        X_test = X_test.astype(numpy.float32)[:5]
        dump_data_and_model(X_test,
                            model,
                            model_onnx,
                            basename="SklearnHGBRegressor",
                            verbose=False,
                            allow_failure="StrictVersion(onnx.__version__)"
                            " < StrictVersion('1.2') or "
                            "StrictVersion(onnxruntime.__version__)"
                            " <= StrictVersion('0.2.1')")

    @unittest.skipIf(_sklearn_version() < StrictVersion('0.22.0'),
                     reason="missing_go_to_left is missing")
    @unittest.skipIf(HistGradientBoostingRegressor is None,
                     reason="scikit-learn 0.22 + manual activation")
    def test_model_hgb_regressor_nonan(self):
        self.common_test_model_hgb_regressor(False)

    @unittest.skipIf(_sklearn_version() < StrictVersion('0.22.0'),
                     reason="NaN not allowed")
    @unittest.skipIf(HistGradientBoostingRegressor is None,
                     reason="scikit-learn 0.22 + manual activation")
    def test_model_hgb_regressor_nan(self):
        self.common_test_model_hgb_regressor(True)

    def common_test_model_hgb_classifier(self, add_nan=False, n_classes=2):
        model = HistGradientBoostingClassifier(max_iter=5, max_depth=2)
        X, y = make_classification(n_features=10,
                                   n_samples=1000,
                                   n_informative=4,
                                   n_classes=n_classes,
                                   random_state=42)
        if add_nan:
            rows = numpy.random.randint(0, X.shape[0] - 1, X.shape[0] // 3)
            cols = numpy.random.randint(0, X.shape[1] - 1, X.shape[0] // 3)
            X[rows, cols] = numpy.nan

        X_train, X_test, y_train, _ = train_test_split(X,
                                                       y,
                                                       test_size=0.5,
                                                       random_state=42)
        model.fit(X_train, y_train)

        model_onnx = convert_sklearn(
            model, "unused", [("input", FloatTensorType([None, X.shape[1]]))])
        self.assertIsNotNone(model_onnx)
        X_test = X_test.astype(numpy.float32)[:5]

        dump_data_and_model(X_test,
                            model,
                            model_onnx,
                            basename="SklearnHGBClassifier%s%d" %
                            ("nan" if add_nan else '', n_classes),
                            verbose=False,
                            allow_failure="StrictVersion(onnx.__version__)"
                            " < StrictVersion('1.2') or "
                            "StrictVersion(onnxruntime.__version__)"
                            " <= StrictVersion('0.2.1')")

        if n_classes == 2:
            model_onnx = convert_sklearn(
                model,
                "unused", [("input", FloatTensorType([None, X.shape[1]]))],
                options={model.__class__: {
                    'raw_scores': True
                }})
            self.assertIsNotNone(model_onnx)
            X_test = X_test.astype(numpy.float32)[:5]

            # There is a bug in onnxruntime <= 1.1.0.
            # Raw scores are always positive.
            dump_data_and_model(
                X_test,
                model,
                model_onnx,
                basename="SklearnHGBClassifierRaw%s%d" %
                ("nan" if add_nan else '', n_classes),
                verbose=False,
                allow_failure="StrictVersion(onnx.__version__)"
                " < StrictVersion('1.2') or "
                "StrictVersion(onnxruntime.__version__)"
                " < StrictVersion('1.2.0')",
                methods=['predict', 'decision_function_binary'])

    @unittest.skipIf(_sklearn_version() < StrictVersion('0.22.0'),
                     reason="missing_go_to_left is missing")
    @unittest.skipIf(HistGradientBoostingClassifier is None,
                     reason="scikit-learn 0.22 + manual activation")
    def test_model_hgb_classifier_nonan(self):
        self.common_test_model_hgb_classifier(False)

    @unittest.skipIf(_sklearn_version() < StrictVersion('0.22.0'),
                     reason="NaN not allowed")
    @unittest.skipIf(HistGradientBoostingClassifier is None,
                     reason="scikit-learn 0.22 + manual activation")
    def test_model_hgb_classifier_nan(self):
        self.common_test_model_hgb_classifier(True)

    @unittest.skipIf(_sklearn_version() < StrictVersion('0.22.0'),
                     reason="missing_go_to_left is missing")
    @unittest.skipIf(HistGradientBoostingClassifier is None,
                     reason="scikit-learn 0.22 + manual activation")
    def test_model_hgb_classifier_nonan_multi(self):
        self.common_test_model_hgb_classifier(False, n_classes=3)

    @unittest.skipIf(_sklearn_version() < StrictVersion('0.22.0'),
                     reason="NaN not allowed")
    @unittest.skipIf(HistGradientBoostingClassifier is None,
                     reason="scikit-learn 0.22 + manual activation")
    def test_model_hgb_classifier_nan_multi(self):
        self.common_test_model_hgb_classifier(True, n_classes=3)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_random_forest_classifier_multilabel(self):
        model, X_test = fit_multilabel_classification_model(
            RandomForestClassifier(random_state=42))
        options = {id(model): {'zipmap': False}}
        model_onnx = convert_sklearn(
            model,
            "scikit-learn RandomForestClassifier",
            [("input", FloatTensorType([None, X_test.shape[1]]))],
            options=options,
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        assert 'zipmap' not in str(model_onnx).lower()
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnRandomForestClassifierMultiLabel-Out0",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_random_forest_classifier_multilabel_low_samples(self):
        model, X_test = fit_multilabel_classification_model(
            RandomForestClassifier(random_state=42), n_samples=4)
        options = {id(model): {'zipmap': False}}
        model_onnx = convert_sklearn(
            model,
            "scikit-learn RandomForestClassifier",
            [("input", FloatTensorType([None, X_test.shape[1]]))],
            options=options,
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        assert 'zipmap' not in str(model_onnx).lower()
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnRandomForestClassifierMultiLabelLowSamples-Out0",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_extra_trees_classifier_multilabel(self):
        model, X_test = fit_multilabel_classification_model(
            ExtraTreesClassifier(random_state=42))
        options = {id(model): {'zipmap': False}}
        model_onnx = convert_sklearn(
            model,
            "scikit-learn ExtraTreesClassifier",
            [("input", FloatTensorType([None, X_test.shape[1]]))],
            options=options,
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        assert 'zipmap' not in str(model_onnx).lower()
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnExtraTreesClassifierMultiLabel-Out0",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_extra_trees_classifier_multilabel_low_samples(self):
        model, X_test = fit_multilabel_classification_model(
            ExtraTreesClassifier(random_state=42), n_samples=10)
        options = {id(model): {'zipmap': False}}
        model_onnx = convert_sklearn(
            model,
            "scikit-learn ExtraTreesClassifier",
            [("input", FloatTensorType([None, X_test.shape[1]]))],
            options=options,
            target_opset=TARGET_OPSET)
        self.assertTrue(model_onnx is not None)
        assert 'zipmap' not in str(model_onnx).lower()
        dump_data_and_model(
            X_test,
            model,
            model_onnx,
            basename="SklearnExtraTreesClassifierMultiLabelLowSamples-Out0",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_boston_pca_rf(self):
        data = load_boston()
        X, y = data.data, data.target
        X_train, X_test, y_train, y_test = train_test_split(X,
                                                            y,
                                                            random_state=0)
        pipe = Pipeline([('acp', PCA(n_components=7)),
                         ('rf', RandomForestRegressor())])
        pipe.fit(X_train, y_train)
        X32 = X_test.astype(numpy.float32)
        model_onnx = to_onnx(pipe, X32[:1])

        dump_data_and_model(
            X32,
            pipe,
            model_onnx,
            methods=['predict'],
            basename="SklearnBostonPCARF-Dec4",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    def test_random_forest_regressor_int(self):
        model, X = fit_regression_model(RandomForestRegressor(n_estimators=5,
                                                              random_state=42),
                                        is_int=True)
        model_onnx = convert_sklearn(
            model,
            "random forest regression",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRandomForestRegressorInt-Dec4",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    def test_extra_trees_regressor_int(self):
        model, X = fit_regression_model(ExtraTreesRegressor(n_estimators=5,
                                                            random_state=42),
                                        is_int=True)
        model_onnx = convert_sklearn(
            model,
            "extra trees regression",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnExtraTreesRegressorInt-Dec4",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    def test_random_forest_regressor_bool(self):
        model, X = fit_regression_model(RandomForestRegressor(n_estimators=5,
                                                              random_state=42),
                                        is_bool=True)
        model_onnx = convert_sklearn(
            model,
            "random forest regression",
            [("input", BooleanTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnRandomForestRegressorBool-Dec4",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    def test_extra_trees_regressor_bool(self):
        model, X = fit_regression_model(ExtraTreesRegressor(n_estimators=5,
                                                            random_state=42),
                                        is_bool=True)
        model_onnx = convert_sklearn(
            model,
            "extra trees regression",
            [("input", BooleanTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET,
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnExtraTreesRegressorBool-Dec4",
            allow_failure="StrictVersion("
            "onnxruntime.__version__) <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(TARGET_OPSET < 12, reason="LabelEncoder")
    def test_randomforestregressor_decision_path(self):
        model = RandomForestRegressor(max_depth=2, n_estimators=2)
        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
                     }})
        sess = InferenceSession(model_onnx.SerializeToString())
        res = sess.run(None, {'input': X.astype(numpy.float32)})
        pred = model.predict(X)
        assert_almost_equal(pred, res[0].ravel())
        dec = model.decision_path(X)
        exp = binary_array_to_string(dec[0].todense())
        got = numpy.array([''.join(row) for row in res[1]])
        assert exp == got.ravel().tolist()

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(TARGET_OPSET < 12, reason="LabelEncoder")
    def test_extratreesregressor_decision_path(self):
        model = ExtraTreesRegressor(max_depth=2, n_estimators=2)
        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
                     }})
        sess = InferenceSession(model_onnx.SerializeToString())
        res = sess.run(None, {'input': X.astype(numpy.float32)})
        pred = model.predict(X)
        assert_almost_equal(pred, res[0].ravel())
        dec = model.decision_path(X)
        exp = binary_array_to_string(dec[0].todense())
        got = numpy.array([''.join(row) for row in res[1]])
        assert exp == got.ravel().tolist()

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(TARGET_OPSET < 12, reason="LabelEncoder")
    def test_randomforestclassifier_decision_path(self):
        model = RandomForestClassifier(max_depth=2, n_estimators=2)
        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
                     }})
        sess = InferenceSession(model_onnx.SerializeToString())
        res = sess.run(None, {'input': X.astype(numpy.float32)})
        pred = model.predict(X)
        assert_almost_equal(pred, res[0].ravel())
        prob = model.predict_proba(X)
        assert_almost_equal(prob, res[1])
        dec = model.decision_path(X)
        exp = binary_array_to_string(dec[0].todense())
        got = numpy.array([''.join(row) for row in res[2]])
        assert exp == got.ravel().tolist()

    @unittest.skipIf(not onnx_built_with_ml(),
                     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)
        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
                     }})
        sess = InferenceSession(model_onnx.SerializeToString())
        res = sess.run(None, {'input': X.astype(numpy.float32)})
        pred = model.predict(X)
        assert_almost_equal(pred, res[0].ravel())
        prob = model.predict_proba(X)
        assert_almost_equal(prob, res[1])
        dec = model.decision_path(X)
        exp = binary_array_to_string(dec[0].todense())
        got = numpy.array([''.join(row) for row in res[2]])
        assert exp == got.ravel().tolist()
class TestGaussianMixtureConverter(unittest.TestCase):
    def _fit_model_binary_classification(self, model, data, **kwargs):
        X = data.data
        y = data.target
        mid_point = len(data.target_names) / 2
        y[y < mid_point] = 0
        y[y >= mid_point] = 1
        model.fit(X, y)
        return model, X.astype(np.float32)

    def _fit_model_multiclass_classification(self, model, data):
        X = data.data
        y = data.target
        model.fit(X, y)
        return model, X.astype(np.float32)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_gaussian_mixture_binary_classification(self):
        model, X = self._fit_model_binary_classification(
            GaussianMixture(), load_iris())
        model_onnx = convert_sklearn(
            model,
            "gaussian_mixture",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnBinGaussianMixture",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_gaussian_bayesian_mixture_binary_classification(self):
        model, X = self._fit_model_binary_classification(
            BayesianGaussianMixture(), load_iris())
        model_onnx = convert_sklearn(
            model,
            "gaussian_mixture",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnBinBayesianGaussianMixture",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_gaussian_mixture_multiclass(self):
        model, X = self._fit_model_multiclass_classification(
            GaussianMixture(), load_iris())
        model_onnx = convert_sklearn(
            model,
            "gaussian_mixture",
            [("input", FloatTensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnMclGaussianMixture",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gaussian_mixture_comp2(self):
        data = load_iris()
        X = data.data
        model = GaussianMixture(n_components=2)
        model.fit(X)
        model_onnx = convert_sklearn(model, "GM",
                                     [("input", FloatTensorType([None, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32)[40:60],
            model,
            model_onnx,
            basename="GaussianMixtureC2",
            intermediate_steps=True,
            # Operator gemm is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gaussian_mixture_full(self):
        data = load_iris()
        X = data.data
        model = GaussianMixture(n_components=2, covariance_type='full')
        model.fit(X)
        model_onnx = convert_sklearn(model, "GM",
                                     [("input", FloatTensorType([None, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32)[40:60],
            model,
            model_onnx,
            basename="GaussianMixtureC2Full",
            intermediate_steps=True,
            # Operator gemm is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gaussian_mixture_tied(self):
        data = load_iris()
        X = data.data
        model = GaussianMixture(n_components=2, covariance_type='tied')
        model.fit(X)
        model_onnx = convert_sklearn(model, "GM",
                                     [("input", FloatTensorType([None, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32)[40:60],
            model,
            model_onnx,
            basename="GaussianMixtureC2Tied",
            intermediate_steps=True,
            # Operator gemm is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gaussian_mixture_diag(self):
        data = load_iris()
        X = data.data
        model = GaussianMixture(n_components=2, covariance_type='diag')
        model.fit(X)
        model_onnx = convert_sklearn(model, "GM",
                                     [("input", FloatTensorType([None, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32)[40:60],
            model,
            model_onnx,
            basename="GaussianMixtureC2Diag",
            intermediate_steps=True,
            # Operator gemm is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_gaussian_mixture_spherical(self):
        data = load_iris()
        X = data.data
        model = GaussianMixture(n_components=2, covariance_type='spherical')
        model.fit(X)
        model_onnx = convert_sklearn(model, "GM",
                                     [("input", FloatTensorType([None, 4]))])
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32)[40:60],
            model,
            model_onnx,
            basename="GaussianMixtureC2Spherical",
            intermediate_steps=True,
            # Operator gemm is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2')",
        )
예제 #27
0
class TestPerceptronClassifierConverter(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_perceptron_binary_class(self):
        model, X = fit_classification_model(Perceptron(random_state=42), 2)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn Perceptron binary classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnPerceptronClassifierBinary-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_perceptron_multi_class(self):
        model, X = fit_classification_model(Perceptron(random_state=42), 5)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn Perceptron multi-class classifier",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnPerceptronClassifierMulti-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_perceptron_binary_class_int(self):
        model, X = fit_classification_model(Perceptron(random_state=42),
                                            2,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn Perceptron binary classifier",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.int64),
            model,
            model_onnx,
            basename="SklearnPerceptronClassifierBinaryInt-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_perceptron_multi_class_int(self):
        model, X = fit_classification_model(Perceptron(random_state=42),
                                            5,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn Perceptron multi-class classifier",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X.astype(np.int64),
            model,
            model_onnx,
            basename="SklearnPerceptronClassifierMultiInt-Out0",
            allow_failure="StrictVersion(onnx.__version__)"
            " < StrictVersion('1.2') or "
            "StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
        )
class TestOneVsRestClassifierConverter(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr(self):
        model = OneVsRestClassifier(LogisticRegression())
        dump_multiple_classification(
            model,
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
            target_opset=TARGET_OPSET)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_02(self):
        model = OneVsRestClassifier(LogisticRegression())
        dump_multiple_classification(
            model,
            first_class=2,
            suffix="F2",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
            target_opset=TARGET_OPSET)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_string(self):
        model = OneVsRestClassifier(LogisticRegression())
        dump_multiple_classification(
            model,
            verbose=False,
            label_string=True,
            suffix="String",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            " <= StrictVersion('0.2.1')",
            target_opset=TARGET_OPSET)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_classification_float(self):
        model, X = fit_classification_model(
            OneVsRestClassifier(LogisticRegression(solver='liblinear')), 3)
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRClassificationFloat",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_classification_decision_function(self):
        model, X = fit_classification_model(
            OneVsRestClassifier(LogisticRegression()), 4)
        options = {id(model): {'raw_scores': True}}
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options=options,
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRClassificationDecisionFunction",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
            methods=['predict', 'decision_function'],
        )
        if StrictVersion(ort_version) < StrictVersion("1.0.0"):
            return
        options = {id(model): {'raw_scores': True, 'zipmap': False}}
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options=options,
            target_opset=TARGET_OPSET)
        sess = InferenceSession(model_onnx.SerializeToString())
        got = sess.run(None, {'input': X})[1]
        dec = model.decision_function(X)
        assert_almost_equal(got, dec, decimal=4)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_classification_decision_function_binary(self):
        model, X = fit_classification_model(
            OneVsRestClassifier(LogisticRegression()), 2)
        options = {id(model): {'raw_scores': True}}
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options=options,
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRClassificationDecisionFunctionBinary",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
            methods=['predict', 'decision_function_binary'],
        )
        if StrictVersion(ort_version) < StrictVersion("1.0.0"):
            return
        options = {id(model): {'raw_scores': True, 'zipmap': False}}
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options=options,
            target_opset=TARGET_OPSET)
        sess = InferenceSession(model_onnx.SerializeToString())
        got = sess.run(None, {'input': X})[1]
        dec = model.decision_function(X)
        assert_almost_equal(got[:, 1], dec, decimal=4)
        assert_almost_equal(-got[:, 0], dec, decimal=4)

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_classification_int(self):
        model, X = fit_classification_model(OneVsRestClassifier(
            LogisticRegression()),
                                            5,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRClassificationInt",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_classification_float_binary(self):
        model, X = fit_classification_model(
            OneVsRestClassifier(LogisticRegression()), 2)
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRClassificationFloatBin",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_classification_float_binary_nozipmap(self):
        model, X = fit_classification_model(
            OneVsRestClassifier(LogisticRegression()), 2)
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET,
            options={id(model): {
                         'zipmap': False
                     }})
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRClassificationFloatBinNoZipMap",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_classification_int_binary(self):
        model, X = fit_classification_model(OneVsRestClassifier(
            LogisticRegression()),
                                            2,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRClassificationIntBin",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_classification_float_mlp(self):
        model, X = fit_classification_model(
            OneVsRestClassifier(MLPClassifier()), 5)
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRClassificationFloatMLP",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_classification_int_ensemble(self):
        model, X = fit_classification_model(OneVsRestClassifier(
            GradientBoostingClassifier()),
                                            5,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRClassificationIntEnsemble",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_classification_float_binary_ensemble(self):
        model, X = fit_classification_model(
            OneVsRestClassifier(GradientBoostingClassifier()), 2)
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRClassificationFloatBinEnsemble",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_classification_int_binary_mlp(self):
        model, X = fit_classification_model(OneVsRestClassifier(
            MLPClassifier()),
                                            2,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "ovr classification",
            [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRClassificationIntBinMLP",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_regression_float(self):
        """The test is unstable, some observations
        are equidistant to more than one class,
        the chosen is difficult to predict. So we
        check only probabilities."""
        rs = 11
        model, X = fit_classification_model(OneVsRestClassifier(
            LinearRegression()),
                                            3,
                                            random_state=rs)
        model_onnx = convert_sklearn(
            model,
            "ovr regression", [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X[:5],
            model,
            model_onnx,
            basename="SklearnOVRRegressionFloat-Out0",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_regression_int(self):
        model, X = fit_classification_model(OneVsRestClassifier(
            LinearRegression()),
                                            10,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "ovr regression", [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRRegressionInt-Out0",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_regression_float_mlp(self):
        model, X = fit_classification_model(
            OneVsRestClassifier(MLPRegressor()), 7)
        model_onnx = convert_sklearn(
            model,
            "ovr regression", [("input", FloatTensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRRegressionFloatMLP-Out0",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_ovr_regression_int_ensemble(self):
        model, X = fit_classification_model(OneVsRestClassifier(
            GradientBoostingRegressor()),
                                            4,
                                            is_int=True)
        model_onnx = convert_sklearn(
            model,
            "ovr regression", [("input", Int64TensorType([None, X.shape[1]]))],
            target_opset=TARGET_OPSET)
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnOVRRegressionIntEnsemble-Out0",
            allow_failure="StrictVersion(onnxruntime.__version__)"
            "<= StrictVersion('0.2.1')",
        )
class TestSklearnMLPConverters(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_mlp_classifier_binary(self):
        data = load_iris()
        X, y = data.data, data.target
        y[y > 1] = 1
        X_train, X_test, y_train, y_test = train_test_split(X,
                                                            y,
                                                            test_size=0.2,
                                                            random_state=42)
        model = MLPClassifier().fit(X_train, y_train)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn MLPClassifier",
            [("input", FloatTensorType(X_test.shape))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X_test.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnMLPClassifierBinary",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_mlp_classifier_multiclass_default(self):
        data = load_iris()
        X, y = data.data, data.target
        X_train, X_test, y_train, y_test = train_test_split(X,
                                                            y,
                                                            test_size=0.2,
                                                            random_state=42)
        model = MLPClassifier().fit(X_train, y_train)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn MLPClassifier",
            [("input", FloatTensorType(X_test.shape))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X_test.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnMLPClassifierMultiClass",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')",
        )

    def test_model_mlp_regressor_default(self):
        data = load_diabetes()
        X, y = data.data, data.target
        X_train, X_test, y_train, y_test = train_test_split(X,
                                                            y,
                                                            test_size=0.2,
                                                            random_state=42)
        model = MLPRegressor().fit(X_train, y_train)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn MLPRegressor",
            [("input", FloatTensorType(X_test.shape))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X_test.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnMLPRegressor",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_mlp_classifier_multiclass_identity(self):
        data = load_digits()
        X, y = data.data, data.target
        X_train, X_test, y_train, y_test = train_test_split(X,
                                                            y,
                                                            test_size=0.2,
                                                            random_state=42)
        model = MLPClassifier(activation="identity").fit(X_train, y_train)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn MLPClassifier",
            [("input", Int64TensorType(X_test.shape))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X_test.astype(np.int64),
            model,
            model_onnx,
            basename="SklearnMLPClassifierMultiClassIdentityActivation",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')",
        )

    def test_model_mlp_regressor_identity(self):
        data = load_diabetes()
        X, y = data.data, data.target
        X_train, X_test, y_train, y_test = train_test_split(X,
                                                            y,
                                                            test_size=0.2,
                                                            random_state=42)
        model = MLPRegressor(activation="identity").fit(
            X_train.astype(np.int64), y_train)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn MLPRegressor",
            [("input", Int64TensorType(X_test.shape))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X_test.astype(np.int64),
            model,
            model_onnx,
            basename="SklearnMLPRegressorIdentityActivation",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_mlp_classifier_multiclass_logistic(self):
        data = load_iris()
        X, y = data.data, data.target
        X_train, X_test, y_train, y_test = train_test_split(X,
                                                            y,
                                                            test_size=0.2,
                                                            random_state=42)
        model = MLPClassifier(activation="logistic").fit(X_train, y_train)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn MLPClassifier",
            [("input", FloatTensorType(X_test.shape))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X_test.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnMLPClassifierMultiClassLogisticActivation",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_mlp_regressor_logistic(self):
        data = load_diabetes()
        X, y = data.data, data.target
        X_train, X_test, y_train, y_test = train_test_split(X,
                                                            y,
                                                            test_size=0.2,
                                                            random_state=42)
        model = MLPRegressor(activation="logistic").fit(X_train, y_train)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn MLPRegressor",
            [("input", FloatTensorType(X_test.shape))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X_test.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnMLPRegressorLogisticActivation",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_mlp_classifier_multiclass_tanh(self):
        data = load_iris()
        X, y = data.data, data.target
        X_train, X_test, y_train, y_test = train_test_split(X,
                                                            y,
                                                            test_size=0.2,
                                                            random_state=42)
        model = MLPClassifier(activation="tanh").fit(X_train, y_train)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn MLPClassifier",
            [("input", FloatTensorType(X_test.shape))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X_test.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnMLPClassifierMultiClassTanhActivation",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')",
        )

    def test_model_mlp_regressor_tanh(self):
        data = load_diabetes()
        X, y = data.data, data.target
        X_train, X_test, y_train, y_test = train_test_split(X,
                                                            y,
                                                            test_size=0.2,
                                                            random_state=42)
        model = MLPRegressor(activation="tanh").fit(X_train, y_train)
        model_onnx = convert_sklearn(
            model,
            "scikit-learn MLPRegressor",
            [("input", FloatTensorType(X_test.shape))],
        )
        self.assertTrue(model_onnx is not None)
        dump_data_and_model(
            X_test.astype(np.float32),
            model,
            model_onnx,
            basename="SklearnMLPRegressorTanhActivation-Dec4",
            allow_failure="StrictVersion("
            "onnxruntime.__version__)<= StrictVersion('0.2.1')",
        )
예제 #30
0
class TestSklearnDecisionTreeModels(unittest.TestCase):
    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    @unittest.skipIf(
        StrictVersion(__version__) <= StrictVersion("0.3.0"),
        reason="No suitable kernel definition found "
               "for op Cast(9) (node Cast)")
    def test_decisiontree_classifier1(self):
        model = DecisionTreeClassifier(max_depth=2)
        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)
        sess = InferenceSession(model_onnx.SerializeToString())
        res = sess.run(None, {'input': X.astype(np.float32)})
        pred = model.predict_proba(X)
        if res[1][0][0] != pred[0, 0]:
            raise AssertionError("{}\n--\n{}".format(pred, DataFrame(res[1])))

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_decisiontree_regressor0(self):
        model = DecisionTreeRegressor(max_depth=2)
        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)
        sess = InferenceSession(model_onnx.SerializeToString())
        res = sess.run(None, {'input': X.astype(np.float32)})
        pred = model.predict(X)
        if res[0][0, 0] != pred[0]:
            raise AssertionError("{}\n--\n{}".format(pred, DataFrame(res[1])))

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_decision_tree_classifier(self):
        model = DecisionTreeClassifier()
        dump_one_class_classification(
            model,
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.3') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )
        dump_binary_classification(
            model,
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.3') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )
        dump_multiple_classification(
            model,
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.3') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_extra_tree_classifier(self):
        model = ExtraTreeClassifier()
        dump_one_class_classification(
            model,
            # Operator cast-1 is not implemented in onnxruntime
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.3') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )
        dump_binary_classification(
            model,
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.3') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )
        dump_multiple_classification(
            model,
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.3') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')",
        )

    def test_decision_tree_regressor(self):
        model = DecisionTreeRegressor()
        dump_single_regression(
            model,
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2')",
        )
        dump_multiple_regression(
            model,
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2')",
        )

    def test_extra_tree_regressor(self):
        model = ExtraTreeRegressor()
        dump_single_regression(
            model,
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2')",
        )
        dump_multiple_regression(
            model,
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2')",
        )

    def test_decision_tree_regressor_int(self):
        model, X = fit_regression_model(
            DecisionTreeRegressor(random_state=42), is_int=True)
        model_onnx = convert_sklearn(
            model,
            "decision tree regression",
            [("input", Int64TensorType([None, X.shape[1]]))],
        )
        self.assertIsNotNone(model_onnx)
        dump_data_and_model(
            X,
            model,
            model_onnx,
            basename="SklearnDecisionTreeRegressionInt",
            allow_failure="StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')")

    @unittest.skipIf(not onnx_built_with_ml(),
                     reason="Requires ONNX-ML extension.")
    def test_model_multi_class_nocl(self):
        model, X = fit_classification_model(
            DecisionTreeClassifier(),
            4, label_string=True)
        model_onnx = convert_sklearn(
            model,
            "multi-class nocl",
            [("input", FloatTensorType([None, X.shape[1]]))],
            options={id(model): {'nocl': True}})
        self.assertIsNotNone(model_onnx)
        sonx = str(model_onnx)
        assert 'classlabels_strings' not in sonx
        assert 'cl0' not in sonx
        dump_data_and_model(
            X, model, model_onnx, classes=model.classes_,
            basename="SklearnDTMultiNoCl",
            allow_failure="StrictVersion(onnx.__version__)"
                          " < StrictVersion('1.2') or "
                          "StrictVersion(onnxruntime.__version__)"
                          " <= StrictVersion('0.2.1')")