Skip to content

Commit

Permalink
Added PyJNIus backend. Fixes #1
Browse files Browse the repository at this point in the history
  • Loading branch information
vruusmann committed Feb 1, 2019
1 parent 608d136 commit 0a8cd48
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 16 deletions.
38 changes: 35 additions & 3 deletions jpmml_evaluator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from py4j.java_collections import JavaMap
from py4j.java_gateway import JavaGateway

import jnius_config
import os
import pkg_resources

Expand All @@ -20,6 +21,25 @@ def newObject(self, className, *args):
def staticInvoke(self, className, methodName, *args):
raise ValueError()

def jnius_configure_classpath(user_classpath = []):
jnius_config.set_classpath(*_classpath(user_classpath))

class PyJNIusBackend(JavaBackend):

def __init__(self):
super(PyJNIusBackend, self).__init__()

def newObject(self, className, *args):
from jnius import autoclass
javaClass = autoclass(className)
return javaClass(*args)

def staticInvoke(self, className, methodName, *args):
from jnius import autoclass
javaClass = autoclass(className)
javaMember = javaClass.__dict__[methodName]
return javaMember(*args)

def launch_gateway(user_classpath = []):
return JavaGateway.launch_gateway(classpath = os.pathsep.join(_classpath(user_classpath)))

Expand Down Expand Up @@ -66,7 +86,7 @@ def getOpType(self):
return self.opType

def _initModelFields(backend, javaModelFields):
return [ModelField(backend, javaModelField) for javaModelField in javaModelFields]
return [ModelField(backend, javaModelFields.get(i)) for i in range(javaModelFields.size())]

class Evaluator(JavaObject):

Expand Down Expand Up @@ -96,10 +116,22 @@ def getOutputFields(self):
def evaluate(self, arguments):
javaArguments = self.backend.newObject("java.util.LinkedHashMap")
for k, v in arguments.items():
javaArguments.put(self.backend.staticInvoke("org.dmg.pmml.FieldName", "create", k), v)
javaFieldName = self.backend.staticInvoke("org.dmg.pmml.FieldName", "create", k)
if isinstance(v, str):
javaObject = self.backend.newObject("java.lang.String", v)
elif isinstance(v, int):
javaObject = self.backend.newObject("java.lang.Integer", v)
elif isinstance(v, float):
javaObject = self.backend.newObject("java.lang.Double", v)
elif isinstance(v, bool):
javaObject = self.backend.newObject("java.lang.Boolean", v)
else:
raise ValueError()
javaArguments.put(javaFieldName, javaObject)
javaResults = self.javaEvaluator.evaluate(javaArguments)
results = self.backend.staticInvoke("org.jpmml.evaluator.EvaluatorUtil", "decode", javaResults)
return results
pyResults = {entry.getKey() : entry.getValue() for entry in results.entrySet().toArray()}
return pyResults

def evaluateAll(self, arguments_df):
argument_records = arguments_df.to_dict(orient = "records")
Expand Down
Binary file not shown.
Binary file not shown.
34 changes: 23 additions & 11 deletions jpmml_evaluator/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
#!/usr/bin/env python

from jpmml_evaluator import Evaluator, LoadingModelEvaluatorBuilder, ModelEvaluatorBuilder, Py4JBackend
from jpmml_evaluator import launch_gateway
from jpmml_evaluator import Evaluator, LoadingModelEvaluatorBuilder, ModelEvaluatorBuilder, PyJNIusBackend, Py4JBackend
from jpmml_evaluator import jnius_configure_classpath, launch_gateway
from unittest import TestCase

import os
import pandas

jnius_configure_classpath()

def _resource(name):
return os.path.join(os.path.dirname(__file__), "resources", name)

class EvaluatorTest(TestCase):

def setUp(self):
self.gateway = launch_gateway()

def tearDown(self):
self.gateway.shutdown()

def test_DecisionTreeIris(self):
backend = Py4JBackend(self.gateway)

def workflow(self, backend):
evaluatorBuilder = LoadingModelEvaluatorBuilder(backend) \
.setLocatable(True) \
.setDefaultVisitorBattery() \
Expand Down Expand Up @@ -65,3 +59,21 @@ def test_DecisionTreeIris(self):
print(results_df.head(5))

self.assertEqual((150, 5), results_df.shape)

class PyJNIusEvaluatorTest(EvaluatorTest):

def test_pyjnius(self):
backend = PyJNIusBackend()
super(PyJNIusEvaluatorTest, self).workflow(backend)

class Py4JEvaluatorTest(EvaluatorTest):

def setUp(self):
self.gateway = launch_gateway()

def tearDown(self):
self.gateway.shutdown()

def test_py4j(self):
backend = Py4JBackend(self.gateway)
super(Py4JEvaluatorTest, self).workflow(backend)
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.jpmml</groupId>
<artifactId>jpmml-evaluator</artifactId>
<version>1.4.6</version>
<version>1.4-SNAPSHOT</version>
</parent>

<groupId>org.jpmml</groupId>
Expand Down
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"jpmml_evaluator.resources" : ["*.jar"]
},
install_requires = [
"py4j"
"Cython",
"py4j",
"pyjnius"
]
)

0 comments on commit 0a8cd48

Please sign in to comment.