From b8ba45193d88f7d6037cb5444f64bb452e9e58a2 Mon Sep 17 00:00:00 2001 From: Adam Pocock Date: Fri, 7 Oct 2022 14:29:39 -0400 Subject: [PATCH] Release Tribuo 4.3 (#289) * Updating readme and adding v4.3 release notes. * Adding more to the release notes. * Adding the TF PR. * Bumping to 4.3. * Updating release notes. * Version bumps in readme and release notes. * Fixing the version number in the feature selection pom. * Updating tutorials for 4.3.0. * Update tribuo-v4-3-release-notes.md More spaces --- AnomalyDetection/Core/pom.xml | 2 +- AnomalyDetection/LibLinear/pom.xml | 2 +- AnomalyDetection/LibSVM/pom.xml | 2 +- AnomalyDetection/pom.xml | 2 +- Classification/Core/pom.xml | 2 +- Classification/DecisionTree/pom.xml | 2 +- Classification/Experiments/pom.xml | 2 +- Classification/Explanations/pom.xml | 2 +- Classification/FeatureSelection/pom.xml | 2 +- Classification/LibLinear/pom.xml | 2 +- Classification/LibSVM/pom.xml | 2 +- Classification/MultinomialNaiveBayes/pom.xml | 2 +- Classification/SGD/pom.xml | 2 +- Classification/XGBoost/pom.xml | 2 +- Classification/pom.xml | 2 +- Clustering/Core/pom.xml | 2 +- Clustering/Hdbscan/pom.xml | 2 +- Clustering/KMeans/pom.xml | 2 +- Clustering/pom.xml | 2 +- Common/LibLinear/pom.xml | 2 +- Common/LibSVM/pom.xml | 2 +- Common/NearestNeighbour/pom.xml | 2 +- Common/SGD/pom.xml | 2 +- Common/Trees/pom.xml | 2 +- Common/XGBoost/pom.xml | 2 +- Common/pom.xml | 2 +- Core/pom.xml | 2 +- Data/pom.xml | 2 +- Interop/Core/pom.xml | 2 +- Interop/ModelCard/pom.xml | 2 +- Interop/OCI/pom.xml | 2 +- Interop/ONNX/pom.xml | 2 +- Interop/Tensorflow/pom.xml | 2 +- Interop/pom.xml | 2 +- Json/pom.xml | 2 +- Math/pom.xml | 2 +- MultiLabel/Core/pom.xml | 2 +- MultiLabel/SGD/pom.xml | 2 +- MultiLabel/pom.xml | 2 +- README.md | 62 +-- Regression/Core/pom.xml | 2 +- Regression/LibLinear/pom.xml | 2 +- Regression/LibSVM/pom.xml | 2 +- Regression/RegressionTree/pom.xml | 2 +- Regression/SGD/pom.xml | 2 +- Regression/SLM/pom.xml | 2 +- Regression/XGBoost/pom.xml | 2 +- Regression/pom.xml | 2 +- Reproducibility/pom.xml | 2 +- Util/InformationTheory/pom.xml | 2 +- Util/ONNXExport/pom.xml | 2 +- Util/Tokenization/pom.xml | 2 +- Util/pom.xml | 2 +- distribution/pom.xml | 2 +- .../tribuo-v4-3-release-notes.md | 117 ++++++ pom.xml | 2 +- tests/pom.xml | 2 +- tutorials/anomaly-tribuo-v4.ipynb | 6 +- tutorials/clustering-hdbscan-tribuo-v4.ipynb | 22 +- tutorials/clustering-tribuo-v4.ipynb | 31 +- tutorials/columnar-tribuo-v4.ipynb | 19 +- tutorials/configuration-tribuo-v4.ipynb | 48 +-- .../document-classification-tribuo-v4.ipynb | 390 +++++++++--------- tutorials/external-models-tribuo-v4.ipynb | 6 +- tutorials/feature-selection-tribuo-v4.ipynb | 54 +-- tutorials/irises-tribuo-v4.ipynb | 86 ++-- tutorials/modelcard-tribuo-v4.ipynb | 56 +-- tutorials/multi-label-tribuo-v4.ipynb | 22 +- tutorials/onnx-export-tribuo-v4.ipynb | 78 ++-- tutorials/regression-tribuo-v4.ipynb | 18 +- tutorials/reproducibility-tribuo-v4.ipynb | 98 +++-- tutorials/tensorflow-tribuo-v4.ipynb | 66 +-- 72 files changed, 725 insertions(+), 564 deletions(-) create mode 100644 docs/release-notes/tribuo-v4-3-release-notes.md diff --git a/AnomalyDetection/Core/pom.xml b/AnomalyDetection/Core/pom.xml index 0e5897b38..75672a09b 100644 --- a/AnomalyDetection/Core/pom.xml +++ b/AnomalyDetection/Core/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-anomaly - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml AnomalyDetection-Core diff --git a/AnomalyDetection/LibLinear/pom.xml b/AnomalyDetection/LibLinear/pom.xml index 43736051a..07c3d2069 100644 --- a/AnomalyDetection/LibLinear/pom.xml +++ b/AnomalyDetection/LibLinear/pom.xml @@ -20,7 +20,7 @@ org.tribuo tribuo-anomaly - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml AnomalyDetection-LibLinear diff --git a/AnomalyDetection/LibSVM/pom.xml b/AnomalyDetection/LibSVM/pom.xml index a065d2b53..139421b45 100644 --- a/AnomalyDetection/LibSVM/pom.xml +++ b/AnomalyDetection/LibSVM/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-anomaly - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml AnomalyDetection-LibSVM diff --git a/AnomalyDetection/pom.xml b/AnomalyDetection/pom.xml index 6c67d6f32..4f7ad4646 100644 --- a/AnomalyDetection/pom.xml +++ b/AnomalyDetection/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml tribuo-anomaly diff --git a/Classification/Core/pom.xml b/Classification/Core/pom.xml index 66aeaecba..8dfe61fa0 100644 --- a/Classification/Core/pom.xml +++ b/Classification/Core/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-classification - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Classification-Core diff --git a/Classification/DecisionTree/pom.xml b/Classification/DecisionTree/pom.xml index bb8aefece..f8bf11b02 100644 --- a/Classification/DecisionTree/pom.xml +++ b/Classification/DecisionTree/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-classification - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Classification-Tree diff --git a/Classification/Experiments/pom.xml b/Classification/Experiments/pom.xml index 1572b4a53..879d55aba 100644 --- a/Classification/Experiments/pom.xml +++ b/Classification/Experiments/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-classification - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Classification-Experiments diff --git a/Classification/Explanations/pom.xml b/Classification/Explanations/pom.xml index bac01b775..ee6cfec24 100644 --- a/Classification/Explanations/pom.xml +++ b/Classification/Explanations/pom.xml @@ -20,7 +20,7 @@ org.tribuo tribuo-classification - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Classification-Explanations diff --git a/Classification/FeatureSelection/pom.xml b/Classification/FeatureSelection/pom.xml index 040524c71..7923d322a 100644 --- a/Classification/FeatureSelection/pom.xml +++ b/Classification/FeatureSelection/pom.xml @@ -20,7 +20,7 @@ org.tribuo tribuo-classification - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Classification-FeatureSelection diff --git a/Classification/LibLinear/pom.xml b/Classification/LibLinear/pom.xml index 04f586b41..9ed4d5d2b 100644 --- a/Classification/LibLinear/pom.xml +++ b/Classification/LibLinear/pom.xml @@ -20,7 +20,7 @@ org.tribuo tribuo-classification - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Classification-LibLinear diff --git a/Classification/LibSVM/pom.xml b/Classification/LibSVM/pom.xml index ef1f5423e..356809703 100644 --- a/Classification/LibSVM/pom.xml +++ b/Classification/LibSVM/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-classification - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Classification-LibSVM diff --git a/Classification/MultinomialNaiveBayes/pom.xml b/Classification/MultinomialNaiveBayes/pom.xml index 45463b446..e18b32866 100644 --- a/Classification/MultinomialNaiveBayes/pom.xml +++ b/Classification/MultinomialNaiveBayes/pom.xml @@ -22,7 +22,7 @@ org.tribuo tribuo-classification - 4.3.0-SNAPSHOT + 4.3.0 Classification-MultinomialNaiveBayes tribuo-classification-mnnaivebayes diff --git a/Classification/SGD/pom.xml b/Classification/SGD/pom.xml index 1da87d230..103b455d8 100644 --- a/Classification/SGD/pom.xml +++ b/Classification/SGD/pom.xml @@ -20,7 +20,7 @@ org.tribuo tribuo-classification - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Classification-SGD diff --git a/Classification/XGBoost/pom.xml b/Classification/XGBoost/pom.xml index 62666e718..be381123d 100644 --- a/Classification/XGBoost/pom.xml +++ b/Classification/XGBoost/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-classification - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Classification-XGBoost diff --git a/Classification/pom.xml b/Classification/pom.xml index 2cb681313..2eae3f95b 100644 --- a/Classification/pom.xml +++ b/Classification/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml tribuo-classification diff --git a/Clustering/Core/pom.xml b/Clustering/Core/pom.xml index de284dffc..048d58db7 100644 --- a/Clustering/Core/pom.xml +++ b/Clustering/Core/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-clustering - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Clustering-Core diff --git a/Clustering/Hdbscan/pom.xml b/Clustering/Hdbscan/pom.xml index 446bd587d..d8a0ccb36 100644 --- a/Clustering/Hdbscan/pom.xml +++ b/Clustering/Hdbscan/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-clustering - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Clustering-Hdbscan diff --git a/Clustering/KMeans/pom.xml b/Clustering/KMeans/pom.xml index 517b6b018..8e6250b52 100644 --- a/Clustering/KMeans/pom.xml +++ b/Clustering/KMeans/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-clustering - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Clustering-KMeans diff --git a/Clustering/pom.xml b/Clustering/pom.xml index 3d321b91d..285d645f9 100644 --- a/Clustering/pom.xml +++ b/Clustering/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml tribuo-clustering diff --git a/Common/LibLinear/pom.xml b/Common/LibLinear/pom.xml index c1b2595a7..3e30d80b9 100644 --- a/Common/LibLinear/pom.xml +++ b/Common/LibLinear/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-common - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Common-LibLinear diff --git a/Common/LibSVM/pom.xml b/Common/LibSVM/pom.xml index f567a4d3f..2e856b60b 100644 --- a/Common/LibSVM/pom.xml +++ b/Common/LibSVM/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-common - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Common-LibSVM diff --git a/Common/NearestNeighbour/pom.xml b/Common/NearestNeighbour/pom.xml index 7e2fae4d4..30738e96e 100644 --- a/Common/NearestNeighbour/pom.xml +++ b/Common/NearestNeighbour/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-common - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Common-NearestNeighbour diff --git a/Common/SGD/pom.xml b/Common/SGD/pom.xml index 2de721669..ea83850df 100644 --- a/Common/SGD/pom.xml +++ b/Common/SGD/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-common - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Common-SGD diff --git a/Common/Trees/pom.xml b/Common/Trees/pom.xml index cea202cb9..8cf5bee12 100644 --- a/Common/Trees/pom.xml +++ b/Common/Trees/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-common - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Common-Tree diff --git a/Common/XGBoost/pom.xml b/Common/XGBoost/pom.xml index 4b170ed99..bdd0039a1 100644 --- a/Common/XGBoost/pom.xml +++ b/Common/XGBoost/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-common - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Common-XGBoost diff --git a/Common/pom.xml b/Common/pom.xml index 1192e611c..0f1618f5e 100644 --- a/Common/pom.xml +++ b/Common/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml tribuo-common diff --git a/Core/pom.xml b/Core/pom.xml index 2beac4a62..c8b2b287c 100644 --- a/Core/pom.xml +++ b/Core/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Core diff --git a/Data/pom.xml b/Data/pom.xml index e8a1b2a4a..9a74e0372 100644 --- a/Data/pom.xml +++ b/Data/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Data diff --git a/Interop/Core/pom.xml b/Interop/Core/pom.xml index 36f007685..fda41ed94 100644 --- a/Interop/Core/pom.xml +++ b/Interop/Core/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-interop - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Interop-Core diff --git a/Interop/ModelCard/pom.xml b/Interop/ModelCard/pom.xml index 5ad71462e..174b692e0 100644 --- a/Interop/ModelCard/pom.xml +++ b/Interop/ModelCard/pom.xml @@ -5,7 +5,7 @@ tribuo-interop org.tribuo - 4.3.0-SNAPSHOT + 4.3.0 4.0.0 ModelCard diff --git a/Interop/OCI/pom.xml b/Interop/OCI/pom.xml index febb8cb8c..8d2ba3e01 100644 --- a/Interop/OCI/pom.xml +++ b/Interop/OCI/pom.xml @@ -20,7 +20,7 @@ org.tribuo tribuo-interop - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml OCI diff --git a/Interop/ONNX/pom.xml b/Interop/ONNX/pom.xml index d9c47d840..c8a55cf92 100644 --- a/Interop/ONNX/pom.xml +++ b/Interop/ONNX/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-interop - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Interop-ONNX diff --git a/Interop/Tensorflow/pom.xml b/Interop/Tensorflow/pom.xml index cb3b7432d..05c403fa7 100644 --- a/Interop/Tensorflow/pom.xml +++ b/Interop/Tensorflow/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-interop - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Interop-Tensorflow diff --git a/Interop/pom.xml b/Interop/pom.xml index 0da938c66..4348ca943 100644 --- a/Interop/pom.xml +++ b/Interop/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml tribuo-interop diff --git a/Json/pom.xml b/Json/pom.xml index 9388a31fe..1f0b9b03a 100644 --- a/Json/pom.xml +++ b/Json/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 4.0.0 Json diff --git a/Math/pom.xml b/Math/pom.xml index 0f4ea98c7..a1cbf34e7 100644 --- a/Math/pom.xml +++ b/Math/pom.xml @@ -20,7 +20,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Math diff --git a/MultiLabel/Core/pom.xml b/MultiLabel/Core/pom.xml index 5c71cb8cd..c021ea69e 100644 --- a/MultiLabel/Core/pom.xml +++ b/MultiLabel/Core/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-multilabel - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml MultiLabel-Core diff --git a/MultiLabel/SGD/pom.xml b/MultiLabel/SGD/pom.xml index d0b3b260c..459fd5c5f 100644 --- a/MultiLabel/SGD/pom.xml +++ b/MultiLabel/SGD/pom.xml @@ -20,7 +20,7 @@ org.tribuo tribuo-multilabel - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml MultiLabel-SGD diff --git a/MultiLabel/pom.xml b/MultiLabel/pom.xml index ae0109646..c0f9f40fd 100644 --- a/MultiLabel/pom.xml +++ b/MultiLabel/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml tribuo-multilabel diff --git a/README.md b/README.md index 929af111b..d50aceeed 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

Tribuo Logo

-# Tribuo - A Java prediction library (v4.2) +# Tribuo - A Java prediction library (v4.3) [Tribuo](https://tribuo.org) is a machine learning library in Java that provides multi-class classification, regression, clustering, anomaly detection @@ -13,10 +13,10 @@ Learning Research Group; we welcome community contributions. All trainers are configurable using the [OLCUT](https://github.com/oracle/olcut) configuration system. This allows a -user to define a trainer in an xml file and repeatably build models. Example -configurations for each of the supplied Trainers can be found in the config -folder of each package. These configuration files can also be written in json -or edn by using the appropriate OLCUT configuration dependency. Models and +user to define a trainer in an xml or json file and repeatably build models. +Example configurations for each of the supplied Trainers can be found in the +config folder of each package. These configuration files can also be written in +json or edn by using the appropriate OLCUT configuration dependency. Models and datasets are serializable using Java serialization. All models and evaluations include a serializable provenance object which @@ -37,15 +37,15 @@ architectures on Windows 10, macOS and Linux (RHEL/OL/CentOS 7+), as these are supported platforms for the native libraries with which we interface. If you're interested in another platform and wish to use one of the native library interfaces (ONNX Runtime, TensorFlow, and XGBoost), we recommend reaching out -to the developers of those libraries. Note the reproducibility package -requires Java 17, and as such is not part of the `tribuo-all` Maven Central -deployment. +to the developers of those libraries. Note the model card and reproducibility +packages require Java 17, and as such are not part of the `tribuo-all` Maven +Central deployment. ## Documentation * [Library Architecture](docs/Architecture.md) * [Package Overview](docs/PackageOverview.md) -* Javadoc [4.2](https://tribuo.org/learn/4.2/javadoc), [4.1](https://tribuo.org/learn/4.1/javadoc/), [4.0](https://tribuo.org/learn/4.0/javadoc/) +* Javadoc [4.3](https://tribuo.org/learn/4.3/javadoc), [4.2](https://tribuo.org/learn/4.2/javadoc), [4.1](https://tribuo.org/learn/4.1/javadoc/), [4.0](https://tribuo.org/learn/4.0/javadoc/) * [Helper Programs](docs/HelperPrograms.md) * [Developer Documentation](docs/Internals.md) * [Roadmap](docs/Roadmap.md) @@ -58,9 +58,9 @@ Regression, Anomaly Detection, TensorFlow, document classification, columnar data loading, working with externally trained models, and the configuration system, can be found in the [tutorials](tutorials). These use the [IJava](https://github.com/SpencerPark/IJava) Jupyter notebook kernel, and work -with Java 10+, except the reproducibility tutorial which requires Java 17. To -convert the tutorials' code back to Java 8, in most cases simply replace the -`var` keyword with the appropriate types. +with Java 10+, except the model card & reproducibility tutorials which require +Java 17. To convert the tutorials' code back to Java 8, in most cases simply +replace the `var` keyword with the appropriate types. ## Algorithms @@ -101,6 +101,13 @@ Tribuo has implementations or interfaces for: Tribuo also supplies a linear chain CRF for sequence classification tasks. This CRF is trained via SGD using any of Tribuo's gradient optimizers. +Tribuo has a set of information theoretic feature selection algorithms which +can be applied to classification tasks. Feature inputs are automatically +discretised into equal width bins. At the moment this includes implementations +of mutual information maximisation (MIM), Conditional Mutual Information +Maximisation (CMIM), minimum Redundancy Maximum Relevancy (mRMR) and Joint +Mutual Information (JMI). + To explain classifier predictions there is an implementation of the LIME algorithm. Tribuo's implementation allows the mixing of text and tabular data, along with the use of any sparse model as an explainer (e.g., regression trees, @@ -167,37 +174,38 @@ discuss how it would fit into Tribuo. Currently we have interfaces to: -* [LibLinear](https://github.com/bwaldvogel/liblinear-java) - via the LibLinear-java port of the original [LibLinear](https://www.csie.ntu.edu.tw/~cjlin/liblinear/) (v2.43). +* [LibLinear](https://github.com/bwaldvogel/liblinear-java) - via the LibLinear-java port of the original [LibLinear](https://www.csie.ntu.edu.tw/~cjlin/liblinear/) (v2.44). * [LibSVM](https://www.csie.ntu.edu.tw/~cjlin/libsvm/) - using the pure Java transformed version of the C++ implementation (v3.25). -* [ONNX Runtime](https://onnxruntime.ai) - via the Java API contributed by our group (v1.9.0). -* [TensorFlow](https://tensorflow.org) - Using [TensorFlow Java](https://github.com/tensorflow/java) v0.4.1 (based on TensorFlow v2.7.1). This allows the training and deployment of TensorFlow models entirely in Java. -* [XGBoost](https://xgboost.ai) - via the built in XGBoost4J API (v1.5.0). +* [ONNX Runtime](https://onnxruntime.ai) - via the Java API contributed by our group (v1.12.1). +* [TensorFlow](https://tensorflow.org) - Using [TensorFlow Java](https://github.com/tensorflow/java) v0.4.2 (based on TensorFlow v2.7.4). This allows the training and deployment of TensorFlow models entirely in Java. +* [XGBoost](https://xgboost.ai) - via the built in XGBoost4J API (v1.6.2). ## Binaries Binaries are available on Maven Central, using groupId `org.tribuo`. To pull -all of Tribuo, including the bindings for TensorFlow, ONNX Runtime and XGBoost -(which are native libraries), use: +all the Java 8 compatible components of Tribuo, including the bindings for +TensorFlow, ONNX Runtime and XGBoost (which are native libraries), use: Maven: ```xml org.tribuo tribuo-all - 4.2.1 + 4.3.0 pom ``` or from Gradle: ```groovy -implementation ("org.tribuo:tribuo-all:4.2.1@pom") { +implementation ("org.tribuo:tribuo-all:4.3.0@pom") { transitive = true // for build.gradle (i.e., Groovy) // isTransitive = true // for build.gradle.kts (i.e., Kotlin) } ``` The `tribuo-all` dependency is a pom which depends on all the Tribuo -subprojects except for the reproducibility project which requires Java 17. +subprojects except for the model card and reproducibility projects which +require Java 17. Most of Tribuo is pure Java and thus cross-platform, however some of the interfaces link to libraries which use native code. Those interfaces @@ -207,9 +215,11 @@ are supplied. If you need support for a specific platform, reach out to the maintainers of those projects. As of the 4.1 release these native packages all provide x86\_64 binaries for Windows, macOS and Linux. It is also possible to compile each package for macOS ARM64 (i.e., Apple Silicon), though there are no -binaries available on Maven Central for that platform. When developing on an -ARM platform you can select the `arm` profile in Tribuo's pom.xml to disable -the native library tests. +binaries available on Maven Central for that platform for TensorFlow or +XGBoost. As of the 4.3 release Tribuo now depends on a version of ONNX Runtime +which includes support for macOS ARM64 and Linux aarch64 platforms. When +developing on an ARM platform you can select the `arm` profile in Tribuo's +`pom.xml` to disable the native library tests. Individual jars are published for each Tribuo module. It is preferable to depend only on the modules necessary for the specific project. This prevents @@ -223,7 +233,8 @@ with the latest release. To build, simply run `mvn clean package`. All Tribuo's dependencies should be available on Maven Central. Please file an issue for build-related issues if you're having trouble (though do check if you're missing proxy settings for Maven first, as that's a common cause of build -failures, and out of our control). +failures, and out of our control). Note if you're building using Java 16 or +earlier the model card and reproducibility packages will be disabled. ## Repository Layout @@ -254,6 +265,7 @@ Tribuo is licensed under the [Apache 2.0 License](./LICENSE.txt). ## Release Notes: +- [v4.3.0](https://github.com/oracle/tribuo/blob/main/docs/release-notes/tribuo-v4-3-release-notes.md) - Model card support, feature selection for classification, protobuf serialization format, kd-tree for distance computations, speed improvements for sparse linear models. Version bumps for most dependencies, and various other small fixes and improvements. - [v4.2.1](https://github.com/oracle/tribuo/blob/main/docs/release-notes/tribuo-v4-2-1-release-notes.md) - Bug fixes for KMeans' multithreading, nondeterministic iteration orders affecting ONNX export and K-Means initialization, and upgraded TF-Java to 0.4.1. - [v4.2.0](https://github.com/oracle/tribuo/blob/main/docs/release-notes/tribuo-v4-2-release-notes.md) - Added factorization machines, classifier chains, HDBSCAN. Added ONNX export and OCI Data Science integration. Added reproducibility framework. Various other small fixes and improvements, including the regression fixes from v4.1.1. Filled out the remaining javadoc, added 4 new tutorials (onnx export, multi-label classification, reproducibility, hdbscan), expanded existing tutorials. - [v4.1.1](https://github.com/oracle/tribuo/blob/main/docs/release-notes/tribuo-v4-1-1-release-notes.md) - Bug fixes for multi-output regression, multi-label evaluation, KMeans & KNN with SecurityManager, and update TF-Java 0.4.0. diff --git a/Regression/Core/pom.xml b/Regression/Core/pom.xml index 98640b92e..57a7ce958 100644 --- a/Regression/Core/pom.xml +++ b/Regression/Core/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-regression - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Regression-Core diff --git a/Regression/LibLinear/pom.xml b/Regression/LibLinear/pom.xml index 848c33031..251333abe 100644 --- a/Regression/LibLinear/pom.xml +++ b/Regression/LibLinear/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-regression - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Regression-LibLinear diff --git a/Regression/LibSVM/pom.xml b/Regression/LibSVM/pom.xml index f99daa86b..55efa60a0 100644 --- a/Regression/LibSVM/pom.xml +++ b/Regression/LibSVM/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-regression - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Regression-LibSVM diff --git a/Regression/RegressionTree/pom.xml b/Regression/RegressionTree/pom.xml index 9984cc7de..a70ad74f4 100644 --- a/Regression/RegressionTree/pom.xml +++ b/Regression/RegressionTree/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-regression - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Regression-Tree diff --git a/Regression/SGD/pom.xml b/Regression/SGD/pom.xml index 1b9eed27e..f9ad1a88d 100644 --- a/Regression/SGD/pom.xml +++ b/Regression/SGD/pom.xml @@ -20,7 +20,7 @@ org.tribuo tribuo-regression - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Regression-SGD diff --git a/Regression/SLM/pom.xml b/Regression/SLM/pom.xml index b95a8faf6..3222dadac 100644 --- a/Regression/SLM/pom.xml +++ b/Regression/SLM/pom.xml @@ -20,7 +20,7 @@ org.tribuo tribuo-regression - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Regression-SLM diff --git a/Regression/XGBoost/pom.xml b/Regression/XGBoost/pom.xml index 217c800e3..a45d59ab6 100644 --- a/Regression/XGBoost/pom.xml +++ b/Regression/XGBoost/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-regression - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Regression-XGBoost diff --git a/Regression/pom.xml b/Regression/pom.xml index 51103ce4b..d349b24a0 100644 --- a/Regression/pom.xml +++ b/Regression/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml tribuo-regression diff --git a/Reproducibility/pom.xml b/Reproducibility/pom.xml index 9b7dc416c..3a6702d52 100644 --- a/Reproducibility/pom.xml +++ b/Reproducibility/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 4.0.0 Reproducibility diff --git a/Util/InformationTheory/pom.xml b/Util/InformationTheory/pom.xml index 8f486ba0c..692e34ffb 100644 --- a/Util/InformationTheory/pom.xml +++ b/Util/InformationTheory/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-util - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml InformationTheory diff --git a/Util/ONNXExport/pom.xml b/Util/ONNXExport/pom.xml index af044cd59..2bf8f77b6 100644 --- a/Util/ONNXExport/pom.xml +++ b/Util/ONNXExport/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-util - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml ONNXExport diff --git a/Util/Tokenization/pom.xml b/Util/Tokenization/pom.xml index 1301629d2..242c60919 100644 --- a/Util/Tokenization/pom.xml +++ b/Util/Tokenization/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo-util - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml Tokenization diff --git a/Util/pom.xml b/Util/pom.xml index e8d61b3a7..46680b699 100644 --- a/Util/pom.xml +++ b/Util/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml tribuo-util diff --git a/distribution/pom.xml b/distribution/pom.xml index 8b6958d0c..278ce6694 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -21,7 +21,7 @@ org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml diff --git a/docs/release-notes/tribuo-v4-3-release-notes.md b/docs/release-notes/tribuo-v4-3-release-notes.md new file mode 100644 index 000000000..f586bc75c --- /dev/null +++ b/docs/release-notes/tribuo-v4-3-release-notes.md @@ -0,0 +1,117 @@ +# Tribuo v4.3 Release Notes + +Tribuo v4.3 adds feature selection for classification problems, support for +guided generation of model cards, and protobuf serialization for all +serializable classes. In addition there is a new interface for distance based +computations which can now use a kd-tree or brute force comparisons, the sparse +linear model package has been rewritten to use Tribuo's linear algebra system +improving the speed and reducing memory consumption, and we've added some more +tutorials. + +Note this is likely the last feature release of Tribuo to support Java 8. The +next major version of Tribuo will require Java 17. In addition, support for +using `java.io.Serializable` for serialization will be removed in the next +major release, and Tribuo will exclusively use protobuf based serialization. + +## Feature Selection + +In this release we've added support for feature selection algorithms to the +dataset and provenance systems, along with implementations of 4 information +theoretic feature selection algorithms for use in classification problems. The +algorithms (MIM, CMIM, mRMR and JMI) are described in this [review +paper](https://jmlr.org/papers/v13/brown12a.html). Continuous inputs are +discretised into a fixed number of equal width bins before the mutual +information is computed. These algorithms are a useful feature selection +baseline, and we welcome contributions to extend the set of supported +algorithms. + +- Feature selection algorithms [#254](https://github.com/oracle/tribuo/pull/254). + +## Model Card Support + +[Model Cards](https://dl.acm.org/doi/10.1145/3287560.3287596) are a popular way +of describing a model, its training data, expected applications and any use +cases that should be avoided. In this release we've added guided generation of +model cards, where many fields are automatically generated from the provenance +information inside each Tribuo model. Fields which require user input (such as +the expected use cases for a model, or its license) can be added via a CLI +program, and the resulting model card can be saved in json format. + +At the moment, the automatic data extraction fails on some kinds of nested +ensemble models which are generated without using a Tribuo `Trainer` class, +in the future we'll look at improving the data extraction for this case. + +- Model card infrastructure ([#243](https://github.com/oracle/tribuo/pull/243), [#250](https://github.com/oracle/tribuo/pull/250), [#253](https://github.com/oracle/tribuo/pull/253)). + +## Protobuf Serialization + +In this release we've added [protocol +buffer](https://developers.google.com/protocol-buffers) definitions for +serializing all of Tribuo's serializable types, along with the necessary code +to interact with those definitions. This effort has improved the validation of +serialized data, and will allow Tribuo models to be upwards compatible across +major versions of Tribuo. Any serialized model or dataset from Tribuo v4.2 or +earlier can be loaded in and saved out into the new format which will ensure +compatibility with the next major version of Tribuo. + +- Protobuf support for core types ([#226](https://github.com/oracle/tribuo/pull/226), [#255](https://github.com/oracle/tribuo/pull/255), [#262](https://github.com/oracle/tribuo/pull/262), [#264](https://github.com/oracle/tribuo/pull/264)). +- Protobuf support for models (Multinomial Naive Bayes [#267](https://github.com/oracle/tribuo/pull/267), Sparse linear models [#269](https://github.com/oracle/tribuo/pull/269), XGBoost [#270](https://github.com/oracle/tribuo/pull/270), OCI, ONNX and TF [#271](https://github.com/oracle/tribuo/pull/271), LibSVM [#272](https://github.com/oracle/tribuo/pull/272), LibLinear [#273](https://github.com/oracle/tribuo/pull/273), SGD [#275](https://github.com/oracle/tribuo/pull/275), Clustering models [#276](https://github.com/oracle/tribuo/pull/276), Baseline models and ensembles [#277](https://github.com/oracle/tribuo/pull/277), Trees [#278](https://github.com/oracle/tribuo/pull/278)). +- Docs and supporting programs ([#279](https://github.com/oracle/tribuo/pull/279)). + +## Smaller improvements + +We added an interface for querying the nearest neighbours of a vector, and +updated HDBSCAN, K-Means and K-NN to use the new interface. The old +implementation has been renamed the "brute force" search operator, and a new +implementation which uses a kd-tree has been added. + +- Distance refactor ([#213](https://github.com/oracle/tribuo/pull/213), [#216](https://github.com/oracle/tribuo/pull/216), [#221](https://github.com/oracle/tribuo/pull/221), [#231](https://github.com/oracle/tribuo/pull/231), [#285](https://github.com/oracle/tribuo/pull/285)). + +We migrated off Apache Commons Math, which necessitated adding several methods +to Tribuo's math library. In the process we refactored the sparse linear model +code, removing redundant matrix operations and greatly improving the speed of +LASSO. + +- Refactor sparse linear models and remove Apache Commons Math ([#241](https://github.com/oracle/tribuo/pull/241)). + +The ONNX export support has been refactored to allow the use of different ONNX +opsets, and custom ONNX operations. This allows users of Tribuo's ONNX export +support to supply their own operations, and increases the flexibility of the +ONNX support on the JVM. + +- ONNX operator refactor ([#245](https://github.com/oracle/tribuo/pull/245)). + +ONNX Runtime has been upgraded to v1.12.1, which includes Linux ARM64 and macOS +ARM64 binaries. As a result we've removed the ONNX tests from the arm Maven +profile, and so those tests will execute on Linux & macOS ARM64 platforms. + +- ONNX Runtime upgrade ([#256](https://github.com/oracle/tribuo/pull/256)). + +## Small improvements + +- Improved the assignment to the noise cluster in HDBSCAN ([#222](https://github.com/oracle/tribuo/pull/222)). +- Upgrade liblinear-java to v2.44 ([#228](https://github.com/oracle/tribuo/pull/228)). +- Added accessors for the HDBSCAN cluster exemplars ([#229](https://github.com/oracle/tribuo/pull/229)). +- Improve validation of salts when hashing feature names ([#237](https://github.com/oracle/tribuo/pull/237)). +- Added accessors to TransformedModel for the wrapped model ([#244](https://github.com/oracle/tribuo/pull/244)). +- Added a regex text preprocessor ([#247](https://github.com/oracle/tribuo/pull/247)). +- Upgrade OpenCSV to v5.6 ([#259](https://github.com/oracle/tribuo/pull/259)). +- Added a builder to RowProcessor to make it less confusing ([#263](https://github.com/oracle/tribuo/pull/263)). +- Upgrade TF-Java to v0.4.2 ([#281](https://github.com/oracle/tribuo/pull/281)). +- Upgrade OCI Java SDK to v2.46.0, protobuf-java to 3.19.6, XGBoost to 1.6.2, jackson to 2.14.0-rc1 ([#288](https://github.com/oracle/tribuo/pull/288)). + +## Bug Fixes + +- Fix for HDBSCAN small cluster generation ([#236](https://github.com/oracle/tribuo/pull/236)). +- XGBoost provenance capture ([#239](https://github.com/oracle/tribuo/pull/239). + +## Contributors + +- Adam Pocock ([@Craigacp](https://github.com/Craigacp)) +- Jack Sullivan ([@JackSullivan](https://github.com/JackSullivan)) +- Romina Mahinpei ([@rmahinpei](https://github.com/rmahinpei)) +- Philip Ogren ([@pogren](https://github.com/pogren)) +- Katie Younglove ([@katieyounglove](https://github.com/katieyounglove)) +- Jeffrey Alexander ([@jhalexand](https://github.com/jhalexand)) +- Geoff Stewart ([@geoffreydstewart](https://github.com/geoffreydstewart)) + diff --git a/pom.xml b/pom.xml index 44f2a065a..08fdb5c78 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.tribuo tribuo - 4.3.0-SNAPSHOT + 4.3.0 pom Core diff --git a/tests/pom.xml b/tests/pom.xml index 676369b66..30dd07930 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -21,7 +21,7 @@ tribuo org.tribuo - 4.3.0-SNAPSHOT + 4.3.0 ../pom.xml 4.0.0 diff --git a/tutorials/anomaly-tribuo-v4.ipynb b/tutorials/anomaly-tribuo-v4.ipynb index 82051953f..3f3a12471 100644 --- a/tutorials/anomaly-tribuo-v4.ipynb +++ b/tutorials/anomaly-tribuo-v4.ipynb @@ -19,7 +19,7 @@ "metadata": {}, "outputs": [], "source": [ - "%jars ./tribuo-anomaly-libsvm-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars ./tribuo-anomaly-libsvm-4.3.0-jar-with-dependencies.jar" ] }, { @@ -111,7 +111,7 @@ "obj = 289.5926348816893, rho = 3.144570476807895\n", "nSV = 296, nBSV = 114\n", "\n", - "Training took (00:00:00:147)\n" + "Training took (00:00:00:124)\n" ] } ], @@ -210,7 +210,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "17+35-LTS-2724" + "version": "12+33" } }, "nbformat": 4, diff --git a/tutorials/clustering-hdbscan-tribuo-v4.ipynb b/tutorials/clustering-hdbscan-tribuo-v4.ipynb index d0ddea3ca..bf903c03d 100644 --- a/tutorials/clustering-hdbscan-tribuo-v4.ipynb +++ b/tutorials/clustering-hdbscan-tribuo-v4.ipynb @@ -19,7 +19,7 @@ "metadata": {}, "outputs": [], "source": [ - "%jars ./tribuo-clustering-hdbscan-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", + "%jars ./tribuo-clustering-hdbscan-4.3.0-jar-with-dependencies.jar\n", "%jars ./xchart-3.8.1.jar" ] }, @@ -168,9 +168,9 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ - "BufferedImage@73685dc: type = 1 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0 IntegerInterleavedRaster: width = 600 height = 400 #Bands = 3 xOff = 0 yOff = 0 dataOffset[0] 0" + "BufferedImage@3d9dd79d: type = 1 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0 IntegerInterleavedRaster: width = 600 height = 400 #Bands = 3 xOff = 0 yOff = 0 dataOffset[0] 0" ] }, "execution_count": 8, @@ -271,9 +271,9 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ - "BufferedImage@7fc7c755: type = 1 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0 IntegerInterleavedRaster: width = 600 height = 400 #Bands = 3 xOff = 0 yOff = 0 dataOffset[0] 0" + "BufferedImage@3193ef05: type = 1 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0 IntegerInterleavedRaster: width = 600 height = 400 #Bands = 3 xOff = 0 yOff = 0 dataOffset[0] 0" ] }, "execution_count": 12, @@ -374,9 +374,9 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "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+ully5bp1RZCCCBczgrSQi9xJ4SDBg2qVKnS0qVLe/ToUWII/W6//fb8/Hx71dgAgRchhABC8/HHx6+gvbRuredR7rgQwuXLlyclJQ0YMMCcPnEIR44cOWXKlAULFgwdOjQxMdFMTp48Wc0QQgDhGjFC989eataU7dv1MModF0I4ePBgk7TLL788JSWlTp065nTdunXvvPNOPVfUJZdcYib79++vzieEACLA2UIq6BkuhHD06NHJhapXr27yZv5/ww03mFXdu3c3dZw9e7Y5vW3btjFjxuTk5JjTGRkZ9qQ5R10bIQQQGYEtpIJe4kIIA6mHRps0aWL+aD87NCsry5xOSkoyvaxQoYI53bBhw+zs7CKXJ4QAIshuIRX0GJdDOHXq1NTU1OnTp9t/NAd85o/2E0Tz8vJeeeWVPn36dLSMHDnSWcECQgggstLSqKDXuBzC8BFCAEA4CCEAwNMIIQDA0whhfDt8+PAnn3zChyEAQKkRwnj1+++/z5kz5+abb7Y/FWHw4MFff/21HgIAlIQQxqsZM2b4PxvI1rNnzwMHDug5AMAJEcK49OOPP950000qhMby5cv1KADghAhhXNq1a5duoOW5557TowCAEyKEcWnv3r26gZbp06frUQDACRHCuHTkyJF77rlHVbB169YffPCBHgUAnBAhjFd79uzp0KFDYAhnz56thwAAJSGEcWzfvn0zZswYNmxYenr6jh079GoAQBAIIQDA0wghAMDTCCEAwNMIIQDA0wghAMDTCCEAwNMIIQDA0wghAMDTCCEAwNMIIQDA0wghAMDTCCEAwNPcDGF+fv6rr746a9asd955R68LGiEEAITDzRCOGDHCZ+nVq5deFzRCCAAIh2shXLlyZdWqVZOSkgghAMBF7oQwPz8/JSWlYcOGXbp0IYQAABe5E8Lhw4dXqFDhjTfe6NGjByEEALjIhRC+8847VapU6devnzld6hCODaDO1/9EAACK50IIBw8enJCQ0L59+44dO5533nkmhOeff35qaqqeCw4hBACEw50Q2k8WDXTppZfqueAQQgBAOFwIYaBSPzTqRwgBAOFwOYRTp05NTU2dPn26XhE0QggACIfLIQwfIQQAhIMQAgA8jRACADyNEAIAPI0QAgA8jRACADyNEAIAPI0QAgA8jRACADyNEAIAPI0QAgA8jRACADyNEAIAPI0QAgA8jRACADyNEAIAPI0QAgA8jRACADyNEAIAPI0QAgA8jRACADyNEAIAPI0QAgA8jRACADyNEAIAPM2dEObm5i5atGiWZcOGDXp1oXXr1q0K8N577+kJQggACI87Ibzwwgt9hRITE++99149YWnRooV/zEhOTtYThBAAEB53Qpiamvr000/PnDmza9euduRWr16thwpDeP/996dahg0bpicIIQAgPO6E0C8jI8M+KFy3bp1eVxjC6dOnn+ARVEIIAAiHayF87LHHbr/99jPOOKNGjRojR47Uqy2BD41WqFChd+/e/lVjAwRcghACAELjWgg7deqUnJxs8mYid9ttt+Xl5emJgoKHHnrINHLq1Kn33XefncNXXnlFzRBCAEA4XAuhLSMjIykpyRRu2rRpel1R9vNr+vfvr84nhACAcLgQwqysrFWrVtmnN2zYUK1aNVO4559/vsA6BOzYsePChQvN6ezs7JdeeskeW79+fc2aNc2Y80FUQggACIcLITSdS0hIaNCgwRVXXFGlShWTtzPOOGPz5s1mVZMmTcwf09PTC6xemtO1a9du3ry5Hcu6detu3LhRXRshBACEw4UQmsL17dv3uuuuS0lJufbaa/v162cO+OxVgUeEubm5aWlpnTt3NmMtWrTo06fPcZ9ZSggBAOFwIYSRRQgBAOEghAAATyOEAABPI4QAAE8jhAAATyOEAABPI4QAAE8jhAAATyOEAILwlkhLkZoizUQmixzV64H4RQgBlCRdxFd0eUCPAPGLEAI4oa9FKjtCaJZNehCIU4QQ8KR/iMwWGSeyuqTHOZc7EmgvaXoQiFOEEPCe10SqByStlcg+PfJvyxwJtJen9CAQpwgh4DEFIpUcVeuup/7tK5Ekx7xZNuhBIE4RQsBjHnUkzSwJIt/rwX973jF/jx4B4hchBDzmdkfV7GWHHixikUhzkSoiTUReEDmi1wPxixACHvOYI4FmSRT5UQ8CHkEIAY/5SKSqI4S8LhAu2b9//zPPPNOlS5eOHTuOHj36yy+/1BNljxACYfu79ZLzh0ReEflJr4xFy0VOD6jgHSI/6JGSvS8yQmSYyLt6DRCk7777rnPnzq0CtG/f/osvvtBzZYwQAuGZX/QA61yRv+mRWLRfZK5Vsu16TcmOWE+WCTygNCk9pKeAEr3wwguBFbT9+c9/1nNljBACYfj78R5mbCbyux6MLR+KXF24tVWsJ4WG9OSXFx3/ZLM8qaeAEvXs2VNnsFWrW2+99ejRE7/LQ4QRQiAMzzl6YC/5ejCGfCdSz7HBz+mpE7nScXGzXKCngBIdN4S33XYbIQwNIYSbUh09sJe39WAMSXNsrc86LjyoB4tVx3Fxn/Wi+6jedqE8GD9+vM5gfD00+vjjj2dlZelzo44Qwk1THT2wl8/0YAzp5Nhae9mlB4t1o+OyZrlcTwEl+u6777p06RJYwVtvvfWf//ynnitjpQ9hSkrK6aefnp6erldEFyEMl/me69ZN9u/X5yMY34uc5UhCNz0VW/o5Nthegr/xWW29E426+GI9BQTjX//617PPPtutW7dOnTqNGTPmq6++0hNlr/QhbNu2rc9iTmzYsEGvPqG0tDTzbzYpveaaa3r37r1mzRo9ETRCGBZTwUaNxOeTyy+nhaWUJ9I4oAddrV/CRcoBkb+I3C3ysMhf9coQ/GJ9mu5dIgOKeWj0Sn2JEswQqVF42SoiE/V6II6UPoS7du0aNGhQUlKSaWHNmjX79OmTWkiPOpx//vm1atU655xzKlasaC5+xhln7NixQw8FhxCWnr+C9kILS+2gyE6RJdZr1SPoG5FLiuaqlx4JyhfWM1kCr6dp0T/WLdVLPkzv14i8Y70SA4hnpQ+hLSMj4/TTT7cPDf30kMOqVavsEwsWLLAv8vbbbxcdCRYhLCVVQVoYg7oVzZW9vKanSnar40rM8meRB0U6iDxByeB1YYVw2bJlTZs2tUvWuHHjlEJ67njWr19vcjhs2DBz2fr163NEGFXHrSAtjCmHivlc+I56sAQ/i1RwXInPepgUgKX0ITQNsx/YrFWr1sSJE/Xqktxwww12QWvWrPnaa6/p1SUZG0Cdr/+JcEpP1/0LXObO1fOIvq8d6bKXUH+Z96njGuyllR4EPKv0ITRHfiZjt91226ZNm/S6IMyYMWP06NFt2rQxV1K9evXMzEw9ERxCWEp//rPun71MmKAn4ZZkR7181uOZITkqcqrjSswySA8CnlX6ELZv337KlCn63NCZI0LTwnHjxukVwSGEpedsIRWMKTMc9aom8omeKtkkx/XUFPmHngI8q/QhzMvL02cFZ/ny5XfffbeJ6KxZsx5++OGEhAQTwjlz5ui54BDCsAS2kAqWnSUi3UXaigwVCelVUpMC3sv0PJGNen1QjlrvoJZUeD0XimTrEcDLSh/CUnvzzTft3w7aKlSo8MADD+ihoBHCcNktpIJlp3fRo7HTQnwn0t9EckR267ND9qv1QRORfYEHUC64EEJj06ZN5nDwhRdeMP8v3a8Y/QhhBGws3YEGgrDc8bCkz/p4CpRL/yMySqSzyKOhvGUd3OZOCCOIEKKUfrfeFCYjlLcWKwV1OOhfov3Jo0H4p7U38mL+M6Ri1lqRUwK+xBVFpusRxCZCCE/KFbk04Darj/V6u7JQ3Dtch/ToaFn7xXoyqn/bLrHeKAch+eV47zpbWeRjPYgYRAjhPftFznTcZvXTU5HxjOMvMkt1kcN60E3OD5OqK7JPT+FE1jn2ob3wLqzxgBDCe8Y7bq181scpfKsHI+AHkXMcf9eLespN+4/3URK+ED+qFwsdO9BehulBxCBCCO+513FrZS9r9WBk7BX5Q+FfcZrIS3q9y9Y79oO93K0HcSIfOXagvSzSg4hBhBDeM9Jxa2Uvf9eDkfSjVcQY9JljP9jL43oQJbjHsQ8vt94zFjGPEMJ78qxn9KnbrCutF557UwvH3jjJej4RQvKzyH8GPM7cLiafG4zjIYTwpKlFW3iet19pbg6FGwbsjYrWpwGjdH4Q2Vw2v29GmSGE8Kr/sj6r3dyFf1nkJ73Sc3629oPZG0+JFOiVQPlGCAEAnkYIAQCeRggBt/0g8pD1oRC1rXei2aPXAyhThBBw1S8iFxV9xmZl3uEMiCpCCLjqiaIVtJcWegpA2SGEgKuud1TQLBXK7E3AATgQQsBV1zkqaJZEXtEBRA8hBFw1wlFBszTXUwDKDiEEykaQH2/7Y9F3dTFLJZFsPQWg7BBCINIyRVKst+s81fqkixLfbetf1icD17c+3/wP1luhAogiQghEVIbj4/0u4JkvQEwjhEBENXD8ws9nvakpgFhFCIHI+YcjgfbSTg8CiB2EEIicbx0JtJc79CCA2EEIgYhq6qigWaboKQCxw7UQbtmyJSMjY+XKlbt27dLrQkEIEVuyRaoWreC1Qb+U4sS+F/lOn1e2fg7iKa9A/HMhhLm5uRdddJGv0CmnnPLMM8/oIUuLFi38Y0ZycrKeIISIQR+L9LDeSru59TSZQ3p9yLZbV2Vn9TKRjXp95H0k0rrw6a/nibyt1wPliQshzMnJqVWrVp8+fdLS0uzUVaxYcd26dXquMITt2rXraOnVq5eeIIQo93Zbn0cReIh5kkiOnoqkr0VqOR7dXaGngHLDhRDm5eVlZ2fbp7Oysuyjvfnz5xedOsYO4bJly1atWmWOI/VqCyFEOdfJ0SSz3KSnImmA46/zWa+GBMopF0IYaMqUKT7r0dFt27bpdUUfGq1evfrw4cP9q8YGCLgEIUS5k+xokllqiBzVgxFzleOv81kPk+7Xg0D54GYI586dW6NGjYoVK7700kt6naVnz559+/Z96qmn2rVrZ+dw3rx5aoYQopy7xNEks9TTU5H0B8df57PeAfWAHgTKB9dCmJ6enpSUVK1atWnTpul1x9OwYUMTwocfflidTwhRzg12NMksffVUJE1y/HU+3hMA5Zk7IRw+fHhiYmLt2rUXL14ceP6YMWNSU1OXLVtmTm/fvn3JkiX2+dnZ2WbYhHDYsGGB8wWEEOXezyJNijbpAut9usvO7yI3Fv0b64p8pqeAcsOFEG7bts3/mz+/F1980axq0qSJOW0OFgsKn0dz0UUXtWvXrm7duj7rV4mZmZnq2gghyr8DIk+LtLX6NCYqb+H9u/UmAB2sF0EOFdmn1wPliQshzMnJSXGYO3euWdW9e3dzevbs2eb0zp07BwwY0LJly3POOadBgwYdOnTIyMjQ10UIAQDhcSGEkUUIAQDhIIQAAE8jhAAATyOEAABPI4QAAE8jhAAATyOEAABPI4QAAE8jhAAATyOEAABPI4QAAE8jhAAATyOEAABPI4QAAE8jhAAATyOEAABPI4QAAE8jhAAATyOEAABPI4QAAE8jhAAATyOEse6o+Q8AUGYIYezKlMwr5cqKUvE0Oe1+uX+/7NcTAICwEcIYtUJWJEiCT3z+5UK58Ff5Vc8BAMLjZgjXrFnz3nvv6XNDVF5DeLacHVhBe3lWntVzAIDwuBDC3Nzcyy+/vFKlSj5L7dq1J06cqIeCVi5D+Ll87qygWW6VW/UoACA8LoQwJyfn5JNP7t69+/Dhw5s1a2ZamJSUlJWVpeeCUy5D+LV87aygWTpLZz0KAAiPCyHMy8vbtGmTfXrdunX2ceH8+fOLTgWrXIbQaCyNnSF8SV7ScwCA8LgQwkDTpk0zFaxevfqWLVv0uuCU1xBula1VpEpgBa+T636X3/UcACA8bobwjTfeOPXUUxMTEydMmKDXlWRsAHW+/ifGrQ/lw+7SvZE0ai7N0yTtkBzSEwCAsLkWwpdffrlq1apJSUnhPFOmoPweEQIAosOdED711FMVKlSoWbPmvHnz9LoQEUIAQDhcCOH27dvtJ8jUqFEjudD06dP1XHAIIQBEzcGDB5cvXz5u3LgpU6bk5OTo1fHJhRCafZfiMHfuXD0XHEIIANGxb9++++67r1WASZMm6aE45EIII4sQAkB0jBo1KrCCtvXr1+u5eEMIAQAlO3jwYJs2bXQGW7V68skn9Wi8IYQAgJJ98803uoGWAQMG6NF4QwgBAEG5/fbbdQZbtZo8ebKeizeEEAAQlKVLl6oKtm/f/quvvtJz8YYQAgCCcvTo0QULFtx88812Be+6664PPvhAD8UhQggACMFvv/22e/fuvXv36hVxixACADyNEAIAPI0QAgA8jRACADyNEAIAPI0QAgA8jRACADyNEAIAPI0QAgA8jRACADyNEAIAPI0QAgA8jRACADyNEAIAPI0QAgA8jRACADyNEAIAPI0QAoCrfvxRDh/WZyKKCCEAuOeHH+Tqq6VLF1roIndCmJaWlpKSkmwZNGiQXl3o1ltvtWdszZo10xOEEED8sivo8x1baKF73Alh586dGzdu3KBBA5/P17t3b726UIsWLcyA6V+KpV27dnqCEAKIU4EVpIWucieEtm7dugUTwg0bNmRnZ+t1hQghgPjjrCAtdE8chDAxMdH8v379+uPHj/evGhsg4BJlGMLf5LfX5LVH5dGJMvET+USvBoAgFVdBWuiSmA5hhw4dOnfunJqaetVVV9lFXLJkiZqJTgg/lU8vlov936pVpeocmaOHACAYhw5Jx466f/5l4EA9jzIW0yH0y8vLO/vss83wwIED1aoohPCoHL1GrlHfrZWl8m7ZrUcBIBjFtZAKuiG2QjhmzBhz/Lds2TJzeseOHe+//759fm5ubnJyshkePHiwf9gWhRD+Xf7u+G49toyRMXoUAILkbCEVdIk7IRw6dGhKSkrt2rVN284880xzevTo0eb8Jk2amHPS09PN6aysrIoVK15//fXdu3e/5JJLzPmVK1d+99131VVFIYTvyXvOCprlPrlPjwJA8AJbSAXd404I+/btG/gCweTCVxPedNNN5vTUqVMLrCPCHj16NGzYsFq1alWrVr366qtff/11fUVRCeGX8qWzgmZ5QV7QowAQEruFVNBV7oQwgqIQQuMe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", "text/plain": [ - "BufferedImage@2b5e6079: type = 1 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0 IntegerInterleavedRaster: width = 600 height = 400 #Bands = 3 xOff = 0 yOff = 0 dataOffset[0] 0" + "BufferedImage@2b53682e: type = 1 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0 IntegerInterleavedRaster: width = 600 height = 400 #Bands = 3 xOff = 0 yOff = 0 dataOffset[0] 0" ] }, "execution_count": 16, @@ -448,9 +448,9 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAGQCAIAAAD9V4nPAAAs20lEQVR4Xu3dCXgUVbrG8U4QwqqogBhQUdxFuChRxC0qIIKILMIgKMgiN4OCbIIKghgVFALCgCCLKMgqggzKomEJa1hCkuuAOirXO47LFcZd2b97rLrp6XxFSHc66epO/X+ex6eo83VxqE7q7dNdXeXLBQDAw3x6BQAAXkIQAgA8jSAEAHgaQQgA8DSCEADgaQQhAMDTCEIAgKcRhAAATyMIAQCeFgNBOHr06MA/pqWljQYAIGhTp04NzBEl9oLQ/FEAAAiayhGFIAQAlHIEIQDA0whCAICnEYQAAE8jCAEAnkYQAgA8jSAEAHgaQQgAiD3/Etkm8oNeXRQEIQAglnwn0kHEl9ceDDsOCUIAQMkyQfWlXldEJ0SSA1LQbq11VWgIQgBASfmbyI15cXWuyALdH7K1jhS0W6YuDAFBCAAoEV+LnO1IrEW6KjRjHBu02yu6MAQEIQCgRPR3xJVpF+iq0MxxbNBuy3RhCAhCAECJaOKIK7t9qwtD8KVIFccGq4kc1IUhIAgBACXibkdimVZW5DddGJr5IgkBG6wk8o4uCQ1BCAAoEdMcKWhaC11VFHtFBou0FRkq8qnuDBlBCAAoEccdk8JaIvt1lfsIQgBASTkhMluknTURfErke90fFQhCAICnEYQAAE8jCAEAnkYQAgA8jSAEAHgaQQggVu0TWSqyR+So7kHxOCSy09rJ+3VPqUIQAog934ncE/DttGutUETx2i5SN2An9xD5VZeUEgQhgNjT0nG9kktL72HaFd9YF/BUOzlFVxXReuueglVF6os8I3JE94fge5FNYU9YCUIAMSbHcYC221xdiKJLdexe0+KK4xvxC6ztBG62hfW9+1CZ1z1/DtjUDSJ/1yXBcicIu3XrlhSgRYsWuiJoBCHgNW86DtB2e1wXouj+5Ni9dtukC0NzSOQsxzZ9RbpJYW/HRi4u6rsC7gRh48aNfT7fueeem2hp2LChrggaQQh4zWbHEdBuU3Qhim6oY/fa7X90YWh2OjZot1DfdP3SMa2023RdGBQ3gzAjI0N3hI4gBLzGzCoucxwBTxf5hy5E0WVZ90tSO/lWXRWyHY5t2u0/dWEhVjq2YLdQA9XmZhCed955ZjrYpEmTefPm6YrCjA6g1ut/IoBSZ7dI7YDDXxXrFH8Ur6ki5QJ28hVhn5Mi1ouYMx3p5bM+OAzJHscW7PasLgyKO0F40003NWzYsE2bNrVr1zaJWL58+VWrVumi4BCEgDf9YL0X2ldkQnEcoHFSH4qMFXlEZJbI77qziOY50qtZ6CfLHBW53LEdM4XN1YVBcScId+/ebS/s3LmzRo0aJgsHDx6cvyRYBCEAxJa1Ijdad5a/wro302HdH5RdIucEpOBpIpN1SbBcCMKsrCyTf/ZyTk7OhRdeaIKwf//++auCRRACgDcdsCasXawThvfozhC4EIQZGRnVqlXr0qXL8OHDmzZtalIwPj5+yZIlui44BCEAIBwuBGFmZmaTJk0SEhJ8lsTExPHjx+uioBGEAIBwuBCEfunp6evWrdNrQ0QQAgDC4WYQFguCEAAQDoIQAOBpBCEAwNMIQgCApxGEAABPIwgBAJ5GEAIAPI0gBAAU4juRl0X6iKSJfKE7Yx5BCAA4lS35L299usgKXVKI/da1QI/q1dGCIAQAFOgXkTqOGx6dKfK1Ljy5zID7JVW27pwVhQhCAECB1jpS0G6zdeFJ/Lc1fSzCAyOMIAQAFGimI8nsNkoXnsSfHY8yLVFXuY8gBAAUKNORZHZbqgtPorHjUXYL8m3ViCEIAQAFOiHS1JFk9YO7rXwbxwNNKydySBe6jCAEAJzKNyKtApKsichnuuTk5jhS0LR7dZX7CEIAQOE+FnlH5L/06kJ0yZ+Cl4h8pUvcRxACAErQWyK9RdqJjBf5VXdGBYIQKNxPP/1kfrrM/3UHgNhHEAKn8v33348YMSI5T2pq6s8//6yLAMQyghAo0IkTJ/r16+dPQduwYcN0HYBYRhACBdq5c6dKQdvevXt1KYCYRRACBXrzzTd1BlreeecdXQogZhGEQIFWr16tM9CyefNmXQogZhGEQIEOHDjQsmVLlYL33nsvp48CpYmbQZidnT179uxZs2a9++67us+yZMmSWQHmzZunKwhClLD09PTmzZv7U/Cuu+7aunWrLkJp8bX1nfFt0fp1N5QQN4Nw8ODBPkv37t11n6Vx48Z2gS0xMVFXEIQoeV988cX06dNHjhw5c+bMr76KwstioBgcFRkiUibvAiiJIqt1CUot14JwxYoVCQkJlSpVKjQIn3jiiVRLWlqariAIARSHVMclMStaFxWDF7gThNnZ2fXr17/iiivuu+++QoPQROBzzz23bNky3W0hCAGE6fjJ7h/rs26nBy9wJwgHDBhQrly5pUuXdu7cudAg9LvnnntycnLsrtEBAh9CEAII1eeOCLTbzboQpZMLQbh8+fKEhIR+/fqZ5VMH4fDhwydPnjx//vwhQ4bEx8ebykmTJqkaghBAmA6JlHWkoGlddSFKJxeCcNCgQSbSrrnmmqSkpBo1apjlmjVr3nfffbouvyuvvNJU9u3bV60nCAGE70+OFDRtla5C6eRCEI4cOTIxT+XKlU28mf/feuutpqtTp04mHWfPnm2Wt2/fPmrUqJ07d5rllStX2pVmjdoaQQggfN+JJAVEYLzICF2CUsuFIAyk3hqtX7+++aN9dmhGRoZZTkhIMHlZpkwZs1y3bt3MzMx8jycIARSToyLzRPqLPCOSqTtRmrkchFOnTk1JSZk+fbr9RzPhM3+0TxDNzs5+9dVXe/Xq1cYyfPhwZwrmEoQAgPC4HIThIwgBAOEgCAEAnkYQAgA8jSCMbUePHv3000+5GQIAFBlBGKuOHTs2Z86cZs2a2XdFGDRo0DfffKOLAACFIQhj1YwZM/z3BrJ17dr10KFDug4AcEoEYUz66aef7rjjDhWExvLly3UpAOCUCMKYtGfPHp2BlrFjx+pSAMApEYQxaf/+/ToDLdOnT9elAIBTIghj0vHjxx944AGVgrfddtuHH36oSwEAp0QQxqp9+/a1bt06MAhnz56tiwAAhSEIY9iBAwdmzJgxdOjQtLS0Xbt26W4AQBAIQgCApxGEAABPIwgBAJ5GEAIAPI0gBAB4GkEIAPA0ghAA4GkEIQDA0whCAICnEYQAAE8jCAEAnkYQAgA8zc0gzMnJee2112bNmvXuu+/qvqARhACAcLgZhE899ZTP0r17d90XNIIQABAO14Jw1apVFStWTEhIIAgBAC5yJwhzcnKSkpLq1q3bvn17ghAA4CJ3gnDYsGFlypRZuHBh586dCUIAgItcCMJ33323QoUKffr0MctFDsLRAdR6/U8EAKBgLgThoEGD4uLiWrZs2aZNm4suusgE4cUXX5ySkqLrgkMQAgDC4U4Q2ieLBrrqqqt0XXAIQgBAOFwIwkBFfmvUjyAEAITD5SCcOnVqSkrK9OnTdUfQCEIAQDhcDsLwEYQAgHAQhAAATyMIAQCeRhACADyNIAQAeBpBCADwNIIQAOBpBCEAwNMIQgCApxGEAABPIwgBAJ5GEAIAPI0gBAB4GkEIAPA0ghAA4GkEIQDA0whCAICnEYQAAE8jCAEAnkYQAgA8jSAEAHgaQQgA8DSCEADgaQQhAMDTCEIAgKe5E4RZWVmLFi2aZdm4caPuzrN+/frVAd5//31dQRACAMLjThBedtllvjzx8fEPPvigrrA0btzYX2YkJibqCoIQABAed4IwJSXlueeemzlzZocOHeyQW7NmjS7KC8KHHnooxTJ06FBdQRACAMLjThD6rVy50p4Url+/XvflBeH06dNP8Q4qQQgACIdrQfj444/fc88955xzTpUqVYYPH667LYFvjZYpU6Znz57+rtEBAh5BEAIAQuNaELZt2zYxMdHEmwm5u+++Ozs7W1fk5j7yyCMmI6dOndqtWzc7Dl999VVVQxACAMLhWhDaVq5cmZCQYBJu2rRpui8/+/yavn37qvUEIQAgHC4EYUZGxurVq+3ljRs3VqpUySTciy++mGtNAdu0abNgwQKznJmZOWXKFLtsw4YNVatWNWXON1EJQgBAOFwIQpNzcXFxderUufbaaytUqGDi7ZxzztmyZYvpql+/vvljWlparpWXZrl69eqNGjWyw7JmzZqbNm1SWyMIAQDhcCEITcL17t375ptvTkpKuummm/r06WMmfHZX4IwwKysrNTW1Xbt2pqxx48a9evU66ZmlBCEAIBwuBGHxIggBAOEgCAEAnkYQAgA8jSAEAHgaQQgA8DSCEADgaQQhAMDTCEIAgKcRhACC8LZIE5GqIg1FJomc0P1A7CIIARQmTcSXv/XQJUDsIggBnNI3IuUdQWjaZl0IxCiCEPCkf4jMFhkjsqaw9zmXOyLQbqm6EIhRBCHgPW+IVA6ItGSRA7rk35Y5ItBuz+pCIEYRhIDH5IqUc6RaJ131b1+LJDjqTduoC4EYRRACHjPQEWmmxYn8oAv/7UVH/QO6BIhdBCHgMfc4Us1uu3RhPotEGolUEKkv8pLIcd0PxC6CEPCYxx0RaFq8yE+6EPAIghDwmI9FKjqCkO8FwiUHDx58/vnn27dv36ZNm5EjR3711Ve6ouQRhEDY/m595fwRkVdFftad0Wi5yNkBKXivyI+6pHAfiDwlMlTkPd0DBOn7779v165dcoCWLVt++eWXuq6EEYRAeObln2BdKPI3XRKNDoq8biXZDt1TuOPWyTKBE0oTpUd0FVCol156KTAFbU8++aSuK2EEIRCGv5/sbcaGIsd0YXT5SOSGvNFWsE4KDenkl5cd/2TTntFVQKG6du2qYzA5uVWrVidOnPoqD8WMIATCMNaRB3bL0YVR5HuRWo4Bj9VVp3Kd4+GmXaKrgEKdNAjvvvtugjA0BCHclOLIA7u9owujSKpjtD5rXnhYFxaohuPhPutL9xE9dqE0GDdunI7B2Hpr9IknnsjIyNBrI44ghJumOvLAbp/rwijS1jFau+3RhQW63fFY067RVUChvv/++/bt2wemYKtWrf75z3/quhJW9CBMSko6++yz09LSdEdkEYRw0w8i5zkioaOuii59HAO2W/AHnzXWlWjUwxfrKiAY//rXv1544YWOHTu2bdt21KhRX3/9ta4oeUUPwubNm/ssZmHjxo26+5RSU1PNv9lE6Y033tizZ8+1a9fqiqARhGH5SORJkT+JjBTZrzsRlGyRegF50MH6EK64HBL5i0gXkUdF/qo7Q/CrdTfd+0X6FfDW6HX6EYWYIVIl77EVRCbofiCGFD0I9+zZM2DAgISEBJOFVatW7dWrV0oeXepw8cUXV6tW7YILLihbtqx5+DnnnLNr1y5dFByCsOgW5r/PXBW+EFZUh0V2iyyxvqtejL4VuTJ/XHXXJUH50jqTJXA7DfL/sWaRvvJh8n6tyLvWNzGAWFb0ILStXLny7LPPtqeGfrrIYfXq1fbC/Pnz7Ye88847+UuCRRAWkTk4np7/aGjaOcU6m0GYOjqeIJ91B6VQtXJsxGe9E/CwSGuRp0kyeF1YQbhs2bIGDRrYSVavXr2kPLruZDZs2GDicOjQoeaxtWvXZkYYaa85jox2W6EL4Y4jBdwXvo0uLMQvImUcG/FZb5MCsBQ9CE2G2W9sVqtWbcKECbq7MLfeequdoFWrVn3jjTd0d2FGB1Dr9T8RJ/Wc48hot2m6EO74xvHU2C3UD/M+c2zBbsm6EPCsogehmfmZGLv77rs3b96s+4IwY8aMkSNHNm3a1GykcuXK6enpuiI4BGERvec4MtotUxfCNYmOZ8dnvZ8ZkhMiZzo2YtoAXQh4VtGDsGXLlpMnT9ZrQ2dmhCYLx4wZozuCQxAW0XGRGx0Hx1a6Cm6a4XiCKol8qqsKN9Gxnaoi/9BVgGcVPQizs7P1quAsX768S5cuJkRnzZr16KOPxsXFmSCcM2eOrgsOQVh031jnSvgPjp05U6bELBHpJNJcZIhISN+SmhhwLdOLRDbp/qCcsK6glpC3ncuY9wP5FD0Ii+ytt96yPx20lSlTpkePHrooaARhuP5XZCPnDZaknvlnY2eFeCXS30V2iuzVq0P2m3WjieL9ggdQKrgQhMbmzZvNdPCll14y/y/aR4x+BCGi2nLH25I+6/YUKJX+R2SESDuRgaFcsg5ucycIixFBiCI6Zl0UZmUolxYrAjUd9LdI33k0CP+09kZ21N9DKmqtEzkj4CkuKzJdlyA6EYTwpCyRqwKOWb2s79uVhIKucB3Su6Ml7VfrZFT/2K60LpSDkPx6sqvOlhf5RBciChGE8J6DIuc6jll9dFXxeN7xF5lWWeSoLnST82ZSNUUO6CqcynrHPrQbV2GNBQQhvGec42jls26n8J0uLAY/ilzg+Lte1lVuOniyW0n4QrxVLxY4dqDdhupCRCGCEN7zoONoZbd1urB47Be5M++vOEtkiu532QbHfrBbF12IU/nYsQPttkgXIgoRhPCe4Y6jld3+rguL00/ReqOrzx37wW5P6EIU4gHHPrzGumYsoh5BCO/Jts7oU8es66wvnntTY8feOM06nwgh+UXkPwPeZ24RlecG42QIQnjS1PxZeJG3v2lupsJ1A/ZGWetuwCiaH0W2lMznzSgxBCG86r+se7Wbl/CviPysOz3nF2s/mL3xrEiu7gRKN4IQAOBpBCEAwNMIQsBtP4o8Yt0Uorp1JZp9uh9AiSIIAVf9KnJ5/jM2y3OFMyCiCELAVU/nT0G7NdZVAEoOQQi46hZHCppWpsQuAg7AgSAEXHWzIwVNi+cbHUDkEISAq55ypKBpjXQVgJJDEAIlI8jb2/6U/6ouppUTydRVAEoOQQgUt3SRJOtynWdad7oo9Gpb/7LuDFzbur/5ndalUAFEEEEIFKuVjtv7XcKZL0BUIwiBYlXH8YGfz7qoKYBoRRACxecfjgi0WwtdCCB6EIRA8fnOEYF2u1cXAogeBCFQrBo4UtC0yboKQPRwLQi3bt26cuXKVatW7dmzR/eFgiBEdMkUqZg/BW8K+qsUp/aDyPd6Xcn6JYhTXoHY50IQZmVlXX755b48Z5xxxvPPP6+LLI0bN/aXGYmJibqCIEQU+kSks3Up7UbWaTJHdH/IdlibsmP1apFNur/4fSxyW97prxeJvKP7gdLEhSDcuXNntWrVevXqlZqaakdd2bJl169fr+vygrBFixZtLN27d9cVBCFKvb3W/SgCp5iniezUVcXpG5Fqjnd3V+gqoNRwIQizs7MzMzPt5YyMDHu2N2/evPxVf7CDcNmyZatXrzbzSN1tIQhRyrV1ZJJpd+iq4tTP8df5rG9DAqWUC0EYaPLkyT7r3dHt27frvvxvjVauXHnYsGH+rtEBAh5BEKLUSXRkkmlVRE7owmJzveOv81lvkx7UhUDp4GYQvv7661WqVClbtuyUKVN0n6Vr1669e/d+9tlnW7RoYcfh3LlzVQ1BiFLuSkcmmVZLVxWnOx1/nc+6AuohXQiUDq4FYVpaWkJCQqVKlaZNm6b7TqZu3bomCB999FG1niBEKTfIkUmm9dZVxWmi46/zcU0AlGbuBOGwYcPi4+OrV6++ePHiwPWjRo1KSUlZtmyZWd6xY8eSJUvs9ZmZmabYBOHQoUMD63MJQpR6v4jUz59Jl1jX6S45x0Ruz/831hT5XFcBpYYLQbh9+3b/J39+L7/8sumqX7++WTaTxdy882guv/zyFi1a1KxZ02d9lJienq62RhCi9Dsk8pxIcyufRkXkEt7HrIsAtLa+BDlE5IDuB0oTF4Jw586dSQ6vv/666erUqZNZnj17tlnevXt3v379mjRpcsEFF9SpU6d169YrV67U2yIIAQDhcSEIixdBCAAIB0EIAPA0ghAA4GkEIQDA0whCAICnEYQAAE8jCAEAnkYQAgA8jSAEAHgaQQgA8DSCEADgaQQhAMDTCEIAgKcRhAAATyMIAQCeRhACADyNIAQAeBpBCADwNIIQAOBpBCEAwNMIQgCApxGE0e6E+Q8AUGIIwuiVLunXyXVlpexZctZD8tBBOagrAABhIwij1ApZESdxPvH522Vy2W/ym64DAITHzSBcu3bt+++/r9eGqLQG4flyfmAK2u0FeUHXAQDC40IQZmVlXXPNNeXKlfNZqlevPmHCBF0UtFIZhF/IF84UNK2VtNKlAIDwuBCEO3fuPP300zt16jRs2LCGDRuaLExISMjIyNB1wSmVQfiNfONMQdPaSTtdCgAIjwtBmJ2dvXnzZnt5/fr19rxw3rx5+auCVSqD0Kgn9ZxBOEWm6DoAQHhcCMJA06ZNMylYuXLlrVu36r7glNYg3CbbKkiFwBS8WW4+Jsd0HQAgPG4G4cKFC88888z4+Pjx48frvsKMDqDW639izPpIPuoknS6VSxtJo1RJPSJHdAUAIGyuBeErr7xSsWLFhISEcM6UyS29M0IAQGS4E4TPPvtsmTJlqlatOnfuXN0XIoIQABAOF4Jwx44d9gkyVapUScwzffp0XRccghAAIubw4cPLly8fM2bM5MmTd+7cqbtjkwtBaPZdksPrr7+u64JDEAJAZBw4cKBbt27JASZOnKiLYpALQVi8CEIAiIwRI0YEpqBtw4YNui7WEIQAgMIdPny4adOmOgaTk5955hldGmsIQgBA4b799ludgZZ+/frp0lhDEAIAgnLPPffoGExOnjRpkq6LNQQhACAoS5cuVSnYsmXLr7/+WtfFGoIQABCUEydOzJ8/v1mzZnYK3n///R9++KEuikEEIQAgBL///vvevXv379+vO2IWQQgA8DSCEADgaQQhAMDTCEIAgKcRhAAATyMIAQCeRhACADyNIAQAeBpBCADwNIIQAOBpBCEAwNMIQgCApxGEAABPIwgBAJ5GEAIAPI0gBAB4GkEIAPA0ghAA4GkEIQDA09wJwtTU1KSkpETLgAEDdHeeVq1a2TW2hg0b6gqCEEDM+uyzzwYOHHjnnXeaY92IESO+/fZbXYGIcCcI27VrV69evTp16vh8vp49e+ruPI0bNzYFJv+SLC1atNAVBCGA2PTpp582a9YsOUCbNm0OHjyo61Dy3AlCW8eOHYMJwo0bN2ZmZuq+PAQhgFg0YMCAwBS0jRs3Tteh5MVAEMbHx5v/165d2/yI+LtGBwh4RAkG4e/y+xvyxkAZOEEmfCqf6m4ACNqxY8fuvPNOHYPJyd26ddOlKHlRHYStW7du165dSkrK9ddfbyfikiVLVE1kgvAz+ewKucInPrtVlIpzZI4uAoDgnDhxomXLljoGk5PN8VCXouRFdRD6ZWdnn3/++aa4f//+qisCQXhCTtwoN/pT0G7lpfxe2atLASA4Tz75pI7B5OQpU6boOpS86ArCUaNGmfnfsmXLzPKuXbs++OADe31WVlZiYqIpHjRokL/YFoEg/Lv8XaWg3UbJKF0KAMH56quvWrduHZiCXbp0+fXXX3UdSp47QThkyJCkpKTq1aubbDv33HPN8siRI836+vXrmzVpaWlmOSMjo2zZsrfcckunTp2uvPJKs758+fLvvfee2lQEgvB9ed+ZgqZ1k266FACCduDAgbFjx3br1q1Hjx5mLkgKusWdIOzdu3fgFwQT875NeMcdd5jlqVOn5lozws6dO9etW7dSpUoVK1a84YYb3nzzTb2hiAThV/KVMwVNe0le0qUAgFjjThAWowgEofGAPKBSsIbU+F/5X10HAIg1BGFQfpQfO0pHfwrWlbqZkqmLAAAxiCAMwUfy0UJZuFW2/i6/6z4AQGwiCAEAnkYQAgA8jSAEAHgaQQgA8DSCEADgaQRhpO2X/QNlYDNp1kt6pUu67g7CJtnUR/rcIXf0l/4fy8e6GwAQCoIwotbJuipSxf99xDiJS5VUXXRKE2VivMT7t1BBKqyUlboI+e2VvQtkgXkB8Zv8pvsAeB5BGDmH5NB5cp66Qk0ZKbNbduvSAuyTfeWknNpCDanxo/yoS2FRV0K4UC7cIlt0EQBvIwgjZ5tsUxlmt9ES7JgnyATnw01bK2t1KSwPyoNqX1WTat/IN7oOgIcRhJHzV/mrM8NM6yf9dGkBnpKnnA83bb7M16UQ+Va+de4r08bIGF0KwMMIwsj5Sr4K/HjP396QN3RpAZbLcufD4yTuE/lEl0IkXdKdu8u0B+QBXQrAwwjCiBogA9RBuaE0PCJHdF0BjsvxG+VGtYVe0kvXwbJf9jtT0LSn5WldCsDDCMKIMpk3QkZUkAr2Ebm9tP9avtZFp3RADtwv99szywRJGCyDuQL4Kdwqt6oUNDvtb/I3XQfAwwhCFxyTY/tk38/ys+4I2q/yq9lC8FNJzzKTwnpSz5+CFaXiHJmjiwB4G0FY+v1g/vOww3J4vswfIkMmysTP5XPdDcDzCMJS67gcHy/jEyXRzITOkrNMEvAmKgA4EYSl1kAZqD4eay2tdREAeB5BWDp9Lp+f9Ksa78v7uhQAvI0gLJ0WyAJnCvpCuYoNAHgEQVg6rZAVzhQ0bbyM16UA4G0EYen0nXwXeJsLu5WRMtmSrUsBwNsIwlLrNXlNfUw4XIbrIgDwPHeC8MUXX0xOTq5Vq1ZiYuKAAQN0dyiKNwh3yI6JMnGWzPpMPtN9YftJflomy8bK2BWy4pAc0t0lYLNsbiftLpfL75F7lspS3Q0AcCsI77777ksuucQEoc/n69mzp+4ORXEF4WE53FW6+idP5aRcmqTpojCYiK0jdfzbv0Ku2Ct7dREAIOLcCcKcnBzz/44dO0ZPEA6X4eoTtTiJWyNrdF2R/Cg/XiAXqO1fLVeb9NWlAIDIcicIbVEVhNWlugoq09pJO11XJAtloXPjpqVLui4FAERWrAbh6ABqvf4nBuGgHHSmlGn1pJ4uLZLRMtq5cdNekVd0acF+kB9SJKWG1Cgn5a6T6/hqPAAUi1gNQr9iCUIpYEbYXtrruiJZJIucGzdtnazTpQU4LIcbSIPAx8ZJHOe/AED4CML/N1JGqpQySfOBfKDriuRn+flCuVBt3wRb8J8RTpSJ6uGmnSvnnpATuhQAEAp3gnDIkCFJSUnVq1c3QXjuueea5ZEjR+qi4BRXEB6RIw/JQ/6MKS/lJ8kkXRSG3bK7rtT1b/9qufoj+UgXFayDdHAGoWkfy8e6FAAQCneCsHfv3on5FfnbhMUVhLYcyfmL/GWuzP1v+W/dF7bf5LcVsmKCTHhP3gt+LmjrLJ2dKWjaftmvSwEAoXAnCItR8QZh1JopM50paKaYug4AECKCMDYcl+O3yW2BKVhOyq2X9boOABAigjBmHJEjz8lz18q1F8qF7aV9juToCgBA6AhCAICnEYQAAE8jCAF4wvHjx9esWZOWljZp0qQtW7bobngYQQig9Pvtt9/69u2bHGDUqFEnTnA9CvyBIPx/R+XoAlnwmDw2RsbskT26G0AsM7PAwBS0vf3227oOnkQQ/uFb+TZJkvzfTDhNTntBXtBFRfKZfPapfKrXAoistm3b6hhMTu7Xr5+ugycRhH9wXsAsTuLC/Jbeall9vpxvb6221F4pK3UFgIg4cuTI7bffrmMwOblz5866FJ5EEMov8ksZKaOC0LSe0lOXBm2H7DDTysCtmb9is2zWdQAi4qGHHtIxmJw8YsQIXQdPIghln+xzpqBpTaWpLg3anXKnc4PJkqzrAETE+vXrVQo2bdr044+5Zj3+QBD+cZpMBangzK3+0l+XBq2aVHNusIpU0XUAImXFihV33XWXnYLt2rXjGxTwIwj/8JQ8pUKrklQK5ySXK+VKZxByjWzAXYcOHdq3b98nn3xy9OhR3QcPIwj/cFgOPyqPxkmcnVi1pNYaWaOLQvGEPOEMwoEyUNcBANxGEP7bF/LF2/L2Jtn0i/yi+0L0u/x+g9wQmIJJkhT+ZgEAxY4gLCnH5Ng0mdZBOrSX9lNkylHhrRgAiEYEIQDA0whCAICnEYQAAE8jCAEAnkYQAgA8jSAEAHgaQQgA8DSCEADgaQQhAMDTSlsQjh8/fjQAAEEbN25cYI4oMRCEAACUHIIQAOBpBCEAwNMIQgCAp8VeEOrPQAEAKIzOkgCxF4RR6NS7OBpE/whzY2GQjLBYRP8go3+EubEwyOgfoR9BWAyi//mO/hHmxsIgGWGxiP5BRv8Ic2NhkNE/Qj+CsBhE//Md/SPMjYVBMsJiEf2DjP4R5sbCIKN/hH4EIQDA0whCAICnEYQAAE8jCMOSkZExadKkfv36paSkTJ48WXdH3OLFi81g2lhefPFF3Z1nyJAhdo2ta9euuiKCsrKyzD7s3bu3GUmHDh2ef/757OxsXRRBa9asefjhh5s0aXLFFVdcf/31jz322O7du3VRbq4ZZOA+NJ577jldFEEbNmzo2LFjUlLSpZdeet111/Xt23fHjh26KIJWrlx577332uMxO9P8yJ30aV29erXajTNnztRFEZeTkzN48GDzSx0ln3KZ8XTv3t3snB49eug+y6uvvqp249q1a3VRBL311ltqPAsXLtRF0YQgDMv999/vy3Pffffp7ohr27atGUnFihXN/x988EHdnefmm2/2D9uoXr26roig5cuXmzGcdtppZ555pj2eli1b6qIIevnll80YLrvssv/4j/+Ii4szy+3atdNFubl79uwJ2IV/MDmkiyJo6dKl5nlv0KBB/fr17WGbHwZdFEFTp06tXLnyNddcY15P2PvH5Iouys1dtGhRvp3o8w0fPlwXRdyIESPswTRs2FD3uWHYsGH2eM4//3zdZ3niiSf+vQctS5Ys0UURZJ59NZ4JEyboomhCEIZl7ty5b7zxRpcuXXzREYTvvffe1q1b7fEUGoTp6em6ww1mBmZ+jTMzM83yoEGDzMDMcXzz5s26LlKWLVv29ttv28uPPPKIGc8ZZ5yRv+QPdhBeddVVusMlu3bt2rlzp73cq1cvMzaTQPlLIsrMR80uspdbt25txnPbbbflL/mDHYTuZrZiJqmVKlU677zzfNERhGZuXaFCBfMSx1dYED7zzDO6wyV2EJqfQ90RrQjCYmAfd6IhCG1BBuG1116blJRkpjvmN01XuMS8sPBZs8Pt27frPjc89dRTZjx169bVHXlBaDLS7MPrrrvuz3/+s53lLsrJyTEH8ddff908s2Zsffv21RWRlZWVZcYzc+ZMswPNeJ599lldkReENWvWNLvxxhtvNNPBk76DGjFmH15//fUXXXTRqFGjoiEIzd4ws+pLL730L3/5S6FBePHFF5vdePvtt5sc0hWRZQeheTFhxnPLLbe4+6lBMAjCYhCLQWgfek4//XT7aP7+++/roogzcxqTKGY8f/rTn3SfG5YvX161atX4+PiXX35Z91lBaLrMEcq8VC9TpowZduPGjXVRZG3bts2XxxzBt2zZoisiy8yt/eMx00H/hDWQCcKEhAQzsfa/g3qKn9sIMC99zLM5f/78F154wd6NuiKyHn/88bJlyy5evPjVV1/1nTIIK1eubEZrT2Tj4uLS0tJ0UQSZIDSz2Kuvvtpks/20Dhw4UBdFE4KwGMRcEK5bt85e2LRpU7Vq1UzxoEGD8pdEmjlqN2rUyIykefPm/rfUXGTmVSYFzTGxoBezZuqwfv16e/mVV16xf9vdnVub2cOsWbPMVKZevXpmMOZVha6IrB07dpjpoJnk1alTx4yndevWuiI3d7vFXh4wYIApMwdQtyaFH3zwQcWKFe039KIhCDMyMsyrhI4dO5qJ9fPPP2/Gk5iYaJad+8dU2r815sfSzAh9br8s27p1q/91jzkQmfHUqlUrf0l0IQiLQfQHoXlFaQ6RGzZsyLV+VQx/l33Q7NOnj39N5Jn5qP3K0Yzc+UseeebVtDkAVapUadq0af6V5kAzy2KPMHCc6enpdhAuWLDAv9JF9uzBTFijYWfmWlcYMeOpUaNGrnWINPvwzTfftLsCR2i/njCzmZOephsB5tWP/Twqbr0yM6+r9FAsJrDXrFljduM777xjVwbuRvO7bGrM77V/TeQFjic1NdVXwAft0YMgDMuiRYvM03zrrbeaZzopKcksz507VxdFkDmUpKSkXH311WY8DRo0MMv2odz+0Gjs2LG51pHokksuMVPAyZMnd+/e3f7VcvGc9Y0bN5pDpD3g1DwuniwzZ84cEyH2ocR/8ndWVpaZs9r7yp7BmBnDbbfdZg7xEyZMuP766836M88886Tv/kXG4MGDe/fuPW7cuDFjxpz6xIrIMK8OH330UfOSwuwi+zNCe4b62muvmeXatWvbZQ8//PC9995rhm32p13m4iTMBI//Gbd/Zc4++2yz7NbriU2bNqXksU84qlq1qlnetm1b//79fQGTbPOj2KNHj0mTJg0dOtREjukyv9r5NxZRZhbbqVMn+9k3s1gznqZNm+qiaEIQhsWeCwZyd15ozwUD2fPCwCA0B+uLLrrIX1C+fPkBAwboDUXQ0qVL/z3cPC6e/G1+e/VofD6z01QQzpgx46yzzvIXmN92k6B6WxFkn+DqZ57i+fPn66II6tChQ+B4zKsK+31jFYQjRoywv+1ju+qqq9599918G3JJNLw1Gkh9RqiCsH379qeddpq9D82Uunnz5u6eumV+GhMSEvxPq5kk+D9HiE4EYVhWrVplv13m99e//lUXRZB5Cbk6P3tqtW7dOrMc+LuxYcOGN998c968ee7+whhmAGofGi6OaseOHWofGjk5OWZa4F/2F5s/mtG+9dZbgSvdYp7rBQsWmPG89957us8NGRkZ5mfMjCfwizq7du0yO+2DDz7wr9m9e7f5rTFl7n7CqpgDtxnS4sWLdYdLzEuxwP22detW80ezh/0FZppoXlOaMW/cuNG/0kVmwMuXLzfjWbNmje6LPgQhAMDTCEIAgKcRhAAATyMIAQCeRhACADyNIAQAeBpBCADwNIIQAOBpBCEAwNMIQiCG7d69u1mzZklJSf7b7ixevNj8sXHjxv57jAA4NYIQiG3jxo3zWZdjTk9PN7l46aWX+ty+nQgQWwhCIObdddddJvxuueUW+yrwl19+eVZWli4CUACCEIh5mzZtql69un2l/3Llyi1dulRXACgYQQiUBkOHDrWDsE2bNroPwCkRhEDM27ZtW61atewgLF++fFTdzwiIfgQhEPPsu+A2atSoU6dOZqFBgwZu3VQdiEUEIRDbpk2bFhcXV6lSpVWrVu3YseP88883WfjYY4/pOgAFIAiBGLZly5YaNWqY5Hv66aftNXPnzo2Pjy9Xrtzbb7+dvxbAyRGEAABPIwgBAJ5GEAIAPI0gBAB4GkEIAPA0ghAA4GkEIQDA0whCAICnEYQAAE8jCAEAnvZ/fDoiu99dl3UAAAAASUVORK5C", "text/plain": [ - "BufferedImage@51650547: type = 1 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0 IntegerInterleavedRaster: width = 600 height = 400 #Bands = 3 xOff = 0 yOff = 0 dataOffset[0] 0" + "BufferedImage@57a77532: type = 1 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0 IntegerInterleavedRaster: width = 600 height = 400 #Bands = 3 xOff = 0 yOff = 0 dataOffset[0] 0" ] }, "execution_count": 19, @@ -511,7 +511,7 @@ "outputs": [], "source": [ "var trainer = new HdbscanTrainer(5, // The minimum cluster size\n", - " DistanceType.L2, // The distance function \n", + " DistanceType.L2.getDistance(), // The distance function \n", " 5, // The number of neighbors to use to calculate the core-distance\n", " 4, // The number of compute threads\n", " NeighboursQueryFactoryType.BRUTE_FORCE // The nearest neighbour query algorithm\n", @@ -541,7 +541,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "11.0.12+8-LTS-237" + "version": "12+33" } }, "nbformat": 4, diff --git a/tutorials/clustering-tribuo-v4.ipynb b/tutorials/clustering-tribuo-v4.ipynb index c258ece5a..b72073e42 100644 --- a/tutorials/clustering-tribuo-v4.ipynb +++ b/tutorials/clustering-tribuo-v4.ipynb @@ -19,7 +19,7 @@ "metadata": {}, "outputs": [], "source": [ - "%jars ./tribuo-clustering-kmeans-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars ./tribuo-clustering-kmeans-4.3.0-jar-with-dependencies.jar" ] }, { @@ -98,14 +98,15 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training with 5 clusters took (00:00:00:147)\n" + "Training with 5 clusters took (00:00:00:071)\n" ] } ], "source": [ + "var l2Dist = DistanceType.L2.getDistance();\n", "var trainer = new KMeansTrainer(5, /* centroids */\n", " 10, /* iterations */\n", - " DistanceType.L2, /* distance function */\n", + " l2Dist, /* distance function */\n", " 1, /* number of compute threads */\n", " 1 /* RNG seed */\n", " );\n", @@ -180,12 +181,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training with 5 clusters took (00:00:00:071)\n" + "Training with 5 clusters took (00:00:00:038)\n" ] } ], "source": [ - "var plusplusTrainer = new KMeansTrainer(5,10,DistanceType.L2,Initialisation.PLUSPLUS,1,1);\n", + "var plusplusTrainer = new KMeansTrainer(5,10,l2Dist,Initialisation.PLUSPLUS,1,1);\n", "var startTime = System.currentTimeMillis();\n", "var plusplusModel = plusplusTrainer.train(data);\n", "var endTime = System.currentTimeMillis();\n", @@ -253,7 +254,7 @@ "text/plain": [ "Clustering Evaluation\n", "Normalized MI = 0.8128096132028937\n", - "Adjusted MI = 0.8113314999600718" + "Adjusted MI = 0.8113314999600724" ] }, "execution_count": 9, @@ -283,7 +284,7 @@ "text/plain": [ "Clustering Evaluation\n", "Normalized MI = 0.8154291916732408\n", - "Adjusted MI = 0.8139169342020222" + "Adjusted MI = 0.8139169341974347" ] }, "execution_count": 10, @@ -315,7 +316,7 @@ "text/plain": [ "Clustering Evaluation\n", "Normalized MI = 0.7881995472105396\n", - "Adjusted MI = 0.7864797287891366" + "Adjusted MI = 0.7864797287891137" ] }, "execution_count": 11, @@ -352,13 +353,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training with 5 clusters on 4 threads took (00:00:00:119)\n" + "Training with 5 clusters on 4 threads took (00:00:00:053)\n" ] } ], "source": [ "var mtData = new MutableDataset<>(new GaussianClusterDataSource(2000, 1L));\n", - "var mtTrainer = new KMeansTrainer(5,10,DistanceType.L2,4,1);\n", + "var mtTrainer = new KMeansTrainer(5,10,l2Dist,4,1);\n", "var mtStartTime = System.currentTimeMillis();\n", "var mtModel = mtTrainer.train(mtData);\n", "var mtEndTime = System.currentTimeMillis();\n", @@ -381,12 +382,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training with 20 clusters on 4 threads took (00:00:00:099)\n" + "Training with 20 clusters on 4 threads took (00:00:00:034)\n" ] } ], "source": [ - "var overTrainer = new KMeansTrainer(20,10,DistanceType.L2,4,1);\n", + "var overTrainer = new KMeansTrainer(20,10,l2Dist,4,1);\n", "var overStartTime = System.currentTimeMillis();\n", "var overModel = overTrainer.train(mtData);\n", "var overEndTime = System.currentTimeMillis();\n", @@ -410,7 +411,7 @@ "text/plain": [ "Clustering Evaluation\n", "Normalized MI = 0.8104463467727057\n", - "Adjusted MI = 0.8088941747451207" + "Adjusted MI = 0.8088941747417295" ] }, "execution_count": 14, @@ -440,7 +441,7 @@ "text/plain": [ "Clustering Evaluation\n", "Normalized MI = 0.8647317143685641\n", - "Adjusted MI = 0.860327445295668" + "Adjusted MI = 0.8603214693630152" ] }, "execution_count": 15, @@ -483,7 +484,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "11.0.12+8-LTS-237" + "version": "12+33" } }, "nbformat": 4, diff --git a/tutorials/columnar-tribuo-v4.ipynb b/tutorials/columnar-tribuo-v4.ipynb index 7b43c2ed5..82928d686 100644 --- a/tutorials/columnar-tribuo-v4.ipynb +++ b/tutorials/columnar-tribuo-v4.ipynb @@ -38,8 +38,8 @@ "metadata": {}, "outputs": [], "source": [ - "%jars ./tribuo-classification-experiments-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-json-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars ./tribuo-classification-experiments-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-json-4.3.0-jar-with-dependencies.jar" ] }, { @@ -123,7 +123,18 @@ "cell_type": "code", "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "true" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "var textPipeline = new BasicPipeline(new BreakIteratorTokenizer(Locale.US),2);\n", "var fieldProcessors = new ArrayList();\n", @@ -573,7 +584,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "17+35-LTS-2724" + "version": "12+33" } }, "nbformat": 4, diff --git a/tutorials/configuration-tribuo-v4.ipynb b/tutorials/configuration-tribuo-v4.ipynb index 6d06a20a6..0d875d1f8 100644 --- a/tutorials/configuration-tribuo-v4.ipynb +++ b/tutorials/configuration-tribuo-v4.ipynb @@ -32,8 +32,8 @@ "metadata": {}, "outputs": [], "source": [ - "%jars ./tribuo-classification-experiments-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-json-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars ./tribuo-classification-experiments-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-json-4.3.0-jar-with-dependencies.jar" ] }, { @@ -487,7 +487,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training logistic regression took (00:00:03:494)\n" + "Training logistic regression took (00:00:04:874)\n" ] } ], @@ -554,9 +554,9 @@ " \"export\" : \"false\",\n", " \"import\" : \"false\",\n", " \"properties\" : {\n", - " \"outputPath\" : \"/Users/apocock/Development/Tribuo/tutorials/train-labels-idx1-ubyte.gz\",\n", + " \"outputPath\" : \"/local/ExternalRepositories/tribuo/tutorials/train-labels-idx1-ubyte.gz\",\n", " \"outputFactory\" : \"labelfactory-4\",\n", - " \"featuresPath\" : \"/Users/apocock/Development/Tribuo/tutorials/train-images-idx3-ubyte.gz\"\n", + " \"featuresPath\" : \"/local/ExternalRepositories/tribuo/tutorials/train-images-idx3-ubyte.gz\"\n", " }\n", " }, {\n", " \"name\" : \"linearsgdtrainer-0\",\n", @@ -800,14 +800,14 @@ "\t\t\t\t\tclass-name = org.tribuo.MutableDataset\n", "\t\t\t\t\tdatasource = IDXDataSource(\n", "\t\t\t\t\t\t\tclass-name = org.tribuo.datasource.IDXDataSource\n", - "\t\t\t\t\t\t\toutputPath = /Users/apocock/Development/Tribuo/tutorials/train-labels-idx1-ubyte.gz\n", + "\t\t\t\t\t\t\toutputPath = /local/ExternalRepositories/tribuo/tutorials/train-labels-idx1-ubyte.gz\n", "\t\t\t\t\t\t\toutputFactory = LabelFactory(\n", "\t\t\t\t\t\t\t\t\tclass-name = org.tribuo.classification.LabelFactory\n", "\t\t\t\t\t\t\t\t)\n", - "\t\t\t\t\t\t\tfeaturesPath = /Users/apocock/Development/Tribuo/tutorials/train-images-idx3-ubyte.gz\n", + "\t\t\t\t\t\t\tfeaturesPath = /local/ExternalRepositories/tribuo/tutorials/train-images-idx3-ubyte.gz\n", "\t\t\t\t\t\t\tfeatures-file-modified-time = 2000-07-21T14:20:24-04:00\n", "\t\t\t\t\t\t\toutput-resource-hash = 3552534A0A558BBED6AED32B30C495CCA23D567EC52CAC8BE1A0730E8010255C\n", - "\t\t\t\t\t\t\tdatasource-creation-time = 2021-12-18T20:07:51.388837-05:00\n", + "\t\t\t\t\t\t\tdatasource-creation-time = 2022-10-07T11:33:57.506314-04:00\n", "\t\t\t\t\t\t\toutput-file-modified-time = 2000-07-21T14:20:27-04:00\n", "\t\t\t\t\t\t\tidx-feature-type = UBYTE\n", "\t\t\t\t\t\t\tfeatures-resource-hash = 440FCABF73CC546FA21475E81EA370265605F56BE210A4024D2CA8F203523609\n", @@ -819,7 +819,7 @@ "\t\t\t\t\tnum-examples = 60000\n", "\t\t\t\t\tnum-features = 717\n", "\t\t\t\t\tnum-outputs = 10\n", - "\t\t\t\t\ttribuo-version = 4.2.0\n", + "\t\t\t\t\ttribuo-version = 4.3.0\n", "\t\t\t\t)\n", "\t\t\ttrainer = LinearSGDTrainer(\n", "\t\t\t\t\tclass-name = org.tribuo.classification.sgd.linear.LinearSGDTrainer\n", @@ -839,32 +839,32 @@ "\t\t\t\t\t\t\tclass-name = org.tribuo.classification.sgd.objectives.LogMulticlass\n", "\t\t\t\t\t\t\thost-short-name = LabelObjective\n", "\t\t\t\t\t\t)\n", - "\t\t\t\t\ttribuo-version = 4.2.0\n", + "\t\t\t\t\ttribuo-version = 4.3.0\n", "\t\t\t\t\ttrain-invocation-count = 0\n", "\t\t\t\t\tis-sequence = false\n", "\t\t\t\t\thost-short-name = Trainer\n", "\t\t\t\t)\n", - "\t\t\ttrained-at = 2021-12-18T20:07:55.508414-05:00\n", + "\t\t\ttrained-at = 2022-10-07T11:34:03.181752-04:00\n", "\t\t\tinstance-values = Map{\n", "\t\t\t\treconfigured-model=true\n", "\t\t\t}\n", - "\t\t\ttribuo-version = 4.2.0\n", - "\t\t\tjava-version = 17.0.1\n", - "\t\t\tos-name = Mac OS X\n", - "\t\t\tos-arch = x86_64\n", + "\t\t\ttribuo-version = 4.3.0\n", + "\t\t\tjava-version = 12\n", + "\t\t\tos-name = Linux\n", + "\t\t\tos-arch = amd64\n", "\t\t)\n", "\tdataset-provenance = MutableDataset(\n", "\t\t\tclass-name = org.tribuo.MutableDataset\n", "\t\t\tdatasource = IDXDataSource(\n", "\t\t\t\t\tclass-name = org.tribuo.datasource.IDXDataSource\n", - "\t\t\t\t\toutputPath = /Users/apocock/Development/Tribuo/tutorials/t10k-labels-idx1-ubyte.gz\n", + "\t\t\t\t\toutputPath = /local/ExternalRepositories/tribuo/tutorials/t10k-labels-idx1-ubyte.gz\n", "\t\t\t\t\toutputFactory = LabelFactory(\n", "\t\t\t\t\t\t\tclass-name = org.tribuo.classification.LabelFactory\n", "\t\t\t\t\t\t)\n", - "\t\t\t\t\tfeaturesPath = /Users/apocock/Development/Tribuo/tutorials/t10k-images-idx3-ubyte.gz\n", + "\t\t\t\t\tfeaturesPath = /local/ExternalRepositories/tribuo/tutorials/t10k-images-idx3-ubyte.gz\n", "\t\t\t\t\tfeatures-file-modified-time = 2000-07-21T14:19:56-04:00\n", "\t\t\t\t\toutput-resource-hash = F7AE60F92E00EC6DEBD23A6088C31DBD2371ECA3FFA0DEFAEFB259924204AEC6\n", - "\t\t\t\t\tdatasource-creation-time = 2021-12-18T20:07:41.373899-05:00\n", + "\t\t\t\t\tdatasource-creation-time = 2022-10-07T11:33:44.880399-04:00\n", "\t\t\t\t\toutput-file-modified-time = 2000-07-21T14:20:05-04:00\n", "\t\t\t\t\tidx-feature-type = UBYTE\n", "\t\t\t\t\tfeatures-resource-hash = 8D422C7B0A1C1C79245A5BCF07FE86E33EEAFEE792B84584AEC276F5A2DBC4E6\n", @@ -876,9 +876,9 @@ "\t\t\tnum-examples = 10000\n", "\t\t\tnum-features = 668\n", "\t\t\tnum-outputs = 10\n", - "\t\t\ttribuo-version = 4.2.0\n", + "\t\t\ttribuo-version = 4.3.0\n", "\t\t)\n", - "\ttribuo-version = 4.2.0\n", + "\ttribuo-version = 4.3.0\n", ")\n" ] } @@ -906,7 +906,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training transformed logistic regression took (00:00:04:707)\n" + "Training transformed logistic regression took (00:00:06:555)\n" ] } ], @@ -1049,9 +1049,9 @@ " \"export\" : \"false\",\n", " \"import\" : \"false\",\n", " \"properties\" : {\n", - " \"outputPath\" : \"/Users/apocock/Development/Tribuo/tutorials/train-labels-idx1-ubyte.gz\",\n", + " \"outputPath\" : \"/local/ExternalRepositories/tribuo/tutorials/train-labels-idx1-ubyte.gz\",\n", " \"outputFactory\" : \"labelfactory-7\",\n", - " \"featuresPath\" : \"/Users/apocock/Development/Tribuo/tutorials/train-images-idx3-ubyte.gz\"\n", + " \"featuresPath\" : \"/local/ExternalRepositories/tribuo/tutorials/train-images-idx3-ubyte.gz\"\n", " }\n", " }, {\n", " \"name\" : \"transformationmap-1\",\n", @@ -1113,7 +1113,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "17+35-LTS-2724" + "version": "12+33" } }, "nbformat": 4, diff --git a/tutorials/document-classification-tribuo-v4.ipynb b/tutorials/document-classification-tribuo-v4.ipynb index ab08e7411..4d93b5b77 100644 --- a/tutorials/document-classification-tribuo-v4.ipynb +++ b/tutorials/document-classification-tribuo-v4.ipynb @@ -49,8 +49,8 @@ "metadata": {}, "outputs": [], "source": [ - "%jars ./tribuo-classification-experiments-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-onnx-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars ./tribuo-classification-experiments-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-onnx-4.3.0-jar-with-dependencies.jar" ] }, { @@ -198,34 +198,34 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training the model on BoW features took (00:00:09:601)\n", + "Training the model on BoW features took (00:00:10:110)\n", "\n", "Class n tp fn fp recall prec f1\n", - "soc.religion.christian 398 352 46 110 0.884 0.762 0.819\n", - "rec.autos 396 344 52 63 0.869 0.845 0.857\n", - "talk.religion.misc 251 166 85 120 0.661 0.580 0.618\n", - "comp.windows.x 395 283 112 55 0.716 0.837 0.772\n", - "rec.sport.baseball 397 370 27 45 0.932 0.892 0.911\n", - "comp.graphics 389 293 96 143 0.753 0.672 0.710\n", - "talk.politics.mideast 376 283 93 11 0.753 0.963 0.845\n", - "comp.sys.ibm.pc.hardware 392 277 115 160 0.707 0.634 0.668\n", - "sci.med 396 323 73 43 0.816 0.883 0.848\n", - "comp.os.ms-windows.misc 394 272 122 87 0.690 0.758 0.722\n", - "sci.crypt 396 349 47 23 0.881 0.938 0.909\n", - "comp.sys.mac.hardware 385 283 102 96 0.735 0.747 0.741\n", - "misc.forsale 390 341 49 63 0.874 0.844 0.859\n", - "rec.motorcycles 398 364 34 23 0.915 0.941 0.927\n", - "talk.politics.misc 310 182 128 94 0.587 0.659 0.621\n", - "sci.electronics 393 272 121 135 0.692 0.668 0.680\n", - "rec.sport.hockey 399 367 32 24 0.920 0.939 0.929\n", - "sci.space 394 325 69 56 0.825 0.853 0.839\n", - "alt.atheism 319 243 76 75 0.762 0.764 0.763\n", - "talk.politics.guns 364 303 61 114 0.832 0.727 0.776\n", - "Total 7,532 5,992 1,540 1,540\n", - "Accuracy 0.796\n", - "Micro Average 0.796 0.796 0.796\n", - "Macro Average 0.790 0.795 0.791\n", - "Balanced Error Rate 0.210\n" + "soc.religion.christian 398 346 52 93 0.869 0.788 0.827\n", + "rec.autos 396 349 47 79 0.881 0.815 0.847\n", + "talk.religion.misc 251 154 97 109 0.614 0.586 0.599\n", + "comp.windows.x 395 293 102 66 0.742 0.816 0.777\n", + "rec.sport.baseball 397 368 29 45 0.927 0.891 0.909\n", + "talk.politics.mideast 376 286 90 22 0.761 0.929 0.836\n", + "comp.graphics 389 285 104 163 0.733 0.636 0.681\n", + "comp.sys.ibm.pc.hardware 392 291 101 165 0.742 0.638 0.686\n", + "sci.med 396 299 97 60 0.755 0.833 0.792\n", + "comp.os.ms-windows.misc 394 241 153 74 0.612 0.765 0.680\n", + "sci.crypt 396 346 50 45 0.874 0.885 0.879\n", + "comp.sys.mac.hardware 385 294 91 85 0.764 0.776 0.770\n", + "talk.politics.misc 310 170 140 96 0.548 0.639 0.590\n", + "rec.motorcycles 398 370 28 25 0.930 0.937 0.933\n", + "misc.forsale 390 344 46 67 0.882 0.837 0.859\n", + "sci.electronics 393 269 124 112 0.684 0.706 0.695\n", + "rec.sport.hockey 399 371 28 18 0.930 0.954 0.942\n", + "sci.space 394 324 70 44 0.822 0.880 0.850\n", + "alt.atheism 319 240 79 97 0.752 0.712 0.732\n", + "talk.politics.guns 364 308 56 119 0.846 0.721 0.779\n", + "Total 7,532 5,948 1,584 1,584\n", + "Accuracy 0.790\n", + "Micro Average 0.790 0.790 0.790\n", + "Macro Average 0.783 0.787 0.783\n", + "Balanced Error Rate 0.217\n" ] } ], @@ -244,7 +244,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We got a macro F1 score of 79.6%, which is a fairly good starting point and it's roughly what other linear models get on this task (e.g., scikit-learn's text classification tutorial gets 76.9% macro F1 when using a similar multinomial Naive Bayes model)." + "We got a macro F1 score of 79.0%, which is a fairly good starting point and it's roughly what other linear models get on this task (e.g., scikit-learn's text classification tutorial gets 76.9% macro F1 when using a similar multinomial Naive Bayes model)." ] }, { @@ -291,34 +291,34 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training the model on Unigram features took (00:00:09:146)\n", + "Training the model on Unigram features took (00:00:12:351)\n", "\n", "Class n tp fn fp recall prec f1\n", - "soc.religion.christian 398 362 36 88 0.910 0.804 0.854\n", - "rec.autos 396 353 43 58 0.891 0.859 0.875\n", - "talk.religion.misc 251 148 103 97 0.590 0.604 0.597\n", - "comp.windows.x 395 295 100 54 0.747 0.845 0.793\n", - "rec.sport.baseball 397 356 41 49 0.897 0.879 0.888\n", - "comp.graphics 389 280 109 120 0.720 0.700 0.710\n", - "talk.politics.mideast 376 310 66 29 0.824 0.914 0.867\n", - "comp.sys.ibm.pc.hardware 392 266 126 133 0.679 0.667 0.673\n", - "sci.med 396 310 86 42 0.783 0.881 0.829\n", - "comp.os.ms-windows.misc 394 241 153 82 0.612 0.746 0.672\n", - "sci.crypt 396 354 42 55 0.894 0.866 0.880\n", - "comp.sys.mac.hardware 385 312 73 103 0.810 0.752 0.780\n", - "misc.forsale 390 343 47 69 0.879 0.833 0.855\n", - "rec.motorcycles 398 362 36 27 0.910 0.931 0.920\n", - "talk.politics.misc 310 171 139 90 0.552 0.655 0.599\n", - "sci.electronics 393 289 104 110 0.735 0.724 0.730\n", - "rec.sport.hockey 399 374 25 23 0.937 0.942 0.940\n", - "sci.space 394 342 52 57 0.868 0.857 0.863\n", - "alt.atheism 319 240 79 84 0.752 0.741 0.747\n", - "talk.politics.guns 364 314 50 140 0.863 0.692 0.768\n", - "Total 7,532 6,022 1,510 1,510\n", - "Accuracy 0.800\n", - "Micro Average 0.800 0.800 0.800\n", - "Macro Average 0.793 0.795 0.792\n", - "Balanced Error Rate 0.207\n" + "soc.religion.christian 398 341 57 90 0.857 0.791 0.823\n", + "rec.autos 396 357 39 69 0.902 0.838 0.869\n", + "talk.religion.misc 251 155 96 122 0.618 0.560 0.587\n", + "comp.windows.x 395 291 104 59 0.737 0.831 0.781\n", + "rec.sport.baseball 397 361 36 43 0.909 0.894 0.901\n", + "talk.politics.mideast 376 274 102 27 0.729 0.910 0.809\n", + "comp.graphics 389 288 101 114 0.740 0.716 0.728\n", + "comp.sys.ibm.pc.hardware 392 279 113 141 0.712 0.664 0.687\n", + "sci.med 396 310 86 73 0.783 0.809 0.796\n", + "comp.os.ms-windows.misc 394 263 131 98 0.668 0.729 0.697\n", + "sci.crypt 396 344 52 54 0.869 0.864 0.866\n", + "comp.sys.mac.hardware 385 301 84 82 0.782 0.786 0.784\n", + "talk.politics.misc 310 168 142 121 0.542 0.581 0.561\n", + "rec.motorcycles 398 365 33 31 0.917 0.922 0.919\n", + "misc.forsale 390 321 69 70 0.823 0.821 0.822\n", + "sci.electronics 393 282 111 117 0.718 0.707 0.712\n", + "rec.sport.hockey 399 380 19 29 0.952 0.929 0.941\n", + "sci.space 394 323 71 35 0.820 0.902 0.859\n", + "alt.atheism 319 246 73 105 0.771 0.701 0.734\n", + "talk.politics.guns 364 300 64 103 0.824 0.744 0.782\n", + "Total 7,532 5,949 1,583 1,583\n", + "Accuracy 0.790\n", + "Micro Average 0.790 0.790 0.790\n", + "Macro Average 0.784 0.785 0.783\n", + "Balanced Error Rate 0.216\n" ] } ], @@ -336,7 +336,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We see that the logistic regression trained on unigrams gets about 80% accuracy, pretty much the same as the BoW baseline, and takes about the same amount of time to run. Both of these make sense, as the term count isn't necessarily that useful in this particular dataset, and we didn't change the number of features overall or inside each example by using term counting.\n", + "We see that the logistic regression trained on unigrams gets about 79% accuracy, pretty much the same as the BoW baseline, and takes about the same amount of time to run. Both of these make sense, as the term count isn't necessarily that useful in this particular dataset, and we didn't change the number of features overall or inside each example by using term counting.\n", "\n", "\n", "## N-grams as features\n", @@ -381,34 +381,34 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training the model on Bigram features took (00:00:43:790)\n", + "Training the model on Bigram features took (00:00:32:704)\n", "\n", "Class n tp fn fp recall prec f1\n", - "soc.religion.christian 398 331 67 57 0.832 0.853 0.842\n", - "rec.autos 396 326 70 55 0.823 0.856 0.839\n", - "talk.religion.misc 251 167 84 106 0.665 0.612 0.637\n", - "comp.windows.x 395 297 98 57 0.752 0.839 0.793\n", - "rec.sport.baseball 397 357 40 52 0.899 0.873 0.886\n", - "comp.graphics 389 304 85 196 0.781 0.608 0.684\n", - "talk.politics.mideast 376 300 76 48 0.798 0.862 0.829\n", - "comp.sys.ibm.pc.hardware 392 244 148 104 0.622 0.701 0.659\n", - "sci.med 396 298 98 66 0.753 0.819 0.784\n", - "comp.os.ms-windows.misc 394 260 134 99 0.660 0.724 0.691\n", - "sci.crypt 396 327 69 37 0.826 0.898 0.861\n", - "comp.sys.mac.hardware 385 320 65 162 0.831 0.664 0.738\n", - "misc.forsale 390 352 38 102 0.903 0.775 0.834\n", - "rec.motorcycles 398 359 39 39 0.902 0.902 0.902\n", - "talk.politics.misc 310 185 125 93 0.597 0.665 0.629\n", - "sci.electronics 393 253 140 90 0.644 0.738 0.688\n", - "rec.sport.hockey 399 370 29 30 0.927 0.925 0.926\n", - "sci.space 394 336 58 40 0.853 0.894 0.873\n", - "alt.atheism 319 225 94 65 0.705 0.776 0.739\n", - "talk.politics.guns 364 309 55 114 0.849 0.730 0.785\n", - "Total 7,532 5,920 1,612 1,612\n", - "Accuracy 0.786\n", - "Micro Average 0.786 0.786 0.786\n", - "Macro Average 0.781 0.786 0.781\n", - "Balanced Error Rate 0.219\n" + "soc.religion.christian 398 328 70 38 0.824 0.896 0.859\n", + "rec.autos 396 328 68 53 0.828 0.861 0.844\n", + "talk.religion.misc 251 165 86 93 0.657 0.640 0.648\n", + "comp.windows.x 395 296 99 72 0.749 0.804 0.776\n", + "rec.sport.baseball 397 357 40 51 0.899 0.875 0.887\n", + "talk.politics.mideast 376 292 84 38 0.777 0.885 0.827\n", + "comp.graphics 389 288 101 205 0.740 0.584 0.653\n", + "comp.sys.ibm.pc.hardware 392 281 111 168 0.717 0.626 0.668\n", + "sci.med 396 289 107 60 0.730 0.828 0.776\n", + "comp.os.ms-windows.misc 394 262 132 86 0.665 0.753 0.706\n", + "sci.crypt 396 343 53 65 0.866 0.841 0.853\n", + "comp.sys.mac.hardware 385 289 96 110 0.751 0.724 0.737\n", + "talk.politics.misc 310 176 134 63 0.568 0.736 0.641\n", + "rec.motorcycles 398 366 32 51 0.920 0.878 0.898\n", + "misc.forsale 390 341 49 71 0.874 0.828 0.850\n", + "sci.electronics 393 240 153 67 0.611 0.782 0.686\n", + "rec.sport.hockey 399 366 33 28 0.917 0.929 0.923\n", + "sci.space 394 334 60 51 0.848 0.868 0.858\n", + "alt.atheism 319 256 63 137 0.803 0.651 0.719\n", + "talk.politics.guns 364 300 64 128 0.824 0.701 0.758\n", + "Total 7,532 5,897 1,635 1,635\n", + "Accuracy 0.783\n", + "Micro Average 0.783 0.783 0.783\n", + "Macro Average 0.778 0.784 0.778\n", + "Balanced Error Rate 0.222\n" ] } ], @@ -426,7 +426,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Our performance decreased a little when using bigrams to 78%, and the runtime increased from 10s to 48s. This is because despite there being more information in the features, there are also many, many more features making it easier to confuse this simple linear model plus each example takes longer to process due to the greatly increased number of features. We could look at using a more complex model like boosted trees to exploit this additional information which may increase the performance back above our baseline. We could further increase number of n-gram features but we'll start to see diminishing returns even with more powerful models as the dimensionality of the feature space increases without a commensurate increase in training data.\n", + "Our performance decreased a little when using bigrams to 78%, and the runtime increased from 12s to 32s. This is because despite there being more information in the features, there are also many, many more features making it easier to confuse this simple linear model plus each example takes longer to process due to the greatly increased number of features. We could look at using a more complex model like boosted trees to exploit this additional information which may increase the performance back above our baseline. We could further increase number of n-gram features but we'll start to see diminishing returns even with more powerful models as the dimensionality of the feature space increases without a commensurate increase in training data.\n", "\n", "## TFIDF vectors\n", "\n", @@ -480,34 +480,34 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training the model on TF-IDF features took (00:00:45:063)\n", + "Training the model on TF-IDF features took (00:00:33:661)\n", "\n", "Class n tp fn fp recall prec f1\n", - "soc.religion.christian 398 350 48 183 0.879 0.657 0.752\n", - "rec.autos 396 332 64 68 0.838 0.830 0.834\n", - "talk.religion.misc 251 155 96 111 0.618 0.583 0.600\n", - "comp.windows.x 395 290 105 58 0.734 0.833 0.781\n", - "rec.sport.baseball 397 345 52 26 0.869 0.930 0.898\n", - "comp.graphics 389 264 125 111 0.679 0.704 0.691\n", - "talk.politics.mideast 376 306 70 32 0.814 0.905 0.857\n", - "comp.sys.ibm.pc.hardware 392 285 107 170 0.727 0.626 0.673\n", - "sci.med 396 305 91 63 0.770 0.829 0.798\n", - "comp.os.ms-windows.misc 394 248 146 71 0.629 0.777 0.696\n", - "sci.crypt 396 340 56 47 0.859 0.879 0.868\n", - "comp.sys.mac.hardware 385 283 102 69 0.735 0.804 0.768\n", - "misc.forsale 390 340 50 79 0.872 0.811 0.841\n", - "rec.motorcycles 398 359 39 36 0.902 0.909 0.905\n", - "talk.politics.misc 310 191 119 130 0.616 0.595 0.605\n", - "sci.electronics 393 292 101 112 0.743 0.723 0.733\n", - "rec.sport.hockey 399 376 23 32 0.942 0.922 0.932\n", - "sci.space 394 339 55 52 0.860 0.867 0.864\n", - "alt.atheism 319 226 93 57 0.708 0.799 0.751\n", - "talk.politics.guns 364 303 61 96 0.832 0.759 0.794\n", - "Total 7,532 5,929 1,603 1,603\n", - "Accuracy 0.787\n", - "Micro Average 0.787 0.787 0.787\n", - "Macro Average 0.781 0.787 0.782\n", - "Balanced Error Rate 0.219\n" + "soc.religion.christian 398 329 69 83 0.827 0.799 0.812\n", + "rec.autos 396 338 58 63 0.854 0.843 0.848\n", + "talk.religion.misc 251 171 80 83 0.681 0.673 0.677\n", + "comp.windows.x 395 317 78 86 0.803 0.787 0.794\n", + "rec.sport.baseball 397 356 41 31 0.897 0.920 0.908\n", + "talk.politics.mideast 376 310 66 28 0.824 0.917 0.868\n", + "comp.graphics 389 273 116 114 0.702 0.705 0.704\n", + "comp.sys.ibm.pc.hardware 392 268 124 128 0.684 0.677 0.680\n", + "sci.med 396 325 71 143 0.821 0.694 0.752\n", + "comp.os.ms-windows.misc 394 263 131 77 0.668 0.774 0.717\n", + "sci.crypt 396 338 58 60 0.854 0.849 0.851\n", + "comp.sys.mac.hardware 385 285 100 69 0.740 0.805 0.771\n", + "talk.politics.misc 310 181 129 55 0.584 0.767 0.663\n", + "rec.motorcycles 398 362 36 47 0.910 0.885 0.897\n", + "misc.forsale 390 331 59 64 0.849 0.838 0.843\n", + "sci.electronics 393 251 142 84 0.639 0.749 0.690\n", + "rec.sport.hockey 399 369 30 15 0.925 0.961 0.943\n", + "sci.space 394 350 44 113 0.888 0.756 0.817\n", + "alt.atheism 319 251 68 80 0.787 0.758 0.772\n", + "talk.politics.guns 364 315 49 126 0.865 0.714 0.783\n", + "Total 7,532 5,983 1,549 1,549\n", + "Accuracy 0.794\n", + "Micro Average 0.794 0.794 0.794\n", + "Macro Average 0.790 0.794 0.790\n", + "Balanced Error Rate 0.210\n" ] } ], @@ -570,34 +570,34 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training the model on hashed features took (00:00:23:354)\n", + "Training the model on hashed features took (00:00:18:148)\n", "\n", "Class n tp fn fp recall prec f1\n", - "soc.religion.christian 398 306 92 125 0.769 0.710 0.738\n", - "rec.autos 396 324 72 77 0.818 0.808 0.813\n", - "talk.religion.misc 251 139 112 132 0.554 0.513 0.533\n", - "comp.windows.x 395 273 122 78 0.691 0.778 0.732\n", - "rec.sport.baseball 397 335 62 64 0.844 0.840 0.842\n", - "comp.graphics 389 238 151 135 0.612 0.638 0.625\n", - "talk.politics.mideast 376 265 111 35 0.705 0.883 0.784\n", - "comp.sys.ibm.pc.hardware 392 276 116 178 0.704 0.608 0.652\n", - "sci.med 396 251 145 125 0.634 0.668 0.650\n", - "comp.os.ms-windows.misc 394 254 140 109 0.645 0.700 0.671\n", - "sci.crypt 396 305 91 36 0.770 0.894 0.828\n", - "comp.sys.mac.hardware 385 259 126 97 0.673 0.728 0.699\n", - "misc.forsale 390 325 65 87 0.833 0.789 0.810\n", - "rec.motorcycles 398 341 57 75 0.857 0.820 0.838\n", - "talk.politics.misc 310 171 139 195 0.552 0.467 0.506\n", - "sci.electronics 393 243 150 159 0.618 0.604 0.611\n", - "rec.sport.hockey 399 353 46 59 0.885 0.857 0.871\n", - "sci.space 394 305 89 49 0.774 0.862 0.816\n", - "alt.atheism 319 215 104 100 0.674 0.683 0.678\n", - "talk.politics.guns 364 292 72 147 0.802 0.665 0.727\n", - "Total 7,532 5,470 2,062 2,062\n", - "Accuracy 0.726\n", - "Micro Average 0.726 0.726 0.726\n", - "Macro Average 0.721 0.726 0.721\n", - "Balanced Error Rate 0.279\n" + "soc.religion.christian 398 293 105 77 0.736 0.792 0.763\n", + "rec.autos 396 304 92 75 0.768 0.802 0.785\n", + "talk.religion.misc 251 159 92 177 0.633 0.473 0.542\n", + "comp.windows.x 395 293 102 76 0.742 0.794 0.767\n", + "rec.sport.baseball 397 343 54 108 0.864 0.761 0.809\n", + "talk.politics.mideast 376 267 109 34 0.710 0.887 0.789\n", + "comp.graphics 389 254 135 121 0.653 0.677 0.665\n", + "comp.sys.ibm.pc.hardware 392 253 139 138 0.645 0.647 0.646\n", + "sci.med 396 281 115 109 0.710 0.721 0.715\n", + "comp.os.ms-windows.misc 394 240 154 98 0.609 0.710 0.656\n", + "sci.crypt 396 330 66 81 0.833 0.803 0.818\n", + "comp.sys.mac.hardware 385 271 114 117 0.704 0.698 0.701\n", + "talk.politics.misc 310 174 136 160 0.561 0.521 0.540\n", + "rec.motorcycles 398 336 62 41 0.844 0.891 0.867\n", + "misc.forsale 390 334 56 83 0.856 0.801 0.828\n", + "sci.electronics 393 245 148 132 0.623 0.650 0.636\n", + "rec.sport.hockey 399 343 56 32 0.860 0.915 0.886\n", + "sci.space 394 306 88 75 0.777 0.803 0.790\n", + "alt.atheism 319 225 94 105 0.705 0.682 0.693\n", + "talk.politics.guns 364 300 64 142 0.824 0.679 0.744\n", + "Total 7,532 5,551 1,981 1,981\n", + "Accuracy 0.737\n", + "Micro Average 0.737 0.737 0.737\n", + "Macro Average 0.733 0.735 0.732\n", + "Balanced Error Rate 0.267\n" ] } ], @@ -662,34 +662,34 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training the model on trimmed TF-IDF features took (00:00:19:928)\n", + "Training the model on trimmed TF-IDF features took (00:00:14:750)\n", "\n", "Class n tp fn fp recall prec f1\n", - "soc.religion.christian 398 337 61 93 0.847 0.784 0.814\n", - "rec.autos 396 312 84 60 0.788 0.839 0.813\n", - "talk.religion.misc 251 172 79 143 0.685 0.546 0.608\n", - "comp.windows.x 395 290 105 56 0.734 0.838 0.783\n", - "rec.sport.baseball 397 344 53 37 0.866 0.903 0.884\n", - "comp.graphics 389 284 105 112 0.730 0.717 0.724\n", - "talk.politics.mideast 376 301 75 19 0.801 0.941 0.865\n", - "comp.sys.ibm.pc.hardware 392 286 106 217 0.730 0.569 0.639\n", - "sci.med 396 295 101 74 0.745 0.799 0.771\n", - "comp.os.ms-windows.misc 394 219 175 52 0.556 0.808 0.659\n", - "sci.crypt 396 322 74 49 0.813 0.868 0.840\n", - "comp.sys.mac.hardware 385 287 98 125 0.745 0.697 0.720\n", - "misc.forsale 390 320 70 62 0.821 0.838 0.829\n", - "rec.motorcycles 398 353 45 45 0.887 0.887 0.887\n", - "talk.politics.misc 310 191 119 131 0.616 0.593 0.604\n", - "sci.electronics 393 298 95 148 0.758 0.668 0.710\n", - "rec.sport.hockey 399 370 29 41 0.927 0.900 0.914\n", - "sci.space 394 336 58 64 0.853 0.840 0.846\n", - "alt.atheism 319 218 101 59 0.683 0.787 0.732\n", - "talk.politics.guns 364 302 62 108 0.830 0.737 0.780\n", - "Total 7,532 5,837 1,695 1,695\n", - "Accuracy 0.775\n", - "Micro Average 0.775 0.775 0.775\n", - "Macro Average 0.771 0.778 0.771\n", - "Balanced Error Rate 0.229\n" + "soc.religion.christian 398 346 52 128 0.869 0.730 0.794\n", + "rec.autos 396 314 82 68 0.793 0.822 0.807\n", + "talk.religion.misc 251 162 89 121 0.645 0.572 0.607\n", + "comp.windows.x 395 275 120 55 0.696 0.833 0.759\n", + "rec.sport.baseball 397 333 64 26 0.839 0.928 0.881\n", + "talk.politics.mideast 376 295 81 28 0.785 0.913 0.844\n", + "comp.graphics 389 280 109 173 0.720 0.618 0.665\n", + "comp.sys.ibm.pc.hardware 392 277 115 186 0.707 0.598 0.648\n", + "sci.med 396 304 92 127 0.768 0.705 0.735\n", + "comp.os.ms-windows.misc 394 239 155 72 0.607 0.768 0.678\n", + "sci.crypt 396 343 53 70 0.866 0.831 0.848\n", + "comp.sys.mac.hardware 385 259 126 60 0.673 0.812 0.736\n", + "talk.politics.misc 310 193 117 68 0.623 0.739 0.676\n", + "rec.motorcycles 398 359 39 65 0.902 0.847 0.873\n", + "misc.forsale 390 339 51 84 0.869 0.801 0.834\n", + "sci.electronics 393 246 147 103 0.626 0.705 0.663\n", + "rec.sport.hockey 399 367 32 16 0.920 0.958 0.939\n", + "sci.space 394 335 59 86 0.850 0.796 0.822\n", + "alt.atheism 319 237 82 63 0.743 0.790 0.766\n", + "talk.politics.guns 364 310 54 120 0.852 0.721 0.781\n", + "Total 7,532 5,813 1,719 1,719\n", + "Accuracy 0.772\n", + "Micro Average 0.772 0.772 0.772\n", + "Macro Average 0.768 0.774 0.768\n", + "Balanced Error Rate 0.232\n" ] } ], @@ -734,9 +734,9 @@ "python -m transformers.convert_graph_to_onnx --framework pt --model bert-base-uncased bert-base-uncased.onnx\n", "```\n", "\n", - "You'll also need to download the `tokenizer.json` that goes with the BERT variant you are using, for `bert-base-uncased` that file is [here](https://huggingface.co/bert-base-uncased/blob/main/tokenizer.json). Assuming both of those files are now in the same directory as this tutorial, we can create the `BERTFeatureExtractor`. We're going to take the average token embedding across the whole input, as the `[CLS]` token which provides the sentence embedding tends to perform poorly unless it is fine-tuned on your task.\n", + "You'll also need to download the `tokenizer.json` that goes with the BERT variant you are using, for `bert-base-uncased` that file is [here](https://huggingface.co/bert-base-uncased/raw/main/tokenizer.json). Assuming both of those files are now in the same directory as this tutorial, we can create the `BERTFeatureExtractor`. We're going to take the average token embedding across the whole input, as the `[CLS]` token which provides the sentence embedding tends to perform poorly unless it is fine-tuned on your task.\n", "\n", - "Warning: this feature extraction step took more than a minute per newsgroup on a 2019 16\" 6-core MacBook Pro (using the default settings of ONNX Runtime i.e., using a single thead on the CPU provider) so around 55 minutes to extract the full train and test datasets. Your mileage may vary, and your laptop may get quite warm. We recommend not running it while your laptop is actually on your lap. At the moment Tribuo's `TextFeatureExtractor` interface doesn't batch up the inputs, which limits the performance of contextual feature extractors. We'll look at expanding that interface to support batching in a future release. The session options used can be controlled by the `BERTFeatureExtractor.reconfigureOrtSession(SessionOptions options)` method, which allows the use of whatever configuration is supported by your onnxruntime jar." + "Warning: this feature extraction step took more than a minute per newsgroup on a 2019 16\" 6-core MacBook Pro (using the default settings of ONNX Runtime i.e., using a single thead on the CPU provider) so around 55 minutes to extract the full train and test datasets. Your mileage may vary, and your laptop may get quite warm. We recommend not running it while your laptop is actually on your lap. At the moment Tribuo's `TextFeatureExtractor` interface doesn't batch up the inputs, which limits the performance of contextual feature extractors. We'll look at expanding that interface to support batching in a future release. The session options used can be controlled by the `BERTFeatureExtractor.reconfigureOrtSession(SessionOptions options)` method, which allows the use of whatever configuration is supported by your ONNX Runtime jar." ] }, { @@ -750,7 +750,7 @@ "text": [ "bert training data size = 11314, number of features = 768, number of classes = 20\n", "bert testing data size = 7532, number of features = 768, number of classes = 20\n", - "Extracting features with BERT took (00:38:37:476)\n" + "Extracting features with BERT took (00:32:03:647)\n" ] } ], @@ -789,33 +789,33 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training a LR on BERT features took (00:00:06:082)\n", + "Training a LR on BERT features took (00:00:03:802)\n", "Class n tp fn fp recall prec f1\n", - "soc.religion.christian 398 353 45 111 0.887 0.761 0.819\n", - "rec.autos 396 332 64 99 0.838 0.770 0.803\n", - "talk.religion.misc 251 102 149 131 0.406 0.438 0.421\n", - "comp.windows.x 395 288 107 121 0.729 0.704 0.716\n", - "rec.sport.baseball 397 365 32 32 0.919 0.919 0.919\n", - "comp.graphics 389 257 132 183 0.661 0.584 0.620\n", - "talk.politics.mideast 376 289 87 26 0.769 0.917 0.836\n", - "comp.sys.ibm.pc.hardware 392 220 172 166 0.561 0.570 0.566\n", - "sci.med 396 320 76 34 0.808 0.904 0.853\n", - "comp.os.ms-windows.misc 394 247 147 187 0.627 0.569 0.597\n", - "sci.crypt 396 314 82 95 0.793 0.768 0.780\n", - "comp.sys.mac.hardware 385 134 251 32 0.348 0.807 0.486\n", - "misc.forsale 390 342 48 103 0.877 0.769 0.819\n", - "rec.motorcycles 398 308 90 75 0.774 0.804 0.789\n", - "talk.politics.misc 310 186 124 226 0.600 0.451 0.515\n", - "sci.electronics 393 252 141 197 0.641 0.561 0.599\n", - "rec.sport.hockey 399 381 18 21 0.955 0.948 0.951\n", - "sci.space 394 332 62 78 0.843 0.810 0.826\n", - "alt.atheism 319 163 156 121 0.511 0.574 0.541\n", - "talk.politics.guns 364 210 154 99 0.577 0.680 0.624\n", - "Total 7,532 5,395 2,137 2,137\n", - "Accuracy 0.716\n", - "Micro Average 0.716 0.716 0.716\n", - "Macro Average 0.706 0.715 0.704\n", - "Balanced Error Rate 0.294\n" + "soc.religion.christian 398 367 31 114 0.922 0.763 0.835\n", + "rec.autos 396 306 90 51 0.773 0.857 0.813\n", + "talk.religion.misc 251 62 189 48 0.247 0.564 0.343\n", + "comp.windows.x 395 305 90 186 0.772 0.621 0.688\n", + "rec.sport.baseball 397 357 40 20 0.899 0.947 0.922\n", + "talk.politics.mideast 376 292 84 29 0.777 0.910 0.838\n", + "comp.graphics 389 243 146 153 0.625 0.614 0.619\n", + "comp.sys.ibm.pc.hardware 392 190 202 111 0.485 0.631 0.548\n", + "sci.med 396 332 64 53 0.838 0.862 0.850\n", + "comp.os.ms-windows.misc 394 202 192 92 0.513 0.687 0.587\n", + "sci.crypt 396 306 90 74 0.773 0.805 0.789\n", + "comp.sys.mac.hardware 385 263 122 201 0.683 0.567 0.620\n", + "talk.politics.misc 310 164 146 168 0.529 0.494 0.511\n", + "rec.motorcycles 398 337 61 118 0.847 0.741 0.790\n", + "misc.forsale 390 317 73 56 0.813 0.850 0.831\n", + "sci.electronics 393 234 159 124 0.595 0.654 0.623\n", + "rec.sport.hockey 399 380 19 21 0.952 0.948 0.950\n", + "sci.space 394 338 56 104 0.858 0.765 0.809\n", + "alt.atheism 319 200 119 175 0.627 0.533 0.576\n", + "talk.politics.guns 364 278 86 161 0.764 0.633 0.692\n", + "Total 7,532 5,473 2,059 2,059\n", + "Accuracy 0.727\n", + "Micro Average 0.727 0.727 0.727\n", + "Macro Average 0.715 0.722 0.712\n", + "Balanced Error Rate 0.285\n" ] } ], @@ -852,7 +852,7 @@ "text": [ "DirectoryFileSource(\n", "\tclass-name = org.tribuo.data.text.DirectoryFileSource\n", - "\tdataDir = /Users/apocock/Development/Tribuo/tutorials/20news/20news-bydate-train\n", + "\tdataDir = /local/ExternalRepositories/tribuo/tutorials/20news/20news-bydate-train\n", "\tpreprocessors = List[\n", "\t\tNewsPreprocessor(\n", "\t\t\t\t\tclass-name = org.tribuo.data.text.impl.NewsPreprocessor\n", @@ -868,8 +868,8 @@ "\t\t\tclass-name = org.tribuo.interop.onnx.extractors.BERTFeatureExtractor\n", "\t\t\tuseCUDA = false\n", "\t\t\tpooling = MEAN\n", - "\t\t\tmodelPath = /Users/apocock/Development/Tribuo/tutorials/bert-base-uncased.onnx\n", - "\t\t\ttokenizerPath = /Users/apocock/Development/Tribuo/tutorials/tokenizer.json\n", + "\t\t\tmodelPath = /local/ExternalRepositories/tribuo/tutorials/bert-base-uncased.onnx\n", + "\t\t\ttokenizerPath = /local/ExternalRepositories/tribuo/tutorials/tokenizer.json\n", "\t\t\toutputFactory = LabelFactory(\n", "\t\t\t\t\tclass-name = org.tribuo.classification.LabelFactory\n", "\t\t\t\t)\n", @@ -880,7 +880,7 @@ "\t\t\tclass-name = org.tribuo.classification.LabelFactory\n", "\t\t)\n", "\tfile-modified-time = 2003-03-18T07:24:55-05:00\n", - "\tdatasource-creation-time = 2021-12-18T20:50:57.169758-05:00\n", + "\tdatasource-creation-time = 2022-10-07T12:14:14.770299736-04:00\n", ")\n" ] } @@ -918,7 +918,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "17+35-LTS-2724" + "version": "17.0.4.1+1-LTS-2" } }, "nbformat": 4, diff --git a/tutorials/external-models-tribuo-v4.ipynb b/tutorials/external-models-tribuo-v4.ipynb index 0a3b57548..840fb0b1c 100644 --- a/tutorials/external-models-tribuo-v4.ipynb +++ b/tutorials/external-models-tribuo-v4.ipynb @@ -24,8 +24,8 @@ "metadata": {}, "outputs": [], "source": [ - "%jars tribuo-classification-experiments-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars tribuo-onnx-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars tribuo-classification-experiments-4.3.0-jar-with-dependencies.jar\n", + "%jars tribuo-onnx-4.3.0-jar-with-dependencies.jar" ] }, { @@ -469,7 +469,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "19" + "version": "12+33" } }, "nbformat": 4, diff --git a/tutorials/feature-selection-tribuo-v4.ipynb b/tutorials/feature-selection-tribuo-v4.ipynb index 9ed5a014a..f5f820d13 100644 --- a/tutorials/feature-selection-tribuo-v4.ipynb +++ b/tutorials/feature-selection-tribuo-v4.ipynb @@ -25,8 +25,8 @@ "metadata": {}, "outputs": [], "source": [ - "%jars tribuo-classification-sgd-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars tribuo-classification-fs-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars tribuo-classification-sgd-4.3.0-jar-with-dependencies.jar\n", + "%jars tribuo-classification-fs-4.3.0-jar-with-dependencies.jar" ] }, { @@ -118,7 +118,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training factorization machine on 783 features took (00:00:30:968)\n" + "Training factorization machine on 783 features took (00:00:31:395)\n" ] } ], @@ -158,21 +158,21 @@ "data": { "text/plain": [ "Class n tp fn fp recall prec f1\n", - "0 980 962 18 37 0.982 0.963 0.972\n", - "1 1,135 1,117 18 11 0.984 0.990 0.987\n", + "0 980 962 18 35 0.982 0.965 0.973\n", + "1 1,135 1,118 17 11 0.985 0.990 0.988\n", "2 1,032 992 40 63 0.961 0.940 0.951\n", - "3 1,010 968 42 45 0.958 0.956 0.957\n", - "4 982 934 48 39 0.951 0.960 0.955\n", - "5 892 861 31 50 0.965 0.945 0.955\n", - "6 958 921 37 27 0.961 0.972 0.966\n", - "7 1,028 981 47 36 0.954 0.965 0.959\n", - "8 974 915 59 40 0.939 0.958 0.949\n", - "9 1,009 953 56 48 0.944 0.952 0.948\n", - "Total 10,000 9,604 396 396\n", - "Accuracy 0.960\n", - "Micro Average 0.960 0.960 0.960\n", - "Macro Average 0.960 0.960 0.960\n", - "Balanced Error Rate 0.040" + "3 1,010 969 41 48 0.959 0.953 0.956\n", + "4 982 937 45 41 0.954 0.958 0.956\n", + "5 892 861 31 46 0.965 0.949 0.957\n", + "6 958 920 38 24 0.960 0.975 0.967\n", + "7 1,028 980 48 34 0.953 0.966 0.960\n", + "8 974 919 55 38 0.944 0.960 0.952\n", + "9 1,009 954 55 48 0.945 0.952 0.949\n", + "Total 10,000 9,612 388 388\n", + "Accuracy 0.961\n", + "Micro Average 0.961 0.961 0.961\n", + "Macro Average 0.961 0.961 0.961\n", + "Balanced Error Rate 0.039" ] }, "execution_count": 5, @@ -207,7 +207,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Selecting the top 100 features with MIM took (00:00:02:213)\n" + "Selecting the top 100 features with MIM took (00:00:02:861)\n" ] } ], @@ -244,14 +244,14 @@ "\t\t\tclass-name = org.tribuo.MutableDataset\n", "\t\t\tdatasource = IDXDataSource(\n", "\t\t\t\t\tclass-name = org.tribuo.datasource.IDXDataSource\n", - "\t\t\t\t\toutputPath = /Users/craigacp/Development/tribuo/tutorials/train-labels-idx1-ubyte.gz\n", + "\t\t\t\t\toutputPath = /local/ExternalRepositories/tribuo/tutorials/train-labels-idx1-ubyte.gz\n", "\t\t\t\t\toutputFactory = LabelFactory(\n", "\t\t\t\t\t\t\tclass-name = org.tribuo.classification.LabelFactory\n", "\t\t\t\t\t\t)\n", - "\t\t\t\t\tfeaturesPath = /Users/craigacp/Development/tribuo/tutorials/train-images-idx3-ubyte.gz\n", + "\t\t\t\t\tfeaturesPath = /local/ExternalRepositories/tribuo/tutorials/train-images-idx3-ubyte.gz\n", "\t\t\t\t\tfeatures-file-modified-time = 2000-07-21T14:20:24-04:00\n", "\t\t\t\t\toutput-resource-hash = 3552534A0A558BBED6AED32B30C495CCA23D567EC52CAC8BE1A0730E8010255C\n", - "\t\t\t\t\tdatasource-creation-time = 2022-10-01T21:29:52.192904-04:00\n", + "\t\t\t\t\tdatasource-creation-time = 2022-10-07T13:13:41.469063236-04:00\n", "\t\t\t\t\toutput-file-modified-time = 2000-07-21T14:20:27-04:00\n", "\t\t\t\t\tidx-feature-type = UBYTE\n", "\t\t\t\t\tfeatures-resource-hash = 440FCABF73CC546FA21475E81EA370265605F56BE210A4024D2CA8F203523609\n", @@ -263,7 +263,7 @@ "\t\t\tnum-examples = 60000\n", "\t\t\tnum-features = 717\n", "\t\t\tnum-outputs = 10\n", - "\t\t\ttribuo-version = 4.3.0-SNAPSHOT\n", + "\t\t\ttribuo-version = 4.3.0\n", "\t\t)\n", "\tfeature-selector = MIM(\n", "\t\t\tclass-name = org.tribuo.classification.fs.MIM\n", @@ -271,7 +271,7 @@ "\t\t\tk = 100\n", "\t\t\thost-short-name = FeatureSelector\n", "\t\t)\n", - "\ttribuo-version = 4.3.0-SNAPSHOT\n", + "\ttribuo-version = 4.3.0\n", ")\n" ] } @@ -331,7 +331,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training factorization machine on 100 features took (00:00:10:029)\n" + "Training factorization machine on 100 features took (00:00:12:582)\n" ] } ], @@ -410,7 +410,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Selecting the top 100 features with JMI took (00:01:15:685)\n", + "Selecting the top 100 features with JMI took (00:01:33:192)\n", "JMI feature set: [378, 461, 409, 568, 350, 434, 542, 406, 489, 596, 401, 381, 433, 377, 569, 462, 437, 514, 405, 155, 428, 597, 436, 373, 515, 351, 541, 543, 429, 460, 154, 488, 625, 400, 464, 567, 374, 379, 570, 375, 345, 540, 487, 456, 376, 346, 408, 490, 457, 318, 156, 516, 539, 290, 513, 459, 372, 595, 153, 486, 402, 323, 354, 347, 430, 626, 517, 458, 317, 432, 326, 407, 512, 427, 656, 349, 485, 404, 455, 263, 624, 353, 523, 598, 484, 403, 463, 571, 382, 511, 322, 291, 183, 435, 655, 544, 431, 483, 465, 410]\n" ] } @@ -443,7 +443,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training factorization machine on 100 features took (00:00:09:881)\n" + "Training factorization machine on 100 features took (00:00:12:409)\n" ] } ], @@ -531,7 +531,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "19" + "version": "17.0.4.1+1-LTS-2" } }, "nbformat": 4, diff --git a/tutorials/irises-tribuo-v4.ipynb b/tutorials/irises-tribuo-v4.ipynb index 9eac6c82b..ad63acbbf 100644 --- a/tutorials/irises-tribuo-v4.ipynb +++ b/tutorials/irises-tribuo-v4.ipynb @@ -27,8 +27,8 @@ "metadata": {}, "outputs": [], "source": [ - "%jars ./tribuo-classification-experiments-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-json-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars ./tribuo-classification-experiments-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-json-4.3.0-jar-with-dependencies.jar" ] }, { @@ -408,10 +408,10 @@ "\t\t\t\t\tclass-name = org.tribuo.classification.LabelFactory\n", "\t\t\t\t)\n", "\t\t\tseparator = ,\n", - "\t\t\tdataPath = /Users/craigacp/Development/tribuo/tutorials/bezdekIris.data\n", + "\t\t\tdataPath = /local/ExternalRepositories/tribuo/tutorials/bezdekIris.data\n", "\t\t\tresource-hash = 0FED2A99DB77EC533A62DC66894D3EC6DF3B58B6A8F3CF4A6B47E4086B7F97DC\n", "\t\t\tfile-modified-time = 1999-12-14T15:12:39-05:00\n", - "\t\t\tdatasource-creation-time = 2022-10-02T17:16:22.164235-04:00\n", + "\t\t\tdatasource-creation-time = 2022-10-07T11:20:06.279351-04:00\n", "\t\t\thost-short-name = DataSource\n", "\t\t)\n", "\ttrain-proportion = 0.7\n", @@ -463,7 +463,7 @@ "\t\t\tclass-name = org.tribuo.classification.sgd.objectives.LogMulticlass\n", "\t\t\thost-short-name = LabelObjective\n", "\t\t)\n", - "\ttribuo-version = 4.3.0-SNAPSHOT\n", + "\ttribuo-version = 4.3.0\n", "\ttrain-invocation-count = 0\n", "\tis-sequence = false\n", "\thost-short-name = Trainer\n", @@ -524,7 +524,7 @@ " \"tribuo-version\" : {\n", " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n", " \"key\" : \"tribuo-version\",\n", - " \"value\" : \"4.3.0-SNAPSHOT\",\n", + " \"value\" : \"4.3.0\",\n", " \"provenance-class\" : \"com.oracle.labs.mlrg.olcut.provenance.primitives.StringProvenance\",\n", " \"additional\" : \"\",\n", " \"is-reference\" : false\n", @@ -532,7 +532,7 @@ " \"java-version\" : {\n", " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n", " \"key\" : \"java-version\",\n", - " \"value\" : \"19\",\n", + " \"value\" : \"12\",\n", " \"provenance-class\" : \"com.oracle.labs.mlrg.olcut.provenance.primitives.StringProvenance\",\n", " \"additional\" : \"\",\n", " \"is-reference\" : false\n", @@ -548,7 +548,7 @@ " \"os-arch\" : {\n", " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n", " \"key\" : \"os-arch\",\n", - " \"value\" : \"aarch64\",\n", + " \"value\" : \"amd64\",\n", " \"provenance-class\" : \"com.oracle.labs.mlrg.olcut.provenance.primitives.StringProvenance\",\n", " \"additional\" : \"\",\n", " \"is-reference\" : false\n", @@ -556,7 +556,7 @@ " \"trained-at\" : {\n", " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n", " \"key\" : \"trained-at\",\n", - " \"value\" : \"2022-10-02T17:16:22.729336-04:00\",\n", + " \"value\" : \"2022-10-07T11:20:06.643297-04:00\",\n", " \"provenance-class\" : \"com.oracle.labs.mlrg.olcut.provenance.primitives.DateTimeProvenance\",\n", " \"additional\" : \"\",\n", " \"is-reference\" : false\n", @@ -564,7 +564,7 @@ " \"os-name\" : {\n", " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n", " \"key\" : \"os-name\",\n", - " \"value\" : \"Mac OS X\",\n", + " \"value\" : \"Linux\",\n", " \"provenance-class\" : \"com.oracle.labs.mlrg.olcut.provenance.primitives.StringProvenance\",\n", " \"additional\" : \"\",\n", " \"is-reference\" : false\n", @@ -619,7 +619,7 @@ " \"tribuo-version\" : {\n", " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n", " \"key\" : \"tribuo-version\",\n", - " \"value\" : \"4.3.0-SNAPSHOT\",\n", + " \"value\" : \"4.3.0\",\n", " \"provenance-class\" : \"com.oracle.labs.mlrg.olcut.provenance.primitives.StringProvenance\",\n", " \"additional\" : \"\",\n", " \"is-reference\" : false\n", @@ -678,7 +678,7 @@ " \"tribuo-version\" : {\n", " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n", " \"key\" : \"tribuo-version\",\n", - " \"value\" : \"4.3.0-SNAPSHOT\",\n", + " \"value\" : \"4.3.0\",\n", " \"provenance-class\" : \"com.oracle.labs.mlrg.olcut.provenance.primitives.StringProvenance\",\n", " \"additional\" : \"\",\n", " \"is-reference\" : false\n", @@ -896,14 +896,14 @@ " \"provenance-class\" : \"org.tribuo.data.csv.CSVDataSource$CSVDataSourceProvenance\",\n", " \"map\" : {\n", " \"resource-hash\" : {\n", - " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n" + " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n", + " \"key\" : \"resource-hash\",\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - " \"key\" : \"resource-hash\",\n", " \"value\" : \"0FED2A99DB77EC533A62DC66894D3EC6DF3B58B6A8F3CF4A6B47E4086B7F97DC\",\n", " \"provenance-class\" : \"com.oracle.labs.mlrg.olcut.provenance.primitives.HashProvenance\",\n", " \"additional\" : \"SHA256\",\n", @@ -983,7 +983,7 @@ " \"datasource-creation-time\" : {\n", " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n", " \"key\" : \"datasource-creation-time\",\n", - " \"value\" : \"2022-10-02T17:16:22.164235-04:00\",\n", + " \"value\" : \"2022-10-07T11:20:06.279351-04:00\",\n", " \"provenance-class\" : \"com.oracle.labs.mlrg.olcut.provenance.primitives.DateTimeProvenance\",\n", " \"additional\" : \"\",\n", " \"is-reference\" : false\n", @@ -1023,7 +1023,7 @@ " \"dataPath\" : {\n", " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n", " \"key\" : \"dataPath\",\n", - " \"value\" : \"/Users/craigacp/Development/tribuo/tutorials/bezdekIris.data\",\n", + " \"value\" : \"/local/ExternalRepositories/tribuo/tutorials/bezdekIris.data\",\n", " \"provenance-class\" : \"com.oracle.labs.mlrg.olcut.provenance.primitives.FileProvenance\",\n", " \"additional\" : \"\",\n", " \"is-reference\" : false\n", @@ -1084,7 +1084,13 @@ " \"is-reference\" : true\n", " },\n", " \"weightExtractor\" : {\n", - " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n", + " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ " \"key\" : \"weightExtractor\",\n", " \"value\" : \"fieldextractor-14\",\n", " \"provenance-class\" : \"com.oracle.labs.mlrg.olcut.provenance.impl.NullConfiguredProvenance\",\n", @@ -1269,13 +1275,7 @@ " },\n", " \"class-name\" : {\n", " \"marshalled-class\" : \"com.oracle.labs.mlrg.olcut.provenance.io.SimpleMarshalledProvenance\",\n", - " \"key\" : \"class-name\",\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ + " \"key\" : \"class-name\",\n", " \"value\" : \"org.tribuo.data.columnar.processors.field.DoubleFieldProcessor\",\n", " \"provenance-class\" : \"com.oracle.labs.mlrg.olcut.provenance.primitives.StringProvenance\",\n", " \"additional\" : \"\",\n", @@ -1412,7 +1412,13 @@ " \"additional\" : \"\",\n", " \"is-reference\" : false\n", " }\n", - " }\n", + " }\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ "} ]\n" ] } @@ -1438,7 +1444,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "linear-sgd-model - Model(class-name=org.tribuo.classification.sgd.linear.LinearSGDModel,dataset=Dataset(class-name=org.tribuo.MutableDataset,datasource=SplitDataSourceProvenance(className=org.tribuo.evaluation.TrainTestSplitter,innerSourceProvenance=DataSource(class-name=org.tribuo.data.csv.CSVDataSource,headers=[sepalLength, sepalWidth, petalLength, petalWidth, species],rowProcessor=RowProcessor(class-name=org.tribuo.data.columnar.RowProcessor,metadataExtractors=[],fieldProcessorList=[FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=petalLength,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor), FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=petalWidth,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor), FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=sepalWidth,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor), FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=sepalLength,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor)],featureProcessors=[],responseProcessor=ResponseProcessor(class-name=org.tribuo.data.columnar.processors.response.FieldResponseProcessor,uppercase=false,fieldNames=[species],defaultValues=[],displayField=false,outputFactory=OutputFactory(class-name=org.tribuo.classification.LabelFactory),host-short-name=ResponseProcessor),weightExtractor=null,replaceNewlinesWithSpaces=true,regexMappingProcessors={},host-short-name=RowProcessor),quote=\",outputRequired=true,outputFactory=OutputFactory(class-name=org.tribuo.classification.LabelFactory),separator=,,dataPath=/Users/craigacp/Development/tribuo/tutorials/bezdekIris.data,resource-hash=SHA-256[0FED2A99DB77EC533A62DC66894D3EC6DF3B58B6A8F3CF4A6B47E4086B7F97DC],file-modified-time=1999-12-14T15:12:39-05:00,datasource-creation-time=2022-10-02T17:16:22.164235-04:00,host-short-name=DataSource),trainProportion=0.7,seed=1,size=150,isTrain=true),transformations=[],is-sequence=false,is-dense=true,num-examples=105,num-features=4,num-outputs=3,tribuo-version=4.3.0-SNAPSHOT),trainer=Trainer(class-name=org.tribuo.classification.sgd.linear.LogisticRegressionTrainer,seed=12345,minibatchSize=1,shuffle=true,epochs=5,optimiser=StochasticGradientOptimiser(class-name=org.tribuo.math.optimisers.AdaGrad,epsilon=0.1,initialLearningRate=1.0,initialValue=0.0,host-short-name=StochasticGradientOptimiser),loggingInterval=1000,objective=LabelObjective(class-name=org.tribuo.classification.sgd.objectives.LogMulticlass,host-short-name=LabelObjective),tribuo-version=4.3.0-SNAPSHOT,train-invocation-count=0,is-sequence=false,host-short-name=Trainer),trained-at=2022-10-02T17:16:22.729336-04:00,instance-values={},tribuo-version=4.3.0-SNAPSHOT,java-version=19,os-name=Mac OS X,os-arch=aarch64)\n" + "linear-sgd-model - Model(class-name=org.tribuo.classification.sgd.linear.LinearSGDModel,dataset=Dataset(class-name=org.tribuo.MutableDataset,datasource=SplitDataSourceProvenance(className=org.tribuo.evaluation.TrainTestSplitter,innerSourceProvenance=DataSource(class-name=org.tribuo.data.csv.CSVDataSource,headers=[sepalLength, sepalWidth, petalLength, petalWidth, species],rowProcessor=RowProcessor(class-name=org.tribuo.data.columnar.RowProcessor,metadataExtractors=[],fieldProcessorList=[FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=petalLength,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor), FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=petalWidth,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor), FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=sepalWidth,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor), FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=sepalLength,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor)],featureProcessors=[],responseProcessor=ResponseProcessor(class-name=org.tribuo.data.columnar.processors.response.FieldResponseProcessor,uppercase=false,fieldNames=[species],defaultValues=[],displayField=false,outputFactory=OutputFactory(class-name=org.tribuo.classification.LabelFactory),host-short-name=ResponseProcessor),weightExtractor=null,replaceNewlinesWithSpaces=true,regexMappingProcessors={},host-short-name=RowProcessor),quote=\",outputRequired=true,outputFactory=OutputFactory(class-name=org.tribuo.classification.LabelFactory),separator=,,dataPath=/local/ExternalRepositories/tribuo/tutorials/bezdekIris.data,resource-hash=SHA-256[0FED2A99DB77EC533A62DC66894D3EC6DF3B58B6A8F3CF4A6B47E4086B7F97DC],file-modified-time=1999-12-14T15:12:39-05:00,datasource-creation-time=2022-10-07T11:20:06.279351-04:00,host-short-name=DataSource),trainProportion=0.7,seed=1,size=150,isTrain=true),transformations=[],is-sequence=false,is-dense=true,num-examples=105,num-features=4,num-outputs=3,tribuo-version=4.3.0),trainer=Trainer(class-name=org.tribuo.classification.sgd.linear.LogisticRegressionTrainer,seed=12345,minibatchSize=1,shuffle=true,epochs=5,optimiser=StochasticGradientOptimiser(class-name=org.tribuo.math.optimisers.AdaGrad,epsilon=0.1,initialLearningRate=1.0,initialValue=0.0,host-short-name=StochasticGradientOptimiser),loggingInterval=1000,objective=LabelObjective(class-name=org.tribuo.classification.sgd.objectives.LogMulticlass,host-short-name=LabelObjective),tribuo-version=4.3.0,train-invocation-count=0,is-sequence=false,host-short-name=Trainer),trained-at=2022-10-07T11:20:06.643297-04:00,instance-values={},tribuo-version=4.3.0,java-version=12,os-name=Linux,os-arch=amd64)\n" ] } ], @@ -1463,12 +1469,12 @@ "output_type": "stream", "text": [ "{\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", " \"dataset-provenance\" : {\n", " \"num-features\" : \"4\",\n", " \"num-examples\" : \"45\",\n", " \"num-outputs\" : \"3\",\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", " \"datasource\" : {\n", " \"train-proportion\" : \"0.7\",\n", " \"seed\" : \"1\",\n", @@ -1526,14 +1532,14 @@ " \"file-modified-time\" : \"1999-12-14T15:12:39-05:00\",\n", " \"quote\" : \"\\\"\",\n", " \"outputRequired\" : \"true\",\n", - " \"datasource-creation-time\" : \"2022-10-02T17:16:22.164235-04:00\",\n", + " \"datasource-creation-time\" : \"2022-10-07T11:20:06.279351-04:00\",\n", " \"outputFactory\" : {\n", " \"class-name\" : \"org.tribuo.classification.LabelFactory\"\n", " },\n", " \"separator\" : \",\",\n", " \"host-short-name\" : \"DataSource\",\n", " \"class-name\" : \"org.tribuo.data.csv.CSVDataSource\",\n", - " \"dataPath\" : \"/Users/craigacp/Development/tribuo/tutorials/bezdekIris.data\"\n", + " \"dataPath\" : \"/local/ExternalRepositories/tribuo/tutorials/bezdekIris.data\"\n", " },\n", " \"class-name\" : \"org.tribuo.evaluation.TrainTestSplitter\",\n", " \"is-train\" : \"false\"\n", @@ -1546,11 +1552,11 @@ " \"class-name\" : \"org.tribuo.provenance.EvaluationProvenance\",\n", " \"model-provenance\" : {\n", " \"instance-values\" : { },\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", - " \"java-version\" : \"19\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", + " \"java-version\" : \"12\",\n", " \"trainer\" : {\n", " \"seed\" : \"12345\",\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", " \"minibatchSize\" : \"1\",\n", " \"train-invocation-count\" : \"0\",\n", " \"is-sequence\" : \"false\",\n", @@ -1571,14 +1577,14 @@ " \"class-name\" : \"org.tribuo.classification.sgd.objectives.LogMulticlass\"\n", " }\n", " },\n", - " \"os-arch\" : \"aarch64\",\n", - " \"trained-at\" : \"2022-10-02T17:16:22.729336-04:00\",\n", - " \"os-name\" : \"Mac OS X\",\n", + " \"os-arch\" : \"amd64\",\n", + " \"trained-at\" : \"2022-10-07T11:20:06.643297-04:00\",\n", + " \"os-name\" : \"Linux\",\n", " \"dataset\" : {\n", " \"num-features\" : \"4\",\n", " \"num-examples\" : \"105\",\n", " \"num-outputs\" : \"3\",\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", " \"datasource\" : {\n", " \"train-proportion\" : \"0.7\",\n", " \"seed\" : \"1\",\n", @@ -1636,14 +1642,14 @@ " \"file-modified-time\" : \"1999-12-14T15:12:39-05:00\",\n", " \"quote\" : \"\\\"\",\n", " \"outputRequired\" : \"true\",\n", - " \"datasource-creation-time\" : \"2022-10-02T17:16:22.164235-04:00\",\n", + " \"datasource-creation-time\" : \"2022-10-07T11:20:06.279351-04:00\",\n", " \"outputFactory\" : {\n", " \"class-name\" : \"org.tribuo.classification.LabelFactory\"\n", " },\n", " \"separator\" : \",\",\n", " \"host-short-name\" : \"DataSource\",\n", " \"class-name\" : \"org.tribuo.data.csv.CSVDataSource\",\n", - " \"dataPath\" : \"/Users/craigacp/Development/tribuo/tutorials/bezdekIris.data\"\n", + " \"dataPath\" : \"/local/ExternalRepositories/tribuo/tutorials/bezdekIris.data\"\n", " },\n", " \"class-name\" : \"org.tribuo.evaluation.TrainTestSplitter\",\n", " \"is-train\" : \"true\"\n", @@ -1827,7 +1833,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "19" + "version": "12+33" } }, "nbformat": 4, diff --git a/tutorials/modelcard-tribuo-v4.ipynb b/tutorials/modelcard-tribuo-v4.ipynb index 04c75bc6d..fd61787a8 100644 --- a/tutorials/modelcard-tribuo-v4.ipynb +++ b/tutorials/modelcard-tribuo-v4.ipynb @@ -25,8 +25,8 @@ }, "outputs": [], "source": [ - "%jars ./tribuo-anomaly-libsvm-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-modelcard-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars ./tribuo-anomaly-libsvm-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-modelcard-4.3.0-jar-with-dependencies.jar" ] }, { @@ -129,7 +129,7 @@ "\t\t\tnum-examples = 2000\n", "\t\t\tnum-features = 5\n", "\t\t\tnum-outputs = 2\n", - "\t\t\ttribuo-version = 4.3.0-SNAPSHOT\n", + "\t\t\ttribuo-version = 4.3.0\n", "\t\t)\n", "\ttrainer = LibSVMAnomalyTrainer(\n", "\t\t\tclass-name = org.tribuo.anomaly.libsvm.LibSVMAnomalyTrainer\n", @@ -150,17 +150,17 @@ "\t\t\t\t\thost-short-name = SVMType\n", "\t\t\t\t)\n", "\t\t\tgamma = 1.0\n", - "\t\t\ttribuo-version = 4.3.0-SNAPSHOT\n", + "\t\t\ttribuo-version = 4.3.0\n", "\t\t\ttrain-invocation-count = 0\n", "\t\t\tis-sequence = false\n", "\t\t\thost-short-name = Trainer\n", "\t\t)\n", - "\ttrained-at = 2022-09-22T14:18:03.073938-04:00\n", + "\ttrained-at = 2022-10-07T12:03:06.539476091-04:00\n", "\tinstance-values = Map{}\n", - "\ttribuo-version = 4.3.0-SNAPSHOT\n", + "\ttribuo-version = 4.3.0\n", "\tjava-version = 17.0.4.1\n", - "\tos-name = Mac OS X\n", - "\tos-arch = x86_64\n", + "\tos-name = Linux\n", + "\tos-arch = amd64\n", ")\n", "\n", "EvaluationProvenance(\n", @@ -210,7 +210,7 @@ "\t\t\t\t\tnum-examples = 2000\n", "\t\t\t\t\tnum-features = 5\n", "\t\t\t\t\tnum-outputs = 2\n", - "\t\t\t\t\ttribuo-version = 4.3.0-SNAPSHOT\n", + "\t\t\t\t\ttribuo-version = 4.3.0\n", "\t\t\t\t)\n", "\t\t\ttrainer = LibSVMAnomalyTrainer(\n", "\t\t\t\t\tclass-name = org.tribuo.anomaly.libsvm.LibSVMAnomalyTrainer\n", @@ -231,17 +231,17 @@ "\t\t\t\t\t\t\thost-short-name = SVMType\n", "\t\t\t\t\t\t)\n", "\t\t\t\t\tgamma = 1.0\n", - "\t\t\t\t\ttribuo-version = 4.3.0-SNAPSHOT\n", + "\t\t\t\t\ttribuo-version = 4.3.0\n", "\t\t\t\t\ttrain-invocation-count = 0\n", "\t\t\t\t\tis-sequence = false\n", "\t\t\t\t\thost-short-name = Trainer\n", "\t\t\t\t)\n", - "\t\t\ttrained-at = 2022-09-22T14:18:03.073938-04:00\n", + "\t\t\ttrained-at = 2022-10-07T12:03:06.539476091-04:00\n", "\t\t\tinstance-values = Map{}\n", - "\t\t\ttribuo-version = 4.3.0-SNAPSHOT\n", + "\t\t\ttribuo-version = 4.3.0\n", "\t\t\tjava-version = 17.0.4.1\n", - "\t\t\tos-name = Mac OS X\n", - "\t\t\tos-arch = x86_64\n", + "\t\t\tos-name = Linux\n", + "\t\t\tos-arch = amd64\n", "\t\t)\n", "\tdataset-provenance = MutableDataset(\n", "\t\t\tclass-name = org.tribuo.MutableDataset\n", @@ -286,9 +286,9 @@ "\t\t\tnum-examples = 2000\n", "\t\t\tnum-features = 5\n", "\t\t\tnum-outputs = 2\n", - "\t\t\ttribuo-version = 4.3.0-SNAPSHOT\n", + "\t\t\ttribuo-version = 4.3.0\n", "\t\t)\n", - "\ttribuo-version = 4.3.0-SNAPSHOT\n", + "\ttribuo-version = 4.3.0\n", ")\n" ] } @@ -336,7 +336,7 @@ " \"schema-version\" : \"1.0\",\n", " \"model-type\" : \"LibSVMAnomalyModel\",\n", " \"model-package\" : \"org.tribuo.anomaly.libsvm.LibSVMAnomalyModel\",\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", " \"java-version\" : \"17.0.4.1\",\n", " \"configured-parameters\" : {\n", " \"cost\" : \"1.0\",\n", @@ -359,13 +359,13 @@ " \"host-short-name\" : \"SVMType\",\n", " \"class-name\" : \"org.tribuo.anomaly.libsvm.SVMAnomalyType\"\n", " },\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", " \"gamma\" : \"1.0\"\n", " }\n", " },\n", " \"TrainingDetails\" : {\n", " \"schema-version\" : \"1.0\",\n", - " \"training-time\" : \"2022-09-22T14:18:03.073938-04:00\",\n", + " \"training-time\" : \"2022-10-07T12:03:06.539476091-04:00\",\n", " \"training-set-size\" : 2000,\n", " \"num-features\" : 5,\n", " \"features-list\" : [ \"A\", \"B\", \"C\", \"D\", \"E\" ],\n", @@ -415,7 +415,7 @@ " \"schema-version\" : \"1.0\",\n", " \"model-type\" : \"LibSVMAnomalyModel\",\n", " \"model-package\" : \"org.tribuo.anomaly.libsvm.LibSVMAnomalyModel\",\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", " \"java-version\" : \"17.0.4.1\",\n", " \"configured-parameters\" : {\n", " \"cost\" : \"1.0\",\n", @@ -438,13 +438,13 @@ " \"host-short-name\" : \"SVMType\",\n", " \"class-name\" : \"org.tribuo.anomaly.libsvm.SVMAnomalyType\"\n", " },\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", " \"gamma\" : \"1.0\"\n", " }\n", " },\n", " \"TrainingDetails\" : {\n", " \"schema-version\" : \"1.0\",\n", - " \"training-time\" : \"2022-09-22T14:18:03.073938-04:00\",\n", + " \"training-time\" : \"2022-10-07T12:03:06.539476091-04:00\",\n", " \"training-set-size\" : 2000,\n", " \"num-features\" : 5,\n", " \"features-list\" : [ \"A\", \"B\", \"C\", \"D\", \"E\" ],\n", @@ -501,7 +501,7 @@ " \"schema-version\" : \"1.0\",\n", " \"model-type\" : \"LibSVMAnomalyModel\",\n", " \"model-package\" : \"org.tribuo.anomaly.libsvm.LibSVMAnomalyModel\",\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", " \"java-version\" : \"17.0.4.1\",\n", " \"configured-parameters\" : {\n", " \"cost\" : \"1.0\",\n", @@ -524,13 +524,13 @@ " \"host-short-name\" : \"SVMType\",\n", " \"class-name\" : \"org.tribuo.anomaly.libsvm.SVMAnomalyType\"\n", " },\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", " \"gamma\" : \"1.0\"\n", " }\n", " },\n", " \"TrainingDetails\" : {\n", " \"schema-version\" : \"1.0\",\n", - " \"training-time\" : \"2022-09-22T14:18:03.073938-04:00\",\n", + " \"training-time\" : \"2022-10-07T12:03:06.539476091-04:00\",\n", " \"training-set-size\" : 2000,\n", " \"num-features\" : 5,\n", " \"features-list\" : [ \"A\", \"B\", \"C\", \"D\", \"E\" ],\n", @@ -600,7 +600,7 @@ " \"schema-version\" : \"1.0\",\n", " \"model-type\" : \"LibSVMAnomalyModel\",\n", " \"model-package\" : \"org.tribuo.anomaly.libsvm.LibSVMAnomalyModel\",\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", " \"java-version\" : \"17.0.4.1\",\n", " \"configured-parameters\" : {\n", " \"cost\" : \"1.0\",\n", @@ -623,13 +623,13 @@ " \"host-short-name\" : \"SVMType\",\n", " \"class-name\" : \"org.tribuo.anomaly.libsvm.SVMAnomalyType\"\n", " },\n", - " \"tribuo-version\" : \"4.3.0-SNAPSHOT\",\n", + " \"tribuo-version\" : \"4.3.0\",\n", " \"gamma\" : \"1.0\"\n", " }\n", " },\n", " \"TrainingDetails\" : {\n", " \"schema-version\" : \"1.0\",\n", - " \"training-time\" : \"2022-09-22T14:18:03.073938-04:00\",\n", + " \"training-time\" : \"2022-10-07T12:03:06.539476091-04:00\",\n", " \"training-set-size\" : 2000,\n", " \"num-features\" : 5,\n", " \"features-list\" : [ \"A\", \"B\", \"C\", \"D\", \"E\" ],\n", diff --git a/tutorials/multi-label-tribuo-v4.ipynb b/tutorials/multi-label-tribuo-v4.ipynb index 788bafb0c..92fa1c6eb 100644 --- a/tutorials/multi-label-tribuo-v4.ipynb +++ b/tutorials/multi-label-tribuo-v4.ipynb @@ -32,8 +32,8 @@ "metadata": {}, "outputs": [], "source": [ - "%jars ./tribuo-multilabel-sgd-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-classification-experiments-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars ./tribuo-multilabel-sgd-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-classification-experiments-4.3.0-jar-with-dependencies.jar" ] }, { @@ -172,7 +172,7 @@ "output_type": "stream", "text": [ "\n", - "Linear model training took (00:00:00:245)\n" + "Linear model training took (00:00:00:192)\n" ] } ], @@ -201,7 +201,7 @@ "output_type": "stream", "text": [ "\n", - "Tree model training took (00:00:03:499)\n" + "Tree model training took (00:00:03:188)\n" ] } ], @@ -256,7 +256,7 @@ "output_type": "stream", "text": [ "\n", - "Linear model evaluation took (00:00:00:073)\n", + "Linear model evaluation took (00:00:00:063)\n", "Class n tp fn fp recall prec f1\n", "(LabelSet={12}) 683 677 6 230 0.991 0.746 0.852\n", "(LabelSet={13}) 13 0 13 0 0.000 0.000 0.000\n", @@ -307,7 +307,7 @@ "output_type": "stream", "text": [ "\n", - "Tree model evaluation took (00:00:00:085)\n", + "Tree model evaluation took (00:00:00:094)\n", "Class n tp fn fp recall prec f1\n", "(LabelSet={12}) 683 607 76 201 0.889 0.751 0.814\n", "(LabelSet={13}) 13 0 13 2 0.000 0.000 0.000\n", @@ -387,8 +387,8 @@ "output_type": "stream", "text": [ "\n", - "Classifier Chain model training took (00:00:03:195)\n", - "Classifier Chain model evaluation took (00:00:00:146)\n", + "Classifier Chain model training took (00:00:02:893)\n", + "Classifier Chain model evaluation took (00:00:00:153)\n", "Class n tp fn fp recall prec f1\n", "(LabelSet={12}) 683 616 67 203 0.902 0.752 0.820\n", "(LabelSet={13}) 13 0 13 2 0.000 0.000 0.000\n", @@ -448,8 +448,8 @@ "output_type": "stream", "text": [ "\n", - "Classifier Chain Ensemble model training took (00:01:04:418)\n", - "Classifier Chain Ensemble model evaluation took (00:00:02:474)\n", + "Classifier Chain Ensemble model training took (00:00:54:230)\n", + "Classifier Chain Ensemble model evaluation took (00:00:02:249)\n", "Class n tp fn fp recall prec f1\n", "(LabelSet={12}) 683 629 54 216 0.921 0.744 0.823\n", "(LabelSet={13}) 13 0 13 1 0.000 0.000 0.000\n", @@ -514,7 +514,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "17+35-LTS-2724" + "version": "12+33" } }, "nbformat": 4, diff --git a/tutorials/onnx-export-tribuo-v4.ipynb b/tutorials/onnx-export-tribuo-v4.ipynb index 7d5057963..9fa494436 100644 --- a/tutorials/onnx-export-tribuo-v4.ipynb +++ b/tutorials/onnx-export-tribuo-v4.ipynb @@ -37,10 +37,10 @@ "metadata": {}, "outputs": [], "source": [ - "%jars ./tribuo-classification-experiments-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-oci-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-onnx-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-json-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars ./tribuo-classification-experiments-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-oci-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-onnx-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-json-4.3.0-jar-with-dependencies.jar" ] }, { @@ -150,7 +150,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training factorization machine took (00:00:11:305)\n" + "Training factorization machine took (00:00:15:126)\n" ] } ], @@ -177,7 +177,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Scoring factorization machine took (00:00:00:412)\n", + "Scoring factorization machine took (00:00:00:379)\n", "Class n tp fn fp recall prec f1\n", "0 980 959 21 31 0.979 0.969 0.974\n", "1 1,135 1,120 15 22 0.987 0.981 0.984\n", @@ -352,7 +352,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Scoring ONNX factorization machine took (00:00:00:810)\n", + "Scoring ONNX factorization machine took (00:00:00:801)\n", "Class n tp fn fp recall prec f1\n", "0 980 959 21 31 0.979 0.969 0.974\n", "1 1,135 1,120 15 22 0.987 0.981 0.984\n", @@ -446,7 +446,7 @@ "\t\t\t\t\toutputFactory = LabelFactory(\n", "\t\t\t\t\t\t\tclass-name = org.tribuo.classification.LabelFactory\n", "\t\t\t\t\t\t)\n", - "\t\t\t\t\tdatasource-creation-time = 2021-12-18T20:36:37.266127-05:00\n", + "\t\t\t\t\tdatasource-creation-time = 2022-10-07T11:46:10.955196-04:00\n", "\t\t\t\t)\n", "\t\t\ttransformations = List[]\n", "\t\t\tis-sequence = false\n", @@ -454,27 +454,27 @@ "\t\t\tnum-examples = -1\n", "\t\t\tnum-features = 717\n", "\t\t\tnum-outputs = 10\n", - "\t\t\ttribuo-version = 4.2.0\n", + "\t\t\ttribuo-version = 4.3.0\n", "\t\t)\n", "\ttrainer = Trainer(\n", "\t\t\tclass-name = org.tribuo.Trainer\n", - "\t\t\tfileModifiedTime = 2021-12-18T20:36:36.445-05:00\n", - "\t\t\tmodelHash = 06071247AEDE7539B899A2D530508D8E2B43304B8A7884A257368AA2CF1C18ED\n", - "\t\t\tlocation = file:/Users/apocock/Development/Tribuo/tutorials/./fm-mnist.onnx\n", + "\t\t\tfileModifiedTime = 2022-10-07T11:46:10.476-04:00\n", + "\t\t\tmodelHash = 9DD2FABC436FB75BAD6A3E061BE51022A79F140FC491C6CA8B8033253F43CD5F\n", + "\t\t\tlocation = file:/local/ExternalRepositories/tribuo/tutorials/./fm-mnist.onnx\n", "\t\t)\n", - "\ttrained-at = 2021-12-18T20:36:37.263832-05:00\n", + "\ttrained-at = 2022-10-07T11:46:10.952607-04:00\n", "\tinstance-values = Map{\n", "\t\tmodel-domain=org.tribuo.tutorials.onnxexport.fm\n", "\t\tmodel-graphname=FMClassificationModel\n", - "\t\tmodel-description=factorization-machine-model - Model(class-name=org.tribuo.classification.sgd.fm.FMClassificationModel,dataset=Dataset(class-name=org.tribuo.MutableDataset,datasource=DataSource(class-name=org.tribuo.datasource.IDXDataSource,outputPath=/Users/apocock/Development/Tribuo/tutorials/train-labels-idx1-ubyte.gz,outputFactory=OutputFactory(class-name=org.tribuo.classification.LabelFactory),featuresPath=/Users/apocock/Development/Tribuo/tutorials/train-images-idx3-ubyte.gz,features-file-modified-time=2000-07-21T14:20:24-04:00,output-resource-hash=SHA-256[3552534A0A558BBED6AED32B30C495CCA23D567EC52CAC8BE1A0730E8010255C],datasource-creation-time=2021-12-18T20:36:23.109293-05:00,output-file-modified-time=2000-07-21T14:20:27-04:00,idx-feature-type=UBYTE,features-resource-hash=SHA-256[440FCABF73CC546FA21475E81EA370265605F56BE210A4024D2CA8F203523609],host-short-name=DataSource),transformations=[],is-sequence=false,is-dense=false,num-examples=60000,num-features=717,num-outputs=10,tribuo-version=4.2.0),trainer=Trainer(class-name=org.tribuo.classification.sgd.fm.FMClassificationTrainer,seed=12345,variance=0.1,minibatchSize=1,factorizedDimSize=6,shuffle=true,epochs=5,optimiser=StochasticGradientOptimiser(class-name=org.tribuo.math.optimisers.AdaGrad,epsilon=0.1,initialLearningRate=0.1,initialValue=0.0,host-short-name=StochasticGradientOptimiser),loggingInterval=30000,objective=LabelObjective(class-name=org.tribuo.classification.sgd.objectives.LogMulticlass,host-short-name=LabelObjective),tribuo-version=4.2.0,train-invocation-count=0,is-sequence=false,host-short-name=Trainer),trained-at=2021-12-18T20:36:35.640663-05:00,instance-values={},tribuo-version=4.2.0,java-version=17.0.1,os-name=Mac OS X,os-arch=x86_64)\n", + "\t\tmodel-description=factorization-machine-model - Model(class-name=org.tribuo.classification.sgd.fm.FMClassificationModel,dataset=Dataset(class-name=org.tribuo.MutableDataset,datasource=DataSource(class-name=org.tribuo.datasource.IDXDataSource,outputPath=/local/ExternalRepositories/tribuo/tutorials/train-labels-idx1-ubyte.gz,outputFactory=OutputFactory(class-name=org.tribuo.classification.LabelFactory),featuresPath=/local/ExternalRepositories/tribuo/tutorials/train-images-idx3-ubyte.gz,features-file-modified-time=2000-07-21T14:20:24-04:00,output-resource-hash=SHA-256[3552534A0A558BBED6AED32B30C495CCA23D567EC52CAC8BE1A0730E8010255C],datasource-creation-time=2022-10-07T11:45:53.253680-04:00,output-file-modified-time=2000-07-21T14:20:27-04:00,idx-feature-type=UBYTE,features-resource-hash=SHA-256[440FCABF73CC546FA21475E81EA370265605F56BE210A4024D2CA8F203523609],host-short-name=DataSource),transformations=[],is-sequence=false,is-dense=false,num-examples=60000,num-features=717,num-outputs=10,tribuo-version=4.3.0),trainer=Trainer(class-name=org.tribuo.classification.sgd.fm.FMClassificationTrainer,seed=12345,variance=0.1,minibatchSize=1,factorizedDimSize=6,shuffle=true,epochs=5,optimiser=StochasticGradientOptimiser(class-name=org.tribuo.math.optimisers.AdaGrad,epsilon=0.1,initialLearningRate=0.1,initialValue=0.0,host-short-name=StochasticGradientOptimiser),loggingInterval=30000,objective=LabelObjective(class-name=org.tribuo.classification.sgd.objectives.LogMulticlass,host-short-name=LabelObjective),tribuo-version=4.3.0,train-invocation-count=0,is-sequence=false,host-short-name=Trainer),trained-at=2022-10-07T11:46:09.759423-04:00,instance-values={},tribuo-version=4.3.0,java-version=12,os-name=Linux,os-arch=amd64)\n", "\t\tmodel-producer=Tribuo\n", "\t\tmodel-version=0\n", "\t\tinput-name=input\n", "\t}\n", - "\ttribuo-version = 4.2.0\n", - "\tjava-version = 17.0.1\n", - "\tos-name = Mac OS X\n", - "\tos-arch = x86_64\n", + "\ttribuo-version = 4.3.0\n", + "\tjava-version = 12\n", + "\tos-name = Linux\n", + "\tos-arch = amd64\n", ")\n" ] } @@ -511,11 +511,11 @@ "\t\t\t\t\toutputFactory = LabelFactory(\n", "\t\t\t\t\t\t\tclass-name = org.tribuo.classification.LabelFactory\n", "\t\t\t\t\t\t)\n", - "\t\t\t\t\toutputPath = /Users/apocock/Development/Tribuo/tutorials/train-labels-idx1-ubyte.gz\n", - "\t\t\t\t\tfeaturesPath = /Users/apocock/Development/Tribuo/tutorials/train-images-idx3-ubyte.gz\n", + "\t\t\t\t\toutputPath = /local/ExternalRepositories/tribuo/tutorials/train-labels-idx1-ubyte.gz\n", + "\t\t\t\t\tfeaturesPath = /local/ExternalRepositories/tribuo/tutorials/train-images-idx3-ubyte.gz\n", "\t\t\t\t\tfeatures-file-modified-time = 2000-07-21T14:20:24-04:00\n", "\t\t\t\t\toutput-resource-hash = 3552534A0A558BBED6AED32B30C495CCA23D567EC52CAC8BE1A0730E8010255C\n", - "\t\t\t\t\tdatasource-creation-time = 2021-12-18T20:36:23.109293-05:00\n", + "\t\t\t\t\tdatasource-creation-time = 2022-10-07T11:45:53.253680-04:00\n", "\t\t\t\t\toutput-file-modified-time = 2000-07-21T14:20:27-04:00\n", "\t\t\t\t\tidx-feature-type = UBYTE\n", "\t\t\t\t\tfeatures-resource-hash = 440FCABF73CC546FA21475E81EA370265605F56BE210A4024D2CA8F203523609\n", @@ -527,7 +527,7 @@ "\t\t\tnum-examples = 60000\n", "\t\t\tnum-features = 717\n", "\t\t\tnum-outputs = 10\n", - "\t\t\ttribuo-version = 4.2.0\n", + "\t\t\ttribuo-version = 4.3.0\n", "\t\t)\n", "\ttrainer = FMClassificationTrainer(\n", "\t\t\tclass-name = org.tribuo.classification.sgd.fm.FMClassificationTrainer\n", @@ -549,17 +549,17 @@ "\t\t\t\t\tclass-name = org.tribuo.classification.sgd.objectives.LogMulticlass\n", "\t\t\t\t\thost-short-name = LabelObjective\n", "\t\t\t\t)\n", - "\t\t\ttribuo-version = 4.2.0\n", + "\t\t\ttribuo-version = 4.3.0\n", "\t\t\ttrain-invocation-count = 0\n", "\t\t\tis-sequence = false\n", "\t\t\thost-short-name = Trainer\n", "\t\t)\n", - "\ttrained-at = 2021-12-18T20:36:35.640663-05:00\n", + "\ttrained-at = 2022-10-07T11:46:09.759423-04:00\n", "\tinstance-values = Map{}\n", - "\ttribuo-version = 4.2.0\n", - "\tjava-version = 17.0.1\n", - "\tos-name = Mac OS X\n", - "\tos-arch = x86_64\n", + "\ttribuo-version = 4.3.0\n", + "\tjava-version = 12\n", + "\tos-name = Linux\n", + "\tos-arch = amd64\n", ")\n" ] } @@ -648,7 +648,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Scoring ensemble took (00:00:00:675)\n", + "Scoring ensemble took (00:00:00:611)\n", "Class n tp fn fp recall prec f1\n", "0 980 965 15 43 0.985 0.957 0.971\n", "1 1,135 1,119 16 34 0.986 0.971 0.978\n", @@ -725,7 +725,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Scoring ONNX ensemble took (00:00:01:021)\n", + "Scoring ONNX ensemble took (00:00:00:938)\n", "Predictions are equal - true\n" ] } @@ -774,7 +774,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -809,7 +809,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -827,7 +827,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -848,7 +848,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -863,19 +863,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "As `OCIModel` is a Tribuo model we can evaluate it using our standard tools." + "As `OCIModel` is a Tribuo model we can evaluate it using our standard tools.\n", + "\n", + "Note when running this notebook from scratch the OCI Model Deployment can take up to 15 minutes to fully instantiate, and the next cell will not execute correctly until that deployment has finished. You can monitor the status of the deployment in the OCI console." ] }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Scoring OCI model took (00:01:06:960)\n", + "Scoring OCI model took (00:00:53:606)\n", "Class n tp fn fp recall prec f1\n", "0 980 959 21 31 0.979 0.969 0.974\n", "1 1,135 1,120 15 22 0.987 0.981 0.984\n", @@ -944,7 +946,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "19" + "version": "12+33" } }, "nbformat": 4, diff --git a/tutorials/regression-tribuo-v4.ipynb b/tutorials/regression-tribuo-v4.ipynb index c1dc5bedf..85f6f5cef 100644 --- a/tutorials/regression-tribuo-v4.ipynb +++ b/tutorials/regression-tribuo-v4.ipynb @@ -23,10 +23,10 @@ "metadata": {}, "outputs": [], "source": [ - "%jars ./tribuo-json-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-regression-sgd-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-regression-xgboost-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-regression-tree-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars ./tribuo-json-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-regression-sgd-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-regression-xgboost-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-regression-tree-4.3.0-jar-with-dependencies.jar" ] }, { @@ -264,7 +264,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training Linear Regression (SGD) took (00:00:00:070)\n", + "Training Linear Regression (SGD) took (00:00:00:051)\n", "Evaluation (train):\n", " RMSE 0.979522\n", " MAE 0.741870\n", @@ -357,7 +357,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training Linear Regression (AdaGrad) took (00:00:00:041)\n", + "Training Linear Regression (AdaGrad) took (00:00:00:024)\n", "Evaluation (train):\n", " RMSE 0.735311\n", " MAE 0.575096\n", @@ -403,7 +403,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training CART took (00:00:00:071)\n", + "Training CART took (00:00:00:092)\n", "Evaluation (train):\n", " RMSE 0.544516\n", " MAE 0.405062\n", @@ -436,7 +436,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Training XGBoost took (00:00:00:263)\n", + "Training XGBoost took (00:00:00:194)\n", "Evaluation (train):\n", " RMSE 0.143871\n", " MAE 0.097167\n", @@ -477,7 +477,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "17+35-LTS-2724" + "version": "12+33" } }, "nbformat": 4, diff --git a/tutorials/reproducibility-tribuo-v4.ipynb b/tutorials/reproducibility-tribuo-v4.ipynb index 481868ecf..e86544fdd 100644 --- a/tutorials/reproducibility-tribuo-v4.ipynb +++ b/tutorials/reproducibility-tribuo-v4.ipynb @@ -21,10 +21,10 @@ "metadata": {}, "outputs": [], "source": [ - "%jars ./tribuo-classification-experiments-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-onnx-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-json-4.3.0-SNAPSHOT-jar-with-dependencies.jar\n", - "%jars ./tribuo-reproducibility-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars ./tribuo-classification-experiments-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-onnx-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-json-4.3.0-jar-with-dependencies.jar\n", + "%jars ./tribuo-reproducibility-4.3.0-jar-with-dependencies.jar" ] }, { @@ -68,7 +68,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "linear-sgd-model - Model(class-name=org.tribuo.classification.sgd.linear.LinearSGDModel,dataset=Dataset(class-name=org.tribuo.MutableDataset,datasource=SplitDataSourceProvenance(className=org.tribuo.evaluation.TrainTestSplitter,innerSourceProvenance=DataSource(class-name=org.tribuo.data.csv.CSVDataSource,headers=[sepalLength, sepalWidth, petalLength, petalWidth, species],rowProcessor=RowProcessor(class-name=org.tribuo.data.columnar.RowProcessor,metadataExtractors=[],fieldProcessorList=[FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=petalLength,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor), FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=petalWidth,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor), FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=sepalWidth,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor), FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=sepalLength,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor)],featureProcessors=[],responseProcessor=ResponseProcessor(class-name=org.tribuo.data.columnar.processors.response.FieldResponseProcessor,uppercase=false,fieldNames=[species],defaultValues=[],displayField=false,outputFactory=OutputFactory(class-name=org.tribuo.classification.LabelFactory),host-short-name=ResponseProcessor),weightExtractor=null,replaceNewlinesWithSpaces=true,regexMappingProcessors={},host-short-name=RowProcessor),quote=\",outputRequired=true,outputFactory=OutputFactory(class-name=org.tribuo.classification.LabelFactory),separator=,,dataPath=/Users/apocock/Development/Tribuo/tutorials/bezdekIris.data,resource-hash=SHA-256[0FED2A99DB77EC533A62DC66894D3EC6DF3B58B6A8F3CF4A6B47E4086B7F97DC],file-modified-time=1999-12-14T15:12:39-05:00,datasource-creation-time=2021-12-18T20:31:02.286464-05:00,host-short-name=DataSource),trainProportion=0.7,seed=1,size=150,isTrain=true),transformations=[],is-sequence=false,is-dense=true,num-examples=105,num-features=4,num-outputs=3,tribuo-version=4.2.0),trainer=Trainer(class-name=org.tribuo.classification.sgd.linear.LogisticRegressionTrainer,seed=12345,minibatchSize=1,shuffle=true,epochs=5,optimiser=StochasticGradientOptimiser(class-name=org.tribuo.math.optimisers.AdaGrad,epsilon=0.1,initialLearningRate=1.0,initialValue=0.0,host-short-name=StochasticGradientOptimiser),loggingInterval=1000,objective=LabelObjective(class-name=org.tribuo.classification.sgd.objectives.LogMulticlass,host-short-name=LabelObjective),tribuo-version=4.2.0,train-invocation-count=0,is-sequence=false,host-short-name=Trainer),trained-at=2021-12-18T20:31:02.707624-05:00,instance-values={},tribuo-version=4.2.0,java-version=17.0.1,os-name=Mac OS X,os-arch=x86_64)\n" + "linear-sgd-model - Model(class-name=org.tribuo.classification.sgd.linear.LinearSGDModel,dataset=Dataset(class-name=org.tribuo.MutableDataset,datasource=SplitDataSourceProvenance(className=org.tribuo.evaluation.TrainTestSplitter,innerSourceProvenance=DataSource(class-name=org.tribuo.data.csv.CSVDataSource,headers=[sepalLength, sepalWidth, petalLength, petalWidth, species],rowProcessor=RowProcessor(class-name=org.tribuo.data.columnar.RowProcessor,metadataExtractors=[],fieldProcessorList=[FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=petalLength,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor), FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=petalWidth,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor), FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=sepalWidth,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor), FieldProcessor(class-name=org.tribuo.data.columnar.processors.field.DoubleFieldProcessor,fieldName=sepalLength,onlyFieldName=true,throwOnInvalid=true,host-short-name=FieldProcessor)],featureProcessors=[],responseProcessor=ResponseProcessor(class-name=org.tribuo.data.columnar.processors.response.FieldResponseProcessor,uppercase=false,fieldNames=[species],defaultValues=[],displayField=false,outputFactory=OutputFactory(class-name=org.tribuo.classification.LabelFactory),host-short-name=ResponseProcessor),weightExtractor=null,replaceNewlinesWithSpaces=true,regexMappingProcessors={},host-short-name=RowProcessor),quote=\",outputRequired=true,outputFactory=OutputFactory(class-name=org.tribuo.classification.LabelFactory),separator=,,dataPath=/local/ExternalRepositories/tribuo/tutorials/bezdekIris.data,resource-hash=SHA-256[0FED2A99DB77EC533A62DC66894D3EC6DF3B58B6A8F3CF4A6B47E4086B7F97DC],file-modified-time=1999-12-14T15:12:39-05:00,datasource-creation-time=2022-10-07T11:20:06.279351-04:00,host-short-name=DataSource),trainProportion=0.7,seed=1,size=150,isTrain=true),transformations=[],is-sequence=false,is-dense=true,num-examples=105,num-features=4,num-outputs=3,tribuo-version=4.3.0),trainer=Trainer(class-name=org.tribuo.classification.sgd.linear.LogisticRegressionTrainer,seed=12345,minibatchSize=1,shuffle=true,epochs=5,optimiser=StochasticGradientOptimiser(class-name=org.tribuo.math.optimisers.AdaGrad,epsilon=0.1,initialLearningRate=1.0,initialValue=0.0,host-short-name=StochasticGradientOptimiser),loggingInterval=1000,objective=LabelObjective(class-name=org.tribuo.classification.sgd.objectives.LogMulticlass,host-short-name=LabelObjective),tribuo-version=4.3.0,train-invocation-count=0,is-sequence=false,host-short-name=Trainer),trained-at=2022-10-07T11:20:06.643297-04:00,instance-values={},tribuo-version=4.3.0,java-version=12,os-name=Linux,os-arch=amd64)\n" ] } ], @@ -192,10 +192,10 @@ "\t\t\t\t\t\t\tclass-name = org.tribuo.classification.LabelFactory\n", "\t\t\t\t\t\t)\n", "\t\t\t\t\tseparator = ,\n", - "\t\t\t\t\tdataPath = /Users/apocock/Development/Tribuo/tutorials/bezdekIris.data\n", + "\t\t\t\t\tdataPath = /local/ExternalRepositories/tribuo/tutorials/bezdekIris.data\n", "\t\t\t\t\tresource-hash = 0FED2A99DB77EC533A62DC66894D3EC6DF3B58B6A8F3CF4A6B47E4086B7F97DC\n", "\t\t\t\t\tfile-modified-time = 1999-12-14T15:12:39-05:00\n", - "\t\t\t\t\tdatasource-creation-time = 2021-12-18T20:38:43.398834-05:00\n", + "\t\t\t\t\tdatasource-creation-time = 2022-10-07T12:03:48.921236415-04:00\n", "\t\t\t\t\thost-short-name = DataSource\n", "\t\t\t\t)\n", "\t\t\ttrain-proportion = 0.7\n", @@ -209,7 +209,7 @@ "\tnum-examples = 105\n", "\tnum-features = 4\n", "\tnum-outputs = 3\n", - "\ttribuo-version = 4.2.0\n", + "\ttribuo-version = 4.3.0\n", ")\n" ] } @@ -254,7 +254,7 @@ "\t\t\tclass-name = org.tribuo.classification.sgd.objectives.LogMulticlass\n", "\t\t\thost-short-name = LabelObjective\n", "\t\t)\n", - "\ttribuo-version = 4.2.0\n", + "\ttribuo-version = 4.3.0\n", "\ttrain-invocation-count = 0\n", "\tis-sequence = false\n", "\thost-short-name = Trainer\n", @@ -305,15 +305,19 @@ " \"datasource\" : {\n", " \"source\" : {\n", " \"datasource-creation-time\" : {\n", - " \"original\" : \"2021-12-18T20:31:02.286464-05:00\",\n", - " \"reproduced\" : \"2021-12-18T20:38:43.398834-05:00\"\n", + " \"original\" : \"2022-10-07T11:20:06.279351-04:00\",\n", + " \"reproduced\" : \"2022-10-07T12:03:48.921236415-04:00\"\n", " }\n", " }\n", " }\n", " },\n", + " \"java-version\" : {\n", + " \"original\" : \"12\",\n", + " \"reproduced\" : \"17.0.4.1\"\n", + " },\n", " \"trained-at\" : {\n", - " \"original\" : \"2021-12-18T20:31:02.707624-05:00\",\n", - " \"reproduced\" : \"2021-12-18T20:38:43.655448-05:00\"\n", + " \"original\" : \"2022-10-07T11:20:06.643297-04:00\",\n", + " \"reproduced\" : \"2022-10-07T12:03:49.150931420-04:00\"\n", " }\n", "}\n" ] @@ -433,7 +437,7 @@ "\t\t\t\t\toutputFactory = LabelFactory(\n", "\t\t\t\t\t\t\tclass-name = org.tribuo.classification.LabelFactory\n", "\t\t\t\t\t\t)\n", - "\t\t\t\t\tdatasource-creation-time = 2021-12-18T20:38:52.702297-05:00\n", + "\t\t\t\t\tdatasource-creation-time = 2022-10-07T12:03:57.351723125-04:00\n", "\t\t\t\t)\n", "\t\t\ttransformations = List[]\n", "\t\t\tis-sequence = false\n", @@ -441,27 +445,27 @@ "\t\t\tnum-examples = -1\n", "\t\t\tnum-features = 717\n", "\t\t\tnum-outputs = 10\n", - "\t\t\ttribuo-version = 4.2.0\n", + "\t\t\ttribuo-version = 4.3.0\n", "\t\t)\n", "\ttrainer = Trainer(\n", "\t\t\tclass-name = org.tribuo.Trainer\n", - "\t\t\tfileModifiedTime = 2021-12-18T20:36:36.445-05:00\n", - "\t\t\tmodelHash = 06071247AEDE7539B899A2D530508D8E2B43304B8A7884A257368AA2CF1C18ED\n", - "\t\t\tlocation = file:/Users/apocock/Development/Tribuo/tutorials/./fm-mnist.onnx\n", + "\t\t\tfileModifiedTime = 2022-10-07T11:46:10.476-04:00\n", + "\t\t\tmodelHash = 9DD2FABC436FB75BAD6A3E061BE51022A79F140FC491C6CA8B8033253F43CD5F\n", + "\t\t\tlocation = file:/local/ExternalRepositories/tribuo/tutorials/./fm-mnist.onnx\n", "\t\t)\n", - "\ttrained-at = 2021-12-18T20:38:52.700329-05:00\n", + "\ttrained-at = 2022-10-07T12:03:57.349886186-04:00\n", "\tinstance-values = Map{\n", "\t\tmodel-domain=org.tribuo.tutorials.onnxexport.fm\n", "\t\tmodel-graphname=FMClassificationModel\n", - "\t\tmodel-description=factorization-machine-model - Model(class-name=org.tribuo.classification.sgd.fm.FMClassificationModel,dataset=Dataset(class-name=org.tribuo.MutableDataset,datasource=DataSource(class-name=org.tribuo.datasource.IDXDataSource,outputPath=/Users/apocock/Development/Tribuo/tutorials/train-labels-idx1-ubyte.gz,outputFactory=OutputFactory(class-name=org.tribuo.classification.LabelFactory),featuresPath=/Users/apocock/Development/Tribuo/tutorials/train-images-idx3-ubyte.gz,features-file-modified-time=2000-07-21T14:20:24-04:00,output-resource-hash=SHA-256[3552534A0A558BBED6AED32B30C495CCA23D567EC52CAC8BE1A0730E8010255C],datasource-creation-time=2021-12-18T20:36:23.109293-05:00,output-file-modified-time=2000-07-21T14:20:27-04:00,idx-feature-type=UBYTE,features-resource-hash=SHA-256[440FCABF73CC546FA21475E81EA370265605F56BE210A4024D2CA8F203523609],host-short-name=DataSource),transformations=[],is-sequence=false,is-dense=false,num-examples=60000,num-features=717,num-outputs=10,tribuo-version=4.2.0),trainer=Trainer(class-name=org.tribuo.classification.sgd.fm.FMClassificationTrainer,seed=12345,variance=0.1,minibatchSize=1,factorizedDimSize=6,shuffle=true,epochs=5,optimiser=StochasticGradientOptimiser(class-name=org.tribuo.math.optimisers.AdaGrad,epsilon=0.1,initialLearningRate=0.1,initialValue=0.0,host-short-name=StochasticGradientOptimiser),loggingInterval=30000,objective=LabelObjective(class-name=org.tribuo.classification.sgd.objectives.LogMulticlass,host-short-name=LabelObjective),tribuo-version=4.2.0,train-invocation-count=0,is-sequence=false,host-short-name=Trainer),trained-at=2021-12-18T20:36:35.640663-05:00,instance-values={},tribuo-version=4.2.0,java-version=17.0.1,os-name=Mac OS X,os-arch=x86_64)\n", + "\t\tmodel-description=factorization-machine-model - Model(class-name=org.tribuo.classification.sgd.fm.FMClassificationModel,dataset=Dataset(class-name=org.tribuo.MutableDataset,datasource=DataSource(class-name=org.tribuo.datasource.IDXDataSource,outputPath=/local/ExternalRepositories/tribuo/tutorials/train-labels-idx1-ubyte.gz,outputFactory=OutputFactory(class-name=org.tribuo.classification.LabelFactory),featuresPath=/local/ExternalRepositories/tribuo/tutorials/train-images-idx3-ubyte.gz,features-file-modified-time=2000-07-21T14:20:24-04:00,output-resource-hash=SHA-256[3552534A0A558BBED6AED32B30C495CCA23D567EC52CAC8BE1A0730E8010255C],datasource-creation-time=2022-10-07T11:45:53.253680-04:00,output-file-modified-time=2000-07-21T14:20:27-04:00,idx-feature-type=UBYTE,features-resource-hash=SHA-256[440FCABF73CC546FA21475E81EA370265605F56BE210A4024D2CA8F203523609],host-short-name=DataSource),transformations=[],is-sequence=false,is-dense=false,num-examples=60000,num-features=717,num-outputs=10,tribuo-version=4.3.0),trainer=Trainer(class-name=org.tribuo.classification.sgd.fm.FMClassificationTrainer,seed=12345,variance=0.1,minibatchSize=1,factorizedDimSize=6,shuffle=true,epochs=5,optimiser=StochasticGradientOptimiser(class-name=org.tribuo.math.optimisers.AdaGrad,epsilon=0.1,initialLearningRate=0.1,initialValue=0.0,host-short-name=StochasticGradientOptimiser),loggingInterval=30000,objective=LabelObjective(class-name=org.tribuo.classification.sgd.objectives.LogMulticlass,host-short-name=LabelObjective),tribuo-version=4.3.0,train-invocation-count=0,is-sequence=false,host-short-name=Trainer),trained-at=2022-10-07T11:46:09.759423-04:00,instance-values={},tribuo-version=4.3.0,java-version=12,os-name=Linux,os-arch=amd64)\n", "\t\tmodel-producer=Tribuo\n", "\t\tmodel-version=0\n", "\t\tinput-name=input\n", "\t}\n", - "\ttribuo-version = 4.2.0\n", - "\tjava-version = 17.0.1\n", - "\tos-name = Mac OS X\n", - "\tos-arch = x86_64\n", + "\ttribuo-version = 4.3.0\n", + "\tjava-version = 17.0.4.1\n", + "\tos-name = Linux\n", + "\tos-arch = amd64\n", ")\n" ] } @@ -497,11 +501,11 @@ "\t\t\t\t\toutputFactory = LabelFactory(\n", "\t\t\t\t\t\t\tclass-name = org.tribuo.classification.LabelFactory\n", "\t\t\t\t\t\t)\n", - "\t\t\t\t\toutputPath = /Users/apocock/Development/Tribuo/tutorials/train-labels-idx1-ubyte.gz\n", - "\t\t\t\t\tfeaturesPath = /Users/apocock/Development/Tribuo/tutorials/train-images-idx3-ubyte.gz\n", + "\t\t\t\t\toutputPath = /local/ExternalRepositories/tribuo/tutorials/train-labels-idx1-ubyte.gz\n", + "\t\t\t\t\tfeaturesPath = /local/ExternalRepositories/tribuo/tutorials/train-images-idx3-ubyte.gz\n", "\t\t\t\t\tfeatures-file-modified-time = 2000-07-21T14:20:24-04:00\n", "\t\t\t\t\toutput-resource-hash = 3552534A0A558BBED6AED32B30C495CCA23D567EC52CAC8BE1A0730E8010255C\n", - "\t\t\t\t\tdatasource-creation-time = 2021-12-18T20:36:23.109293-05:00\n", + "\t\t\t\t\tdatasource-creation-time = 2022-10-07T11:45:53.253680-04:00\n", "\t\t\t\t\toutput-file-modified-time = 2000-07-21T14:20:27-04:00\n", "\t\t\t\t\tidx-feature-type = UBYTE\n", "\t\t\t\t\tfeatures-resource-hash = 440FCABF73CC546FA21475E81EA370265605F56BE210A4024D2CA8F203523609\n", @@ -513,7 +517,7 @@ "\t\t\tnum-examples = 60000\n", "\t\t\tnum-features = 717\n", "\t\t\tnum-outputs = 10\n", - "\t\t\ttribuo-version = 4.2.0\n", + "\t\t\ttribuo-version = 4.3.0\n", "\t\t)\n", "\ttrainer = FMClassificationTrainer(\n", "\t\t\tclass-name = org.tribuo.classification.sgd.fm.FMClassificationTrainer\n", @@ -535,17 +539,17 @@ "\t\t\t\t\tclass-name = org.tribuo.classification.sgd.objectives.LogMulticlass\n", "\t\t\t\t\thost-short-name = LabelObjective\n", "\t\t\t\t)\n", - "\t\t\ttribuo-version = 4.2.0\n", + "\t\t\ttribuo-version = 4.3.0\n", "\t\t\ttrain-invocation-count = 0\n", "\t\t\tis-sequence = false\n", "\t\t\thost-short-name = Trainer\n", "\t\t)\n", - "\ttrained-at = 2021-12-18T20:36:35.640663-05:00\n", + "\ttrained-at = 2022-10-07T11:46:09.759423-04:00\n", "\tinstance-values = Map{}\n", - "\ttribuo-version = 4.2.0\n", - "\tjava-version = 17.0.1\n", - "\tos-name = Mac OS X\n", - "\tos-arch = x86_64\n", + "\ttribuo-version = 4.3.0\n", + "\tjava-version = 12\n", + "\tos-name = Linux\n", + "\tos-arch = amd64\n", ")\n" ] } @@ -593,14 +597,18 @@ " \"dataset\" : {\n", " \"datasource\" : {\n", " \"datasource-creation-time\" : {\n", - " \"original\" : \"2021-12-18T20:36:23.109293-05:00\",\n", - " \"reproduced\" : \"2021-12-18T20:38:58.740193-05:00\"\n", + " \"original\" : \"2022-10-07T11:45:53.253680-04:00\",\n", + " \"reproduced\" : \"2022-10-07T12:04:03.138366189-04:00\"\n", " }\n", " }\n", " },\n", + " \"java-version\" : {\n", + " \"original\" : \"12\",\n", + " \"reproduced\" : \"17.0.4.1\"\n", + " },\n", " \"trained-at\" : {\n", - " \"original\" : \"2021-12-18T20:36:35.640663-05:00\",\n", - " \"reproduced\" : \"2021-12-18T20:39:09.831081-05:00\"\n", + " \"original\" : \"2022-10-07T11:46:09.759423-04:00\",\n", + " \"reproduced\" : \"2022-10-07T12:04:15.478400652-04:00\"\n", " }\n", "}\n" ] @@ -714,14 +722,18 @@ " \"dataset\" : {\n", " \"datasource\" : {\n", " \"datasource-creation-time\" : {\n", - " \"original\" : \"2021-12-18T20:36:23.109293-05:00\",\n", - " \"reproduced\" : \"2021-12-18T20:38:51.027212-05:00\"\n", + " \"original\" : \"2022-10-07T11:45:53.253680-04:00\",\n", + " \"reproduced\" : \"2022-10-07T12:03:56.006018468-04:00\"\n", " }\n", " }\n", " },\n", + " \"java-version\" : {\n", + " \"original\" : \"12\",\n", + " \"reproduced\" : \"17.0.4.1\"\n", + " },\n", " \"trained-at\" : {\n", - " \"original\" : \"2021-12-18T20:36:35.640663-05:00\",\n", - " \"reproduced\" : \"2021-12-18T20:39:18.280345-05:00\"\n", + " \"original\" : \"2022-10-07T11:46:09.759423-04:00\",\n", + " \"reproduced\" : \"2022-10-07T12:04:24.453627627-04:00\"\n", " },\n", " \"trainer\" : {\n", " \"class-name\" : {\n", @@ -787,7 +799,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "17+35-LTS-2724" + "version": "17.0.4.1+1-LTS-2" } }, "nbformat": 4, diff --git a/tutorials/tensorflow-tribuo-v4.ipynb b/tutorials/tensorflow-tribuo-v4.ipynb index f79d08693..215b5ee6b 100644 --- a/tutorials/tensorflow-tribuo-v4.ipynb +++ b/tutorials/tensorflow-tribuo-v4.ipynb @@ -41,7 +41,7 @@ "metadata": {}, "outputs": [], "source": [ - "%jars ./tribuo-tensorflow-4.3.0-SNAPSHOT-jar-with-dependencies.jar" + "%jars ./tribuo-tensorflow-4.3.0-jar-with-dependencies.jar" ] }, { @@ -274,7 +274,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Wine quality training took (00:00:01:891)\n" + "Wine quality training took (00:00:02:255)\n" ] } ], @@ -302,9 +302,9 @@ "output_type": "stream", "text": [ "Wine quality evaluation:\n", - " RMSE 0.651441\n", - " MAE 0.510348\n", - " R^2 0.347424\n", + " RMSE 0.649654\n", + " MAE 0.507282\n", + " R^2 0.351000\n", "\n" ] } @@ -394,7 +394,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "MNIST MLP training took (00:01:06:256)\n" + "MNIST MLP training took (00:01:08:593)\n" ] } ], @@ -497,7 +497,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "MNIST CNN training took (00:02:57:331)\n" + "MNIST CNN training took (00:01:59:597)\n" ] } ], @@ -538,32 +538,32 @@ "output_type": "stream", "text": [ "Class n tp fn fp recall prec f1\n", - "0 980 968 12 25 0.988 0.975 0.981\n", - "1 1,135 1,123 12 5 0.989 0.996 0.992\n", - "2 1,032 1,013 19 39 0.982 0.963 0.972\n", - "3 1,010 980 30 12 0.970 0.988 0.979\n", - "4 982 963 19 19 0.981 0.981 0.981\n", - "5 892 873 19 21 0.979 0.977 0.978\n", - "6 958 938 20 17 0.979 0.982 0.981\n", - "7 1,028 998 30 14 0.971 0.986 0.978\n", - "8 974 937 37 31 0.962 0.968 0.965\n", - "9 1,009 988 21 36 0.979 0.965 0.972\n", - "Total 10,000 9,781 219 219\n", - "Accuracy 0.978\n", - "Micro Average 0.978 0.978 0.978\n", - "Macro Average 0.978 0.978 0.978\n", - "Balanced Error Rate 0.022\n", + "0 980 968 12 22 0.988 0.978 0.983\n", + "1 1,135 1,127 8 15 0.993 0.987 0.990\n", + "2 1,032 1,011 21 59 0.980 0.945 0.962\n", + "3 1,010 959 51 14 0.950 0.986 0.967\n", + "4 982 977 5 35 0.995 0.965 0.980\n", + "5 892 877 15 54 0.983 0.942 0.962\n", + "6 958 934 24 9 0.975 0.990 0.983\n", + "7 1,028 981 47 12 0.954 0.988 0.971\n", + "8 974 931 43 29 0.956 0.970 0.963\n", + "9 1,009 969 40 17 0.960 0.983 0.971\n", + "Total 10,000 9,734 266 266\n", + "Accuracy 0.973\n", + "Micro Average 0.973 0.973 0.973\n", + "Macro Average 0.973 0.973 0.973\n", + "Balanced Error Rate 0.027\n", " 0 1 2 3 4 5 6 7 8 9\n", - "0 968 0 0 0 0 0 6 0 5 1\n", - "1 0 1,123 1 3 0 2 1 0 5 0\n", - "2 3 1 1,013 2 2 0 3 2 5 1\n", - "3 1 0 9 980 0 9 0 4 2 5\n", - "4 1 0 1 0 963 0 4 1 3 9\n", - "5 1 2 0 6 0 873 1 1 3 5\n", - "6 10 1 1 1 2 2 938 0 3 0\n", - "7 0 1 13 0 4 0 0 998 4 8\n", - "8 7 0 13 0 0 7 2 1 937 7\n", - "9 2 0 1 0 11 1 0 5 1 988\n", + "0 968 0 3 0 0 0 2 2 4 1\n", + "1 0 1,127 3 0 1 1 1 0 1 1\n", + "2 3 2 1,011 5 5 0 1 1 4 0\n", + "3 0 1 14 959 0 28 0 1 5 2\n", + "4 0 0 1 0 977 0 1 0 0 3\n", + "5 1 0 1 4 0 877 3 1 4 1\n", + "6 10 3 1 1 3 5 934 0 1 0\n", + "7 0 2 25 1 9 2 0 981 3 5\n", + "8 8 3 10 1 3 11 1 2 931 4\n", + "9 0 4 1 2 14 7 0 5 7 969\n", "\n" ] } @@ -719,7 +719,7 @@ "mimetype": "text/x-java-source", "name": "Java", "pygments_lexer": "java", - "version": "17+35-LTS-2724" + "version": "17.0.4.1+1-LTS-2" } }, "nbformat": 4,