From d038ade3b2729cd41def955bead8cd7efaebed6d Mon Sep 17 00:00:00 2001 From: Darius Morawiec Date: Sun, 29 Jan 2017 23:12:04 +0100 Subject: [PATCH] Extend backwards compatibility by refactoring dependency handling, tests & examples --- environment.yml | 15 +-- .../classifier/AdaBoostClassifier/c/basics.py | 3 +- .../AdaBoostClassifier/java/basics.py | 3 +- .../AdaBoostClassifier/js/basics.py | 3 +- .../classifier/BernoulliNB/java/basics.py | 3 +- .../DecisionTreeClassifier/c/basics.py | 3 +- .../DecisionTreeClassifier/java/basics.py | 3 +- .../DecisionTreeClassifier/js/basics.py | 3 +- .../DecisionTreeClassifier/php/basics.py | 3 +- .../ExtraTreesClassifier/c/basics.py | 3 +- .../ExtraTreesClassifier/java/basics.py | 3 +- .../ExtraTreesClassifier/js/basics.py | 3 +- examples/classifier/GaussianNB/java/basics.py | 3 +- .../KNeighborsClassifier/java/basics.py | 3 +- .../KNeighborsClassifier/js/basics.py | 3 +- examples/classifier/LinearSVC/c/basics.py | 3 +- examples/classifier/LinearSVC/c/compiling.py | 3 +- examples/classifier/LinearSVC/go/basics.py | 3 +- examples/classifier/LinearSVC/java/basics.py | 3 +- examples/classifier/LinearSVC/js/basics.py | 3 +- examples/classifier/LinearSVC/php/basics.py | 3 +- examples/classifier/LinearSVC/ruby/basics.py | 3 +- .../classifier/MLPClassifier/java/basics.py | 3 +- .../classifier/MLPClassifier/js/basics.py | 3 +- examples/classifier/NuSVC/c/basics.py | 3 +- examples/classifier/NuSVC/java/basics.py | 3 +- examples/classifier/NuSVC/js/basics.py | 3 +- examples/classifier/NuSVC/php/basics.py | 3 +- .../RandomForestClassifier/c/basics.py | 3 +- .../RandomForestClassifier/java/basics.py | 3 +- .../RandomForestClassifier/js/basics.py | 3 +- examples/classifier/SVC/c/basics.py | 3 +- examples/classifier/SVC/java/basics.py | 3 +- examples/classifier/SVC/js/basics.py | 3 +- examples/classifier/SVC/php/basics.py | 3 +- examples/cli/dump_pickle_file.py | 3 +- license.txt | 2 +- readme.md | 122 ++++++++++-------- requirements.txt | 7 +- setup.py | 2 +- sklearn_porter/Model.py | 7 +- sklearn_porter/Porter.py | 76 +++++++---- tests/PorterTest.py | 5 +- tests/c/CTest.py | 6 +- tests/java/JavaTest.py | 6 +- tests/js/JavaScriptTest.py | 6 +- tests/php/PhpTest.py | 6 +- tests/ruby/RubyTest.py | 6 +- 48 files changed, 223 insertions(+), 148 deletions(-) diff --git a/environment.yml b/environment.yml index ad0b97c2..55138083 100644 --- a/environment.yml +++ b/environment.yml @@ -1,14 +1,13 @@ name: sklearn-porter dependencies: -- libgcc=4.8.5=1 -- mkl=11.3.3=0 -- numpy=1.11.2=py27_0 -- openssl=1.0.2j=0 -- pip=8.1.2=py27_0 -- python=2.7.12=1 +- mkl=2017.0.1=0 +- numpy=1.11.3=py27_0 +- openssl=1.0.2k=0 +- pip=9.0.1=py27_1 +- python=2.7.13=0 - readline=6.2=2 -- scikit-learn=0.18=np111py27_0 -- scipy=0.18.1=np111py27_0 +- scikit-learn=0.18.1=np111py27_1 +- scipy=0.18.1=np111py27_1 - setuptools=27.2.0=py27_0 - sqlite=3.13.0=0 - tk=8.5.18=0 diff --git a/examples/classifier/AdaBoostClassifier/c/basics.py b/examples/classifier/AdaBoostClassifier/c/basics.py index dca84e4a..f4de0f87 100644 --- a/examples/classifier/AdaBoostClassifier/c/basics.py +++ b/examples/classifier/AdaBoostClassifier/c/basics.py @@ -7,7 +7,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target base_estimator = DecisionTreeClassifier(max_depth=4, random_state=0) clf = AdaBoostClassifier(base_estimator=base_estimator, n_estimators=100, random_state=0) diff --git a/examples/classifier/AdaBoostClassifier/java/basics.py b/examples/classifier/AdaBoostClassifier/java/basics.py index 2106ed2c..701aab22 100644 --- a/examples/classifier/AdaBoostClassifier/java/basics.py +++ b/examples/classifier/AdaBoostClassifier/java/basics.py @@ -7,7 +7,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target base_estimator = DecisionTreeClassifier(max_depth=4, random_state=0) clf = AdaBoostClassifier(base_estimator=base_estimator, n_estimators=100, random_state=0) diff --git a/examples/classifier/AdaBoostClassifier/js/basics.py b/examples/classifier/AdaBoostClassifier/js/basics.py index 17627ae9..8caf028d 100644 --- a/examples/classifier/AdaBoostClassifier/js/basics.py +++ b/examples/classifier/AdaBoostClassifier/js/basics.py @@ -7,7 +7,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target base_estimator = DecisionTreeClassifier(max_depth=4, random_state=0) clf = AdaBoostClassifier(base_estimator=base_estimator, n_estimators=100, random_state=0) diff --git a/examples/classifier/BernoulliNB/java/basics.py b/examples/classifier/BernoulliNB/java/basics.py index 9ed44907..35c6f93c 100644 --- a/examples/classifier/BernoulliNB/java/basics.py +++ b/examples/classifier/BernoulliNB/java/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = BernoulliNB() clf.fit(X, y) diff --git a/examples/classifier/DecisionTreeClassifier/c/basics.py b/examples/classifier/DecisionTreeClassifier/c/basics.py index ff2c37ee..bb2f2ebb 100644 --- a/examples/classifier/DecisionTreeClassifier/c/basics.py +++ b/examples/classifier/DecisionTreeClassifier/c/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = tree.DecisionTreeClassifier() clf.fit(X, y) diff --git a/examples/classifier/DecisionTreeClassifier/java/basics.py b/examples/classifier/DecisionTreeClassifier/java/basics.py index d62ec51f..062cbb11 100644 --- a/examples/classifier/DecisionTreeClassifier/java/basics.py +++ b/examples/classifier/DecisionTreeClassifier/java/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = tree.DecisionTreeClassifier() clf.fit(X, y) diff --git a/examples/classifier/DecisionTreeClassifier/js/basics.py b/examples/classifier/DecisionTreeClassifier/js/basics.py index 35c9f346..e7c023cc 100644 --- a/examples/classifier/DecisionTreeClassifier/js/basics.py +++ b/examples/classifier/DecisionTreeClassifier/js/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = tree.DecisionTreeClassifier() clf.fit(X, y) diff --git a/examples/classifier/DecisionTreeClassifier/php/basics.py b/examples/classifier/DecisionTreeClassifier/php/basics.py index bcafee02..eeac8282 100644 --- a/examples/classifier/DecisionTreeClassifier/php/basics.py +++ b/examples/classifier/DecisionTreeClassifier/php/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = tree.DecisionTreeClassifier() clf.fit(X, y) diff --git a/examples/classifier/ExtraTreesClassifier/c/basics.py b/examples/classifier/ExtraTreesClassifier/c/basics.py index c8319414..ba9c86bf 100644 --- a/examples/classifier/ExtraTreesClassifier/c/basics.py +++ b/examples/classifier/ExtraTreesClassifier/c/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = ExtraTreesClassifier(n_estimators=15, random_state=0) clf.fit(X, y) diff --git a/examples/classifier/ExtraTreesClassifier/java/basics.py b/examples/classifier/ExtraTreesClassifier/java/basics.py index cdc14216..bf8efced 100644 --- a/examples/classifier/ExtraTreesClassifier/java/basics.py +++ b/examples/classifier/ExtraTreesClassifier/java/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = ExtraTreesClassifier(n_estimators=15, random_state=0) clf.fit(X, y) diff --git a/examples/classifier/ExtraTreesClassifier/js/basics.py b/examples/classifier/ExtraTreesClassifier/js/basics.py index d57ef6ba..48f7259f 100644 --- a/examples/classifier/ExtraTreesClassifier/js/basics.py +++ b/examples/classifier/ExtraTreesClassifier/js/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = ExtraTreesClassifier(n_estimators=15, random_state=0) clf.fit(X, y) diff --git a/examples/classifier/GaussianNB/java/basics.py b/examples/classifier/GaussianNB/java/basics.py index 363de80a..a5d2cba6 100644 --- a/examples/classifier/GaussianNB/java/basics.py +++ b/examples/classifier/GaussianNB/java/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = GaussianNB() clf.fit(X, y) diff --git a/examples/classifier/KNeighborsClassifier/java/basics.py b/examples/classifier/KNeighborsClassifier/java/basics.py index 8054ff96..35dbe72d 100644 --- a/examples/classifier/KNeighborsClassifier/java/basics.py +++ b/examples/classifier/KNeighborsClassifier/java/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = KNeighborsClassifier(algorithm='brute', n_neighbors=3, weights='uniform') clf.fit(X, y) diff --git a/examples/classifier/KNeighborsClassifier/js/basics.py b/examples/classifier/KNeighborsClassifier/js/basics.py index 43658c22..09eff464 100644 --- a/examples/classifier/KNeighborsClassifier/js/basics.py +++ b/examples/classifier/KNeighborsClassifier/js/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = KNeighborsClassifier(algorithm='brute', n_neighbors=3, weights='uniform') clf.fit(X, y) diff --git a/examples/classifier/LinearSVC/c/basics.py b/examples/classifier/LinearSVC/c/basics.py index ec2ed93f..769dec56 100644 --- a/examples/classifier/LinearSVC/c/basics.py +++ b/examples/classifier/LinearSVC/c/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.LinearSVC(C=1., random_state=0) clf.fit(X, y) diff --git a/examples/classifier/LinearSVC/c/compiling.py b/examples/classifier/LinearSVC/c/compiling.py index e776f23a..13796084 100644 --- a/examples/classifier/LinearSVC/c/compiling.py +++ b/examples/classifier/LinearSVC/c/compiling.py @@ -8,7 +8,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.LinearSVC(C=1., random_state=0) clf.fit(X, y) diff --git a/examples/classifier/LinearSVC/go/basics.py b/examples/classifier/LinearSVC/go/basics.py index 29387624..6be4df6d 100644 --- a/examples/classifier/LinearSVC/go/basics.py +++ b/examples/classifier/LinearSVC/go/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.LinearSVC(C=1., random_state=0) clf.fit(X, y) diff --git a/examples/classifier/LinearSVC/java/basics.py b/examples/classifier/LinearSVC/java/basics.py index a69ce36d..13bac8de 100644 --- a/examples/classifier/LinearSVC/java/basics.py +++ b/examples/classifier/LinearSVC/java/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.LinearSVC(C=1., random_state=0) clf.fit(X, y) diff --git a/examples/classifier/LinearSVC/js/basics.py b/examples/classifier/LinearSVC/js/basics.py index d93b6368..c392bca2 100644 --- a/examples/classifier/LinearSVC/js/basics.py +++ b/examples/classifier/LinearSVC/js/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.LinearSVC(C=1., random_state=0) clf.fit(X, y) diff --git a/examples/classifier/LinearSVC/php/basics.py b/examples/classifier/LinearSVC/php/basics.py index cf9d7d1c..d070b116 100644 --- a/examples/classifier/LinearSVC/php/basics.py +++ b/examples/classifier/LinearSVC/php/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.LinearSVC(C=1., random_state=0) clf.fit(X, y) diff --git a/examples/classifier/LinearSVC/ruby/basics.py b/examples/classifier/LinearSVC/ruby/basics.py index 37f6b980..328200fc 100644 --- a/examples/classifier/LinearSVC/ruby/basics.py +++ b/examples/classifier/LinearSVC/ruby/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.LinearSVC(C=1., random_state=0) clf.fit(X, y) diff --git a/examples/classifier/MLPClassifier/java/basics.py b/examples/classifier/MLPClassifier/java/basics.py index a454792b..3fe4c4ad 100644 --- a/examples/classifier/MLPClassifier/java/basics.py +++ b/examples/classifier/MLPClassifier/java/basics.py @@ -9,7 +9,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target X = shuffle(X, random_state=0) y = shuffle(y, random_state=0) diff --git a/examples/classifier/MLPClassifier/js/basics.py b/examples/classifier/MLPClassifier/js/basics.py index a117ffef..04efa883 100644 --- a/examples/classifier/MLPClassifier/js/basics.py +++ b/examples/classifier/MLPClassifier/js/basics.py @@ -9,7 +9,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target X = shuffle(X, random_state=0) y = shuffle(y, random_state=0) diff --git a/examples/classifier/NuSVC/c/basics.py b/examples/classifier/NuSVC/c/basics.py index 2987ad6a..7ba40394 100644 --- a/examples/classifier/NuSVC/c/basics.py +++ b/examples/classifier/NuSVC/c/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.NuSVC(gamma=0.001, kernel='rbf', random_state=0) clf.fit(X, y) diff --git a/examples/classifier/NuSVC/java/basics.py b/examples/classifier/NuSVC/java/basics.py index 0b7e436a..538084fc 100644 --- a/examples/classifier/NuSVC/java/basics.py +++ b/examples/classifier/NuSVC/java/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.NuSVC(gamma=0.001, kernel='rbf', random_state=0) clf.fit(X, y) diff --git a/examples/classifier/NuSVC/js/basics.py b/examples/classifier/NuSVC/js/basics.py index 0a134077..3a428d05 100644 --- a/examples/classifier/NuSVC/js/basics.py +++ b/examples/classifier/NuSVC/js/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.NuSVC(gamma=0.001, kernel='rbf', random_state=0) clf.fit(X, y) diff --git a/examples/classifier/NuSVC/php/basics.py b/examples/classifier/NuSVC/php/basics.py index 6616e82b..30793f8e 100644 --- a/examples/classifier/NuSVC/php/basics.py +++ b/examples/classifier/NuSVC/php/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.NuSVC(gamma=0.001, kernel='rbf', random_state=0) clf.fit(X, y) diff --git a/examples/classifier/RandomForestClassifier/c/basics.py b/examples/classifier/RandomForestClassifier/c/basics.py index a452db37..0ded953b 100644 --- a/examples/classifier/RandomForestClassifier/c/basics.py +++ b/examples/classifier/RandomForestClassifier/c/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = RandomForestClassifier(n_estimators=15, max_depth=None, min_samples_split=2, random_state=0) clf.fit(X, y) diff --git a/examples/classifier/RandomForestClassifier/java/basics.py b/examples/classifier/RandomForestClassifier/java/basics.py index 53026eea..b5a0d44f 100644 --- a/examples/classifier/RandomForestClassifier/java/basics.py +++ b/examples/classifier/RandomForestClassifier/java/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = RandomForestClassifier(n_estimators=15, max_depth=None, min_samples_split=2, random_state=0) clf.fit(X, y) diff --git a/examples/classifier/RandomForestClassifier/js/basics.py b/examples/classifier/RandomForestClassifier/js/basics.py index 28a02da3..f0b2a28f 100644 --- a/examples/classifier/RandomForestClassifier/js/basics.py +++ b/examples/classifier/RandomForestClassifier/js/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = RandomForestClassifier(n_estimators=15, max_depth=None, min_samples_split=2, random_state=0) clf.fit(X, y) diff --git a/examples/classifier/SVC/c/basics.py b/examples/classifier/SVC/c/basics.py index 6b00aeca..26c27fc2 100644 --- a/examples/classifier/SVC/c/basics.py +++ b/examples/classifier/SVC/c/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.SVC(C=1., gamma=0.001, kernel='rbf', random_state=0) clf.fit(X, y) diff --git a/examples/classifier/SVC/java/basics.py b/examples/classifier/SVC/java/basics.py index 38396d45..4274e876 100644 --- a/examples/classifier/SVC/java/basics.py +++ b/examples/classifier/SVC/java/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.SVC(C=1., gamma=0.001, kernel='rbf', random_state=0) clf.fit(X, y) diff --git a/examples/classifier/SVC/js/basics.py b/examples/classifier/SVC/js/basics.py index 38897a4d..4cfcfdeb 100644 --- a/examples/classifier/SVC/js/basics.py +++ b/examples/classifier/SVC/js/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.SVC(C=1., gamma=0.001, kernel='rbf', random_state=0) clf.fit(X, y) diff --git a/examples/classifier/SVC/php/basics.py b/examples/classifier/SVC/php/basics.py index 78df5091..8866da9d 100644 --- a/examples/classifier/SVC/php/basics.py +++ b/examples/classifier/SVC/php/basics.py @@ -6,7 +6,8 @@ from sklearn_porter import Porter -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = svm.SVC(C=1., gamma=0.001, kernel='rbf', random_state=0) clf.fit(X, y) diff --git a/examples/cli/dump_pickle_file.py b/examples/cli/dump_pickle_file.py index c6d9bf2c..77b0d22e 100644 --- a/examples/cli/dump_pickle_file.py +++ b/examples/cli/dump_pickle_file.py @@ -5,7 +5,8 @@ from sklearn.externals import joblib -X, y = load_iris(return_X_y=True) +iris_data = load_iris() +X, y = iris_data.data, iris_data.target clf = tree.DecisionTreeClassifier() clf.fit(X, y) diff --git a/license.txt b/license.txt index da35fb93..240e3b98 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -Copyright 2016, Darius Morawiec +Copyright 2016-2017, Darius Morawiec Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/readme.md b/readme.md index c51e0a09..63a6452f 100644 --- a/readme.md +++ b/readme.md @@ -12,84 +12,80 @@ Transpile trained [scikit-learn](https://github.com/scikit-learn/scikit-learn) m ## Machine learning algorithms -### Classification - -The portable classifiers are listed in the following table: - - - + + - - - - - - - + + + + + + + - - - + + + - + - - - + + + - + - - - - - - + + + + + + - - - + + + - + - - - + + + - - - + + + - - - + + + @@ -97,8 +93,8 @@ The portable classifiers are listed in the following table: - - + + @@ -106,8 +102,8 @@ The portable classifiers are listed in the following table: - - + + @@ -115,7 +111,7 @@ The portable classifiers are listed in the following table: - + @@ -124,7 +120,7 @@ The portable classifiers are listed in the following table: - + @@ -147,6 +143,19 @@ pip uninstall -y sklearn-porter pip install --no-cache-dir https://github.com/nok/sklearn-porter/zipball/master ``` +## Minimum requirements + +``` +- python>=2.7.3 +- scikit-learn>=0.14.1 +``` + +If you want to transpile a multilayer perceptron (sklearn.neural_network.MLPClassifier), you have to upgrade the scikit-learn package: + +``` +- scikit-learn>=0.18.0 +``` + ## Usage @@ -158,17 +167,19 @@ Either you use the porter as [imported module](#module) in your application or y This example shows how you can port a decision tree model from the [official user guide](http://scikit-learn.org/stable/modules/tree.html#classification) to Java: ```python -from sklearn.tree import tree from sklearn.datasets import load_iris - +from sklearn.tree import tree from sklearn_porter import Porter -# Load data and train a classifier: -X, y = load_iris(return_X_y=True) +# Load data: +iris_data = load_iris() +X, y = iris_data.data, iris_data.target + +# Train classifier: clf = tree.DecisionTreeClassifier() clf.fit(X, y) -# Port the classifier: +# Transpile classifier: result = Porter(language='java').port(clf) print(result) ``` @@ -181,12 +192,15 @@ The transpiled [result](examples/classifier/DecisionTreeClassifier/java/basics.p This example shows how you can port a model from the command line. First of all you have to store the model to the [pickle format](http://scikit-learn.org/stable/modules/model_persistence.html#persistence-example): ```python -from sklearn.tree import tree from sklearn.datasets import load_iris +from sklearn.tree import tree from sklearn.externals import joblib -# Load data and train a classifier: -X, y = load_iris(return_X_y=True) +# Load data: +iris_data = load_iris() +X, y = iris_data.data, iris_data.target + +# Train classifier: clf = tree.DecisionTreeClassifier() clf.fit(X, y) diff --git a/requirements.txt b/requirements.txt index 28ea9ded..44621672 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -numpy>=1.11.2 -scipy>=0.18.1 -scikit-learn>=0.18 -six>=1.10 \ No newline at end of file +numpy>=1.8.2 +scipy>=0.14.0 +scikit-learn>=0.14.1 \ No newline at end of file diff --git a/setup.py b/setup.py index 3cb47eb6..cf1fedbd 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ packages=find_packages(exclude=["tests.*", "tests"]), include_package_data=True, version=VERSION, - description='Transpile trained scikit-learn models to a low-level programming language.', + description='Transpile trained scikit-learn models to C, Java, JavaScript and others.', author='Darius Morawiec', author_email='ping@nok.onl', url='https://github.com/nok/sklearn-porter/tree/stable', diff --git a/sklearn_porter/Model.py b/sklearn_porter/Model.py index 555d6898..d4c2244d 100644 --- a/sklearn_porter/Model.py +++ b/sklearn_porter/Model.py @@ -5,8 +5,6 @@ class Model(object): - NL = '\n' - SUPPORTED_METHODS = {} TEMPLATES = {} @@ -103,8 +101,9 @@ def temp(self, name, templates=None, n_indents=None, skipping=False): return self.temp(keys, template, skipping=False) else: # TODO: Replace static path definition: 'classifier' + class_name = self.__class__.__name__ path = os.path.join( - os.path.dirname(__file__), 'classifier', self.__class__.__name__, + os.path.dirname(__file__), 'classifier', class_name, 'templates', self.language, name + '.txt') if os.path.isfile(path): template = open(path, 'r').read() @@ -112,7 +111,7 @@ def temp(self, name, templates=None, n_indents=None, skipping=False): template = self.indent(template, n_indents, skipping) return template else: - raise AttributeError('Template \'%s\' not found.' % (name)) + raise AttributeError('Template "%s" not found.' % name) def port(self, model): """ diff --git a/sklearn_porter/Porter.py b/sklearn_porter/Porter.py index 3e78f4af..81f49c63 100644 --- a/sklearn_porter/Porter.py +++ b/sklearn_porter/Porter.py @@ -3,7 +3,6 @@ import os import sys -from sklearn.neural_network.multilayer_perceptron import MLPClassifier from sklearn.tree.tree import DecisionTreeClassifier from sklearn.ensemble.weight_boosting import AdaBoostClassifier from sklearn.ensemble.forest import RandomForestClassifier @@ -18,7 +17,7 @@ class Porter: - __version__ = '0.3.1' + __version__ = '0.3.2' def __init__(self, language="java", method_name='predict', class_name='Tmp', with_details=False): @@ -58,17 +57,17 @@ def port(self, model): :return : string The ported model as string. """ - md_type, md_name = self.get_model_data(model) - md_path = '.'.join([md_type, md_name]) # e.g.: classifier.LinearSVC + cat, name = self.get_model_data(model) + path = '.'.join([cat, name]) # e.g.: classifier.LinearSVC level = -1 if sys.version_info < (3, 3) else 1 - md_mod = __import__(md_path, globals(), locals(), [md_name], level) - klass = getattr(md_mod, md_name) + module = __import__(path, globals(), locals(), [name], level) + klass = getattr(module, name) instance = klass(language=self.language, method_name=self.method_name, class_name=self.class_name) - ported_model = instance.port(model) + result = instance.port(model) if self.with_details: - return self.get_details(ported_model) - return ported_model + return self.get_details(result) + return result def get_details(self, model): """ @@ -93,36 +92,44 @@ def get_details(self, model): model : string The ported model. """ - filename = '%s.%s' % (self.class_name.lower(), self.language) + + # Filename: + filename = self.class_name.lower() if self.language == 'java': filename = filename.capitalize() + filename = '%s.%s' % (filename, self.language) + # Commands: comp_cmd = '' # compiling command exec_cmd = '' # execution command if self.language is 'c': + class_name = self.class_name.lower() # gcc tmp.c -o tmp - comp_cmd = 'gcc %s -o %s' % (filename, self.class_name.lower()) + comp_cmd = 'gcc %s -o %s' % (filename, class_name) # ./tmp - exec_cmd = os.path.join('.', self.class_name.lower()) + exec_cmd = os.path.join('.', class_name) elif self.language is 'java': # javac Tmp.java comp_cmd = 'javac %s' % filename # java -classpath . Tmp - exec_cmd = 'java -classpath . %s' % self.class_name.capitalize() + class_name = self.class_name.capitalize() + exec_cmd = 'java -classpath . %s' % class_name elif self.language is 'js': # node tmp.js exec_cmd = 'node %s' % filename elif self.language is 'go': + # TODO: Add go-relevant commands pass - data = { + # Result: + result = { 'language': self.language, 'filename': filename, 'compiling_cmd': comp_cmd, 'execution_cmd': exec_cmd, 'model': model, } - return data + return result @staticmethod def get_model_data(model): @@ -136,15 +143,15 @@ def get_model_data(model): Returns ------- - :return md_type : string ['regressor', 'classifier'] - The model type. + :return cat : string ('regressor', 'classifier') + The model category. - :return md_name : string + :return name : string The name of the used algorithm. """ - md_type = Porter.is_supported_model(model) - md_name = type(model).__name__ - return md_type, md_name + cat = Porter.is_supported_model(model) + name = type(model).__name__ + return cat, name @staticmethod def is_supported_classifier(model): @@ -161,8 +168,9 @@ def is_supported_classifier(model): :return : bool Whether the model is a supported classifier. """ - return isinstance(model, ( - MLPClassifier, + + # Default classifiers: + supported_clfs = ( DecisionTreeClassifier, AdaBoostClassifier, RandomForestClassifier, @@ -173,7 +181,20 @@ def is_supported_classifier(model): KNeighborsClassifier, GaussianNB, BernoulliNB, - )) + ) + + # Get version information: + import sklearn + version = sklearn.__version__.split('.') + major, minor = int(version[0]), int(version[1]) + + # MLPClassifier was new in version 0.18: + if major > 0 or (major == 0 and minor >= 18): # version >= 0.18 + from sklearn.neural_network.multilayer_perceptron import \ + MLPClassifier + supported_clfs += (MLPClassifier, ) + + return isinstance(model, supported_clfs) @staticmethod def is_supported_regressor(model): @@ -212,10 +233,15 @@ def is_supported_model(model): -------- onl.nok.sklearn.classifier.*, onl.nok.sklearn.regressor.* """ + + # Is the model a supported classifier? if Porter.is_supported_classifier(model): return 'classifier' + + # Is the model a supported regressor? if Porter.is_supported_regressor(model): - return 'regressors' + return 'regressor' + msg = 'The model is not an instance of '\ 'a supported classifier or regressor.' raise ValueError(msg) diff --git a/tests/PorterTest.py b/tests/PorterTest.py index a162e6d6..adcdd52d 100644 --- a/tests/PorterTest.py +++ b/tests/PorterTest.py @@ -10,6 +10,7 @@ from sklearn.datasets import load_iris from sklearn.externals import joblib from sklearn.tree import tree +from sklearn.utils import shuffle from sklearn_porter import Porter @@ -50,7 +51,9 @@ def _init_test(self): self.n_random_tests = int(n) def _train_model(self): - self.X, self.y = load_iris(return_X_y=True) + data = load_iris() + self.X = shuffle(data.data, random_state=0) + self.y = shuffle(data.target, random_state=0) self.n_features = len(self.X[0]) self.clf = tree.DecisionTreeClassifier(random_state=0) self.clf.fit(self.X, self.y) diff --git a/tests/c/CTest.py b/tests/c/CTest.py index 10300b99..291f5ac2 100644 --- a/tests/c/CTest.py +++ b/tests/c/CTest.py @@ -53,9 +53,9 @@ def _init_test(self): self.n_random_tests = int(n) def _init_data(self): - self.X, self.y = load_iris(return_X_y=True) - self.X = shuffle(self.X, random_state=0) - self.y = shuffle(self.y, random_state=0) + data = load_iris() + self.X = shuffle(data.data, random_state=0) + self.y = shuffle(data.target, random_state=0) self.n_features = len(self.X[0]) def _port_model(self, clf): diff --git a/tests/java/JavaTest.py b/tests/java/JavaTest.py index 65e092e5..e3cc81d4 100644 --- a/tests/java/JavaTest.py +++ b/tests/java/JavaTest.py @@ -53,9 +53,9 @@ def _init_test(self): self.n_random_tests = int(n) def _init_data(self): - self.X, self.y = load_iris(return_X_y=True) - self.X = shuffle(self.X, random_state=0) - self.y = shuffle(self.y, random_state=0) + data = load_iris() + self.X = shuffle(data.data, random_state=0) + self.y = shuffle(data.target, random_state=0) self.n_features = len(self.X[0]) def _port_model(self, clf): diff --git a/tests/js/JavaScriptTest.py b/tests/js/JavaScriptTest.py index 03631a88..16a92ac5 100644 --- a/tests/js/JavaScriptTest.py +++ b/tests/js/JavaScriptTest.py @@ -53,9 +53,9 @@ def _init_test(self): self.n_random_tests = int(n) def _init_data(self): - self.X, self.y = load_iris(return_X_y=True) - self.X = shuffle(self.X, random_state=0) - self.y = shuffle(self.y, random_state=0) + data = load_iris() + self.X = shuffle(data.data, random_state=0) + self.y = shuffle(data.target, random_state=0) self.n_features = len(self.X[0]) def _port_model(self, clf): diff --git a/tests/php/PhpTest.py b/tests/php/PhpTest.py index f13d90c3..0469ece1 100644 --- a/tests/php/PhpTest.py +++ b/tests/php/PhpTest.py @@ -53,9 +53,9 @@ def _init_test(self): self.n_random_tests = int(n) def _init_data(self): - self.X, self.y = load_iris(return_X_y=True) - self.X = shuffle(self.X, random_state=0) - self.y = shuffle(self.y, random_state=0) + data = load_iris() + self.X = shuffle(data.data, random_state=0) + self.y = shuffle(data.target, random_state=0) self.n_features = len(self.X[0]) def _port_model(self, clf): diff --git a/tests/ruby/RubyTest.py b/tests/ruby/RubyTest.py index decc0e99..e0bcac25 100644 --- a/tests/ruby/RubyTest.py +++ b/tests/ruby/RubyTest.py @@ -53,9 +53,9 @@ def _init_test(self): self.n_random_tests = int(n) def _init_data(self): - self.X, self.y = load_iris(return_X_y=True) - self.X = shuffle(self.X, random_state=0) - self.y = shuffle(self.y, random_state=0) + data = load_iris() + self.X = shuffle(data.data, random_state=0) + self.y = shuffle(data.target, random_state=0) self.n_features = len(self.X[0]) def _port_model(self, clf):
Programming languageTypeProgramming language
ClassifierCJavaJavaScriptGoPHPRubyClassifierCJavaJavaScriptGoPHPRuby
sklearn.svm.SVCXXXXXX XX
sklearn.svm.NuSVCXXXXXX XX
sklearn.svm.LinearSVCX , XXXXXXX , XXXXXX
sklearn.tree.DecisionTreeClassifierXXXXXX XX
sklearn.ensemble.RandomForestClassifierXXXXXX
sklearn.ensemble.ExtraTreesClassifierXXXXXX
sklearn.ensemble.AdaBoostClassifierXXXXXX
sklearn.neighbors.KNeighborsClassifier XXXX
sklearn.neural_network.MLPClassifier XXXX
sklearn.naive_bayes.GaussianNB XX
sklearn.naive_bayes.BernoulliNB XX