Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从Java调用scikit learn分类器?_Java_Python_Jython_Scikit Learn - Fatal编程技术网

如何从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

我有一个使用Python的scikit learn训练的分类器。如何使用Java程序中的分类器?我能用Jython吗?有没有办法用Python保存分类器并用Java加载?还有其他方法使用它吗?

您不能使用jython,因为scikit learn严重依赖numpy和scipy,它们有许多已编译的C和Fortran扩展,因此无法在jython中工作

在java环境中使用scikit learn的最简单方法是:

  • 将分类器公开为HTTP/Json服务,例如使用微框架(如or)并使用HTTP客户端库从java调用它

  • 用python编写一个命令行包装应用程序,该应用程序读取stdin上的数据,并使用CSV或JSON(或一些较低级别的二进制表示)等格式在stdout上输出预测,并使用java调用python程序

  • 让python程序输出在拟合时间学习到的原始数值参数(通常作为浮点值数组),并在java中重新实现预测函数(这对于预测线性模型来说通常很容易,其中预测通常只是一个阈值点积)

如果您还需要在Java中重新实现特征提取,那么最后一种方法的工作量将大得多

最后,您可以使用实现所需算法的Java库,如Weka或Mahout,而不是尝试使用scikit从Java学习。

有一个用于此目的的项目

首先,您可以直接从python使用库将scikit学习模型序列化为PMML(内部为XML),或者先将其转储到python中,然后使用java或该库提供的命令行进行转换。接下来,您可以在Java代码中加载pmml文件、反序列化和执行加载的模型


这种方法不适用于所有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);

    }
  }
}