You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ch...@apache.org on 2019/01/11 14:33:44 UTC
[ignite] branch master updated: IGNITE-10810: [ML] Import models
from MLeap
This is an automated email from the ASF dual-hosted git repository.
chief pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new d4fce67 IGNITE-10810: [ML] Import models from MLeap
d4fce67 is described below
commit d4fce67be1daf4d19f1cf35cdc613cdbe50c7a1a
Author: dmitrievanthony <dm...@gmail.com>
AuthorDate: Fri Jan 11 17:33:26 2019 +0300
IGNITE-10810: [ML] Import models from MLeap
This closes #5753
---
examples/pom.xml | 6 +
.../resources/models/mleap/airbnb.model.rf.zip | Bin 0 -> 35932 bytes
.../examples/ml/mleap/MLeapModelParserExample.java | 73 ++++++++++++
.../ignite/examples/ml/mleap/package-info.java | 22 ++++
modules/ml/mleap-model-parser/pom.xml | 51 +++++++++
.../org/apache/ignite/ml/mleap/MLeapModel.java | 122 ++++++++++++++++++++
.../apache/ignite/ml/mleap/MLeapModelParser.java | 123 +++++++++++++++++++++
.../org/apache/ignite/ml/mleap/package-info.java | 22 ++++
.../ignite/ml/mleap/IgniteMLeapTestSuite.java | 30 +++++
.../ignite/ml/mleap/MLeapModelParserTest.java | 68 ++++++++++++
.../test/resources/datasets/scikit-airbnb.rf.zip | Bin 0 -> 216734 bytes
pom.xml | 2 +
12 files changed, 519 insertions(+)
diff --git a/examples/pom.xml b/examples/pom.xml
index 6320a0f..252c972 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -191,6 +191,12 @@
<artifactId>ignite-spark</artifactId>
<version>${project.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-ml-mleap-model-parser</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<build>
diff --git a/examples/src/main/resources/models/mleap/airbnb.model.rf.zip b/examples/src/main/resources/models/mleap/airbnb.model.rf.zip
new file mode 100644
index 0000000..0da815c
Binary files /dev/null and b/examples/src/main/resources/models/mleap/airbnb.model.rf.zip differ
diff --git a/examples/src/main/spark/org/apache/ignite/examples/ml/mleap/MLeapModelParserExample.java b/examples/src/main/spark/org/apache/ignite/examples/ml/mleap/MLeapModelParserExample.java
new file mode 100644
index 0000000..79958dd
--- /dev/null
+++ b/examples/src/main/spark/org/apache/ignite/examples/ml/mleap/MLeapModelParserExample.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.examples.ml.mleap;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.ml.inference.Model;
+import org.apache.ignite.ml.inference.builder.AsyncModelBuilder;
+import org.apache.ignite.ml.inference.builder.IgniteDistributedModelBuilder;
+import org.apache.ignite.ml.inference.reader.FileSystemModelReader;
+import org.apache.ignite.ml.inference.reader.ModelReader;
+import org.apache.ignite.ml.mleap.MLeapModelParser;
+
+/**
+ * This example demonstrates how to import MLeap model and use imported model for distributed inference in Apache
+ * Ignite.
+ */
+public class MLeapModelParserExample {
+ /** Test model resource name. */
+ private static final String TEST_MODEL_RES = "examples/src/main/resources/models/mleap/airbnb.model.rf.zip";
+
+ /** Parser. */
+ private static final MLeapModelParser parser = new MLeapModelParser();
+
+ /** Run example. */
+ public static void main(String... args) throws ExecutionException, InterruptedException {
+ try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
+ File mdlRsrc = IgniteUtils.resolveIgnitePath(TEST_MODEL_RES);
+ if (mdlRsrc == null)
+ throw new IllegalArgumentException("File not found [resource_path=" + TEST_MODEL_RES + "]");
+
+ ModelReader reader = new FileSystemModelReader(mdlRsrc.getPath());
+
+ AsyncModelBuilder mdlBuilder = new IgniteDistributedModelBuilder(ignite, 4, 4);
+
+ try (Model<HashMap<String, Double>, Future<Double>> mdl = mdlBuilder.build(reader, parser)) {
+ HashMap<String, Double> input = new HashMap<>();
+ input.put("bathrooms", 1.0);
+ input.put("bedrooms", 1.0);
+ input.put("security_deposit", 1.0);
+ input.put("cleaning_fee", 1.0);
+ input.put("extra_people", 1.0);
+ input.put("number_of_reviews", 1.0);
+ input.put("square_feet", 1.0);
+ input.put("review_scores_rating", 1.0);
+
+ Future<Double> prediction = mdl.predict(input);
+
+ System.out.println("Predicted price: " + prediction.get());
+ }
+ }
+ }
+}
diff --git a/examples/src/main/spark/org/apache/ignite/examples/ml/mleap/package-info.java b/examples/src/main/spark/org/apache/ignite/examples/ml/mleap/package-info.java
new file mode 100644
index 0000000..698846c
--- /dev/null
+++ b/examples/src/main/spark/org/apache/ignite/examples/ml/mleap/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * <!-- Package description. -->
+ * MLeap model inference examples.
+ */
+package org.apache.ignite.examples.ml.mleap;
\ No newline at end of file
diff --git a/modules/ml/mleap-model-parser/pom.xml b/modules/ml/mleap-model-parser/pom.xml
new file mode 100644
index 0000000..c57ee8b
--- /dev/null
+++ b/modules/ml/mleap-model-parser/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ POM file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>ignite-parent</artifactId>
+ <groupId>org.apache.ignite</groupId>
+ <version>1</version>
+ <relativePath>../../../parent</relativePath>
+ </parent>
+
+ <artifactId>ignite-ml-mleap-model-parser</artifactId>
+ <version>2.8.0-SNAPSHOT</version>
+ <url>http://ignite.apache.org</url>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-ml</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>ml.combust.mleap</groupId>
+ <artifactId>mleap-runtime_2.11</artifactId>
+ <version>0.13.0</version>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/modules/ml/mleap-model-parser/src/main/java/org/apache/ignite/ml/mleap/MLeapModel.java b/modules/ml/mleap-model-parser/src/main/java/org/apache/ignite/ml/mleap/MLeapModel.java
new file mode 100644
index 0000000..2ebd8c0
--- /dev/null
+++ b/modules/ml/mleap-model-parser/src/main/java/org/apache/ignite/ml/mleap/MLeapModel.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.mleap;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import ml.combust.mleap.core.types.ScalarType;
+import ml.combust.mleap.core.types.StructField;
+import ml.combust.mleap.core.types.StructType;
+import ml.combust.mleap.runtime.frame.DefaultLeapFrame;
+import ml.combust.mleap.runtime.frame.Row;
+import ml.combust.mleap.runtime.frame.Transformer;
+import ml.combust.mleap.runtime.javadsl.LeapFrameBuilder;
+import org.apache.ignite.ml.inference.Model;
+import scala.collection.immutable.Set;
+import scala.collection.immutable.Stream;
+import scala.util.Try;
+
+/**
+ * MLeap model imported and wrapped to be compatible with Apache Ignite infrastructure.
+ */
+public class MLeapModel implements Model<HashMap<String, Double>, Double> {
+ /** MLeap model (transformer in terms of MLeap). */
+ private final Transformer transformer;
+
+ /** List of field names. */
+ private final List<String> schema;
+
+ /** Output field name. */
+ private final String outputFieldName;
+
+ /**
+ * Constructs a new instance of MLeap model.
+ *
+ * @param transformer MLpeap model (transformer in terms of MLeap).
+ * @param schema List of field names.
+ * @param outputFieldName Output field name.
+ */
+ public MLeapModel(Transformer transformer, List<String> schema, String outputFieldName) {
+ this.transformer = transformer;
+ this.schema = schema;
+ this.outputFieldName = outputFieldName;
+ }
+
+ // TODO: IGNITE-10834 Add NamedVectors to replace HashMap in Model.
+ /** {@inheritDoc} */
+ @Override public Double predict(HashMap<String, Double> input) {
+ LeapFrameBuilder builder = new LeapFrameBuilder();
+ List<StructField> structFields = new ArrayList<>();
+
+ for (String fieldName : input.keySet())
+ structFields.add(new StructField(fieldName, ScalarType.Double()));
+
+ StructType schema = builder.createSchema(structFields);
+
+ List<Row> rows = new ArrayList<>();
+ rows.add(builder.createRowFromIterable(new ArrayList<>(input.values())));
+
+ DefaultLeapFrame inputFrame = builder.createFrame(schema, rows);
+
+ return predict(inputFrame);
+ }
+
+ /**
+ * Makes a prediction using default column order specified in {@link #schema}.
+ *
+ * @param input Input arguments.
+ * @return Prediction result.
+ */
+ public double predict(Double[] input) {
+ if (input.length != schema.size())
+ throw new IllegalArgumentException("Input size is not equal to schema size");
+
+ Map<String, Double> vec = IntStream.range(0, input.length)
+ .boxed()
+ .collect(Collectors.toMap(schema::get, i -> input[i]));
+
+ return predict(new HashMap<>(vec));
+ }
+
+ /**
+ * Makes a prediction using MLeap API.
+ *
+ * @param inputFrame Input MLeap frame.
+ * @return Prediction result.
+ */
+ public double predict(DefaultLeapFrame inputFrame) {
+ DefaultLeapFrame outputFrame = transformer.transform(inputFrame).get();
+
+ Try<DefaultLeapFrame> resFrame = outputFrame.select(new Set.Set1<>(outputFieldName).toSeq());
+ DefaultLeapFrame frame = resFrame.get();
+
+ Stream<?> stream = (Stream<?>)frame.productElement(1);
+ Row row = (Row)stream.head();
+
+ return (Double)row.get(0);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void close() {
+ transformer.close();
+ }
+}
diff --git a/modules/ml/mleap-model-parser/src/main/java/org/apache/ignite/ml/mleap/MLeapModelParser.java b/modules/ml/mleap-model-parser/src/main/java/org/apache/ignite/ml/mleap/MLeapModelParser.java
new file mode 100644
index 0000000..d3a1d81
--- /dev/null
+++ b/modules/ml/mleap-model-parser/src/main/java/org/apache/ignite/ml/mleap/MLeapModelParser.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.mleap;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import ml.combust.mleap.core.types.ScalarType;
+import ml.combust.mleap.core.types.StructField;
+import ml.combust.mleap.core.types.StructType;
+import ml.combust.mleap.runtime.MleapContext;
+import ml.combust.mleap.runtime.frame.Transformer;
+import ml.combust.mleap.runtime.javadsl.BundleBuilder;
+import ml.combust.mleap.runtime.javadsl.ContextBuilder;
+import ml.combust.mleap.runtime.transformer.PipelineModel;
+import org.apache.ignite.ml.inference.parser.ModelParser;
+import scala.collection.JavaConverters;
+
+/**
+ * MLeap model parser.
+ */
+public class MLeapModelParser implements ModelParser<HashMap<String, Double>, Double, MLeapModel> {
+ /** */
+ private static final long serialVersionUID = -370352744966205715L;
+
+ /** Temporary file prefix. */
+ private static final String TMP_FILE_PREFIX = "mleap_model";
+
+ /** Temporary file postfix. */
+ private static final String TMP_FILE_POSTFIX = ".zip";
+
+ /** {@inheritDoc} */
+ @Override public MLeapModel parse(byte[] mdl) {
+ MleapContext mleapCtx = new ContextBuilder().createMleapContext();
+ BundleBuilder bundleBuilder = new BundleBuilder();
+
+ File file = null;
+ try {
+ file = File.createTempFile(TMP_FILE_PREFIX, TMP_FILE_POSTFIX);
+ try (FileOutputStream fos = new FileOutputStream(file)) {
+ fos.write(mdl);
+ fos.flush();
+ }
+
+ Transformer transformer = bundleBuilder.load(file, mleapCtx).root();
+ PipelineModel pipelineMdl = (PipelineModel)transformer.model();
+
+ List<String> inputSchema = checkAndGetInputSchema(pipelineMdl);
+ String outputSchema = checkAndGetOutputSchema(pipelineMdl);
+
+ return new MLeapModel(transformer, inputSchema, outputSchema);
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ finally {
+ if (file != null)
+ file.delete();
+ }
+ }
+
+ /**
+ * Util method that checks that input schema contains only one double type.
+ *
+ * @param mdl Pipeline model.
+ * @return Name of output field.
+ */
+ private String checkAndGetOutputSchema(PipelineModel mdl) {
+ Transformer lastTransformer = mdl.transformers().last();
+ StructType outputSchema = lastTransformer.outputSchema();
+
+ List<StructField> output = new ArrayList<>(JavaConverters.seqAsJavaListConverter(outputSchema.fields()).asJava());
+
+ if (output.size() != 1)
+ throw new IllegalArgumentException("Parser supports only scalar outputs");
+
+ return output.get(0).name();
+ }
+
+ /**
+ * Util method that checks that output schema contains only double types and returns list of field names.
+ *
+ * @param mdl Pipeline model.
+ * @return List of field names.
+ */
+ private List<String> checkAndGetInputSchema(PipelineModel mdl) {
+ Transformer firstTransformer = mdl.transformers().head();
+ StructType inputSchema = firstTransformer.inputSchema();
+
+ List<StructField> input = new ArrayList<>(JavaConverters.seqAsJavaListConverter(inputSchema.fields()).asJava());
+
+ List<String> schema = new ArrayList<>();
+
+ for (StructField field : input) {
+ String fieldName = field.name();
+
+ schema.add(field.name());
+ if (!ScalarType.Double().base().equals(field.dataType().base()))
+ throw new IllegalArgumentException("Parser supports only double types [name=" +
+ fieldName + ",type=" + field.dataType() + "]");
+ }
+
+ return schema;
+ }
+}
diff --git a/modules/ml/mleap-model-parser/src/main/java/org/apache/ignite/ml/mleap/package-info.java b/modules/ml/mleap-model-parser/src/main/java/org/apache/ignite/ml/mleap/package-info.java
new file mode 100644
index 0000000..bdfe18d
--- /dev/null
+++ b/modules/ml/mleap-model-parser/src/main/java/org/apache/ignite/ml/mleap/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * <!-- Package description. -->
+ * Base package for Mleap model parser.
+ */
+package org.apache.ignite.ml.mleap;
\ No newline at end of file
diff --git a/modules/ml/mleap-model-parser/src/test/java/org/apache/ignite/ml/mleap/IgniteMLeapTestSuite.java b/modules/ml/mleap-model-parser/src/test/java/org/apache/ignite/ml/mleap/IgniteMLeapTestSuite.java
new file mode 100644
index 0000000..109b91d
--- /dev/null
+++ b/modules/ml/mleap-model-parser/src/test/java/org/apache/ignite/ml/mleap/IgniteMLeapTestSuite.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.mleap;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/** Test suite for all module tests. */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ MLeapModelParserTest.class
+})
+public class IgniteMLeapTestSuite {
+ // No-op.
+}
diff --git a/modules/ml/mleap-model-parser/src/test/java/org/apache/ignite/ml/mleap/MLeapModelParserTest.java b/modules/ml/mleap-model-parser/src/test/java/org/apache/ignite/ml/mleap/MLeapModelParserTest.java
new file mode 100644
index 0000000..989c48b
--- /dev/null
+++ b/modules/ml/mleap-model-parser/src/test/java/org/apache/ignite/ml/mleap/MLeapModelParserTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.mleap;
+
+import java.net.URL;
+import java.util.HashMap;
+import org.apache.ignite.ml.inference.builder.SingleModelBuilder;
+import org.apache.ignite.ml.inference.builder.SyncModelBuilder;
+import org.apache.ignite.ml.inference.reader.FileSystemModelReader;
+import org.apache.ignite.ml.inference.reader.ModelReader;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for {@link MLeapModelParser}.
+ */
+public class MLeapModelParserTest {
+ /** Test model resource name. */
+ private static final String TEST_MODEL_RESOURCE = "datasets/scikit-airbnb.rf.zip";
+
+ /** Parser. */
+ private final MLeapModelParser parser = new MLeapModelParser();
+
+ /** Model builder. */
+ private final SyncModelBuilder mdlBuilder = new SingleModelBuilder();
+
+ /** */
+ @Test
+ public void testParseAndPredict() {
+ URL url = MLeapModelParserTest.class.getClassLoader().getResource(TEST_MODEL_RESOURCE);
+ if (url == null)
+ throw new IllegalStateException("File not found [resource_name=" + TEST_MODEL_RESOURCE + "]");
+
+ ModelReader reader = new FileSystemModelReader(url.getPath());
+
+ try (MLeapModel mdl = mdlBuilder.build(reader, parser)) {
+ HashMap<String, Double> input = new HashMap<>();
+ input.put("imp_bathrooms", 1.0);
+ input.put("imp_bedrooms", 1.0);
+ input.put("imp_security_deposit", 1.0);
+ input.put("imp_cleaning_fee", 1.0);
+ input.put("imp_extra_people", 1.0);
+ input.put("imp_number_of_reviews", 1.0);
+ input.put("imp_square_feet", 1.0);
+ input.put("imp_review_scores_rating", 1.0);
+
+ double prediction = mdl.predict(input);
+
+ assertEquals(95.3919, prediction, 1e-5);
+ }
+ }
+}
diff --git a/modules/ml/mleap-model-parser/src/test/resources/datasets/scikit-airbnb.rf.zip b/modules/ml/mleap-model-parser/src/test/resources/datasets/scikit-airbnb.rf.zip
new file mode 100644
index 0000000..e24d3b4
Binary files /dev/null and b/modules/ml/mleap-model-parser/src/test/resources/datasets/scikit-airbnb.rf.zip differ
diff --git a/pom.xml b/pom.xml
index 87dbbf6..f8653f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -118,6 +118,7 @@
<profile>
<id>all-scala</id><!-- used to update project versions and check all modules compilation -->
<modules><!-- sorted alphabetically -->
+ <module>modules/ml/mleap-model-parser</module>
<module>modules/scalar-2.10</module>
<module>modules/scalar</module>
<module>modules/spark</module>
@@ -537,6 +538,7 @@
</activation>
<modules>
+ <module>modules/ml/mleap-model-parser</module>
<module>modules/scalar</module>
<module>modules/spark</module>
<module>modules/visor-console</module>