如何从Java调用scikit learn分类器?
我有一个使用Python的scikit learn训练的分类器。如何使用Java程序中的分类器?我能用Jython吗?有没有办法用Python保存分类器并用Java加载?还有其他方法使用它吗?您不能使用jython,因为scikit learn严重依赖numpy和scipy,它们有许多已编译的C和Fortran扩展,因此无法在jython中工作 在java环境中使用scikit learn的最简单方法是:如何从Java调用scikit learn分类器?,java,python,jython,scikit-learn,Java,Python,Jython,Scikit Learn,我有一个使用Python的scikit learn训练的分类器。如何使用Java程序中的分类器?我能用Jython吗?有没有办法用Python保存分类器并用Java加载?还有其他方法使用它吗?您不能使用jython,因为scikit learn严重依赖numpy和scipy,它们有许多已编译的C和Fortran扩展,因此无法在jython中工作 在java环境中使用scikit learn的最简单方法是: 将分类器公开为HTTP/Json服务,例如使用微框架(如or)并使用HTTP客户端库从j
- 将分类器公开为HTTP/Json服务,例如使用微框架(如or)并使用HTTP客户端库从java调用它
- 用python编写一个命令行包装应用程序,该应用程序读取stdin上的数据,并使用CSV或JSON(或一些较低级别的二进制表示)等格式在stdout上输出预测,并使用java调用python程序
- 让python程序输出在拟合时间学习到的原始数值参数(通常作为浮点值数组),并在java中重新实现预测函数(这对于预测线性模型来说通常很容易,其中预测通常只是一个阈值点积)
这种方法不适用于所有scikit学习模型,但适用于其中的一种。以下是JPMML解决方案的一些代码: --PYTHON部分-- --JAVA部件--
//初始化。
字符串pmmlFile=“ScikitLearnNew.pmml”;
PMML PMML=org.jpmml.model.PMMLUtil.unmarshal(新文件输入流(pmmlFile));
ModelEvaluatorFactory ModelEvaluatorFactory=ModelEvaluatorFactory.newInstance();
MiningModelEvaluator evaluator=(MiningModelEvaluator)modelEvaluatorFactory.newModelEvaluator(pmml);
//确定需要哪些功能作为输入
HashMap()inputFieldMap=新HashMap();
对于(int i=0;i
您可以使用porter,我已经测试了sklearn porter(),它在Java中运行良好
我的代码如下:
import pandas as pd
from sklearn import tree
from sklearn_porter import Porter
train_dataset = pd.read_csv('./result2.csv').as_matrix()
X_train = train_dataset[:90, :8]
Y_train = train_dataset[:90, 8:]
X_test = train_dataset[90:, :8]
Y_test = train_dataset[90:, 8:]
print X_train.shape
print Y_train.shape
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X_train, Y_train)
porter = Porter(clf, language='java')
output = porter.export(embed_data=True)
print(output)
在我的例子中,我使用DecisionTreeClassifier,并且
打印(输出)
以下代码是控制台中的文本:
class DecisionTreeClassifier {
private static int findMax(int[] nums) {
int index = 0;
for (int i = 0; i < nums.length; i++) {
index = nums[i] > nums[index] ? i : index;
}
return index;
}
public static int predict(double[] features) {
int[] classes = new int[2];
if (features[5] <= 51.5) {
if (features[6] <= 21.0) {
// HUGE amount of ifs..........
}
}
return findMax(classes);
}
public static void main(String[] args) {
if (args.length == 8) {
// Features:
double[] features = new double[args.length];
for (int i = 0, l = args.length; i < l; i++) {
features[i] = Double.parseDouble(args[i]);
}
// Prediction:
int prediction = DecisionTreeClassifier.predict(features);
System.out.println(prediction);
}
}
}
类决策树分类程序{
私有静态int findMax(int[]nums){
int指数=0;
对于(int i=0;inums[index]?i:索引;
}
收益指数;
}
公共静态整数预测(双[]特性){
int[]类=新的int[2];
如果(功能[5]我发现自己也处于类似的情况。
我建议创建一个分类器微服务。您可以使用一个在python中运行的分类器微服务,然后通过生成JSON/XML数据交换格式的RESTFul API公开对该服务的调用。我认为这是一种更干净的方法。或者,您可以从经过培训的模型生成python代码。下面是一个hat可以帮你做到这一点我的一位同事刚刚建议使用Jepp…这对这个有用吗?可能我不知道Jepp。它看起来确实适合这个任务。对于web应用程序,我个人更喜欢http暴露方法。@user939259可以为各种应用程序使用分类器池,并更容易地扩展它(根据需求确定池的大小)我只考虑JEPP的桌面应用程序,就像我是一个Python爱好者一样,除非ScIKIT李尔有比WEKA或MaOUT更好的性能,我会选择一种语言解决方案。不止一种语言/框架应该被认为是技术债务。我同意多语言技术债务:在一个团队中很难工作。所有开发人员都懂java和python,而且必须从一种技术文化切换到另一种技术文化,这在项目管理中增加了无用的复杂性。也许这是技术债务——但更进一步地说,在机器学习中,你总是宣布破产,因为你在尝试一些东西,发现它不起作用,然后进行调整它/扔掉它。因此,在这样的情况下,债务可能没有那么大。您如何确保功能转换部分在Python中完成的培训和Java中完成的(使用pmml)之间保持一致为了服务?我尝试了这个,它肯定能将sklearn transformers和xgboost模型转换为Java。但是,由于AGPL许可,我们在生产环境中没有选择这个
import pandas as pd
from sklearn import tree
from sklearn_porter import Porter
train_dataset = pd.read_csv('./result2.csv').as_matrix()
X_train = train_dataset[:90, :8]
Y_train = train_dataset[:90, 8:]
X_test = train_dataset[90:, :8]
Y_test = train_dataset[90:, 8:]
print X_train.shape
print Y_train.shape
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X_train, Y_train)
porter = Porter(clf, language='java')
output = porter.export(embed_data=True)
print(output)
class DecisionTreeClassifier {
private static int findMax(int[] nums) {
int index = 0;
for (int i = 0; i < nums.length; i++) {
index = nums[i] > nums[index] ? i : index;
}
return index;
}
public static int predict(double[] features) {
int[] classes = new int[2];
if (features[5] <= 51.5) {
if (features[6] <= 21.0) {
// HUGE amount of ifs..........
}
}
return findMax(classes);
}
public static void main(String[] args) {
if (args.length == 8) {
// Features:
double[] features = new double[args.length];
for (int i = 0, l = args.length; i < l; i++) {
features[i] = Double.parseDouble(args[i]);
}
// Prediction:
int prediction = DecisionTreeClassifier.predict(features);
System.out.println(prediction);
}
}
}