机器学习是python语言的长处,而Java在web开发方面更具有优势,如何通过java来调用python中训练好的模型进行在线的预测呢?在java语言中去调用python构建好的模型主要有三种方法:

  1.在Java语言中,通过python的解释器执行python代码,简单来说就是在java中通过python解释器对象,传入写好的python代码,进行执行,这样的方式运行的效率非常低,而且存在很多python包无法使用的情况,只适合做简单的python代码的运行,并不推荐使用。

  2.通过PMML工具,将在sklearn中训练好的模型生成一个pmml格式的文件,在该文件中,主要包含了模型的一些训练好的参数,以及输入数据的格式和名称等信息。生成了pmml文件之后,在java中导入pmml相关的包,我们就能通过pmml相关的类读取生成的pmml文件,使用其中的方法传入指定的参数就能实现模型的预测,速度快,效果不错。

  3.第二种方法因为模型已经训练好了,无法改变,不能实现在线调参的功能,我们可以通过socket服务来进行python和java之间的网络通信,python提供socket服务,java端将模型的参数通过网络传给python端,python端接受到参数之后,进行模型的训练,训练完成之后,将得到的结果返回给Java端。

  下面给是使用pmml方式调用的步骤:

  1.在python端生成pmml模型文件,下面以logistic回归为例

    x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.85, random_state=1)
model = PMMLPipeline([('LogisticModer', LogisticRegression())])
model.fit(x_train, y_train)
y_hat = model.predict(x_test)
loss = y_hat == y_test
accuracy = np.mean(loss)
print(accuracy)
sklearn2pmml(model, '.\LogisticRegression.pmml', with_repr=True)

  需要加载的包

from sklearn2pmml import sklearn2pmml
from sklearn2pmml.pipeline import PMMLPipeline

  我们使用PMMLPipeline()的管道函数,还可以在管道中加入其它的一些预处理的操作,比如归一化。sklearn2pmml()函数能够将训练好的模型生成pmml文件,下面来看生成的pmml文件是怎样的吧:

  下面,我们建一个JavaWeb工程:

         <dependency>
<groupId>org.jpmml</groupId>
<artifactId>pmml-evaluator</artifactId>
<version>1.4.1</version>
</dependency> <dependency>
<groupId>org.jpmml</groupId>
<artifactId>pmml-evaluator-extension</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>

  在maven中引入相关的依赖,我们将要用到的方法进行封装,制作成一个工具类:

public static PMML getPMMLModel(InputStream inputStream) {
PMML pmml = new PMML();
try {
pmml = org.jpmml.model.PMMLUtil.unmarshal(inputStream);
} catch (SAXException e1) {
e1.printStackTrace();
} catch (JAXBException e2) {
e2.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return pmml;
}
} public static Evaluator loadPmmlAndgetEvaluator(MachineLearnType machineLearnType) { String modefile = getJpmmlModelPath(machineLearnType); //获取模型的pmml文件路径 InputStream inputStream = readPmmlFile(modefile); //根据文件路径返回输入流 PMML pmml = getPMMLModel(inputStream); //根据输入流返回PMML ModelEvaluatorFactory modelEvaluatorFactory = ModelEvaluatorFactory.newInstance(); //获取 ModelEvaluatorFactory Evaluator evaluator = modelEvaluatorFactory.newModelEvaluator(pmml); // 根据 PMML 模型返回 Evaluator 对象 pmml = null; return evaluator;
} public static Map<String, Object> modelPrediction(Evaluator evaluator, Map<String, Object> paramData) {
if (evaluator == null || paramData == null) {
System.out.println("--------------传入对象 evaluator 或 dataMap 为空, 无法进行预测----------------");
return null;
} List<InputField> inputFields = evaluator.getInputFields(); //获取模型的输入域
Map<FieldName, FieldValue> arguments = new LinkedHashMap<>(); for (InputField inputField : inputFields) { //将参数通过模型对应的名称进行添加
FieldName inputFieldName = inputField.getName(); //获取模型中的参数名
Object paramValue = paramData.get(inputFieldName.getValue()); //获取模型参数名对应的参数值
FieldValue fieldValue = inputField.prepare(paramValue); //将参数值填入模型中的参数中
arguments.put(inputFieldName, fieldValue); //存放在map列表中
}
Map<FieldName, ?> results = evaluator.evaluate(arguments);
List<TargetField> targetFields = evaluator.getTargetFields(); Map<String, Object> resultMap = new HashMap<>(); for(TargetField targetField : targetFields) {
FieldName targetFieldName = targetField.getName();
Object targetFieldValue = results.get(targetFieldName);
if (targetFieldValue instanceof Computable) {
Computable computable = (Computable) targetFieldValue;
resultMap.put(targetFieldName.getValue(), computable.getResult());
}else {
resultMap.put(targetFieldName.getValue(), targetFieldValue);
}
}
return resultMap;
}

  上述的方法中,我们将生成的pmml文件读取,得到InputStream对象,调用上述的方法就行了。上面的代码中,MachineLearnType的作用就是获取pmml的路径,我们将要输入的参数放入Map中,进行预测,最后返回预测结果的Map,下面来看Service层的代码,其中MachineLearnType.LOGISTIC_REGRESSION就是根据名称获取pmml文件:

Evaluator evaluator = JPmmlModelUtil.loadPmmlAndgetEvaluator(MachineLearnType.LOGISTIC_REGRESSION);
Map<String , Object> results = JPmmlModelUtil.modelPrediction(evaluator, paramMap);
int result =(int)((double)results.get("y"));

  下面是Controller层的代码:

  /**
* 使用pmml方式对输入的参数进行线性回归预测
*/
@PostMapping("/logispmml")
public ServerResponse<String> IrisLogosPmmlPredict(@RequestParam @Valid double x1,
@RequestParam @Valid double x2,
@RequestParam @Valid double x3,
@RequestParam @Valid double x4) {
logger.info("x1: " + x1 + " x2: " + x2 + " x3:" + x3 + "x4:" + x4);
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("x1", x1);
paramMap.put("x2", x2);
paramMap.put("x3", x3);
paramMap.put("x4", x4);
String result = logisticRegressionService.pridictlogisticpmml(paramMap);
return createBySuccess(result);
}

  我们生成的模型是logistic回归进行鸢尾花数据集的分类,输入的是样本的四个特征,输出是类别0,1,2

int result =(int)((double)results.get("y"));
String irisName = new String();
if(result == 0){
irisName = "Iris-setosa";
}
if(result == 1){
irisName = "Iris-versicolor";
}
if(result == 2){
irisName = "Iris-virginica";
}
return irisName;
}

  我们在service中将预测结果转换为对应的类别,下面使用测试工具进行测试:

  我们就可以在python中将模型构建好,来进行调用啦!

机器学习——Java调用sklearn生成好的Logistic模型进行鸢尾花的预测的更多相关文章

  1. JAVA调用 keytool 生成keystore 和 cer 证书

    keytool是一个Java数据证书的管理工具, keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中在keystore里, 包含两种数据: 密钥实体( ...

  2. java 调用 keytool 生成keystore 和 cer 证书

    keytool是一个Java数据证书的管理工具, keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中在keystore里, 包含两种数据:密钥实体(K ...

  3. java调用wkhtmltopdf生成pdf文件,美观,省事

    最近项目需要导出企业风险报告,文件格式为pdf,于是搜了一大批文章都是什么Jasper Report,iText ,flying sauser ,都尝试了一遍,感觉不是我想要的效果, 需要自己调整好多 ...

  4. windows文本转语音 通过java 调用python 生成exe可执行文件一条龙

    我已记不清 我失败过多少次 ,找过多少资料 ,但是功夫不负有心人 ,还是成功了. 所有资料和需要的语音模块的资料以放置在文章末尾, 有些是引用别人的博客的部分内容, 原文是在有道云笔记,所以没有图,请 ...

  5. java调用matlab生成exe文件

    一.Matlab生成Java Package 1.在MATLAB的Command Window输入deploytool命令,选择Library Compiler. 2.在弹出的窗口选择Java Pac ...

  6. java调用c++生成的动态和静态库时遇到的问题

    java.lang.UnsatisfiedLinkError: no jacob in java.library.path -Djava.library.path 关于java用jni调用 dll动态 ...

  7. [转载]java调用PageOffice生成word

    一.在开发OA办公或与文档相关的Web系统中,难免会遇到动态生成word文档的需求,为了解决工作中遇到导出word文档的需求,前一段时间上网找了一些资料,在word导出这方面有很多工具可以使用,jac ...

  8. [原创]java调用PageOffice生成word

    一.在开发OA办公或与文档相关的Web系统中,难免会遇到动态生成word文档的需求,为了解决工作中遇到导出word文档的需求,前一段时间上网找了一些资料,在word导出这方面有很多工具可以使用,jac ...

  9. java调用jacob生成pdf,word,excel横向

    /* * 传进一个office文件的byte[]以及后缀,生成一个pdf文件的byte[] */ public byte[] jacob_Office2Pdf(byte[] srcFileBytes, ...

随机推荐

  1. JavaScript中Number数字数值浮点运算有误差

    JavaScript浮点运算的一个bug. 比如:7*0.8 JavaScript算出来就是:5.6000000000000005 //调用:numberExcept(arg1,arg2) //返回值 ...

  2. Python--day42--MySQL外键定义及创建

    什么是外键? 外键的创建:constraint 外键名 foregin key ("表1值1",“ 表1值2”) references 表2的名字(“值1”)

  3. H5 存储数据sessionStorage

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. QuartusII 13.0的完美破解

    网络上破解QuartusII 13.0软件的方法都不行,最后经过本人总结测试(独创),最终实现了QuartusII 13.0的破解,破解方法如下: 网上常规操作之后,会得到一个“license.dat ...

  5. linux 在 scull 中使用旗标

    旗标机制给予 scull 一个工具, 可以在存取 scull_dev 数据结构时用来避免竞争情况. 但是正确使用这个工具是我们的责任. 正确使用加锁原语的关键是严密地指定要保护哪个 资源并且确认每个对 ...

  6. POJ 3660 Cow Contest(floyed运用)

    Description N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming con ...

  7. 闲来无事写一个jquery计算器,没有进行封装......

    <!doctype html> <html> <head> <meta charset="utf-8" /> <title&g ...

  8. EJB版本

    1999: ejb version 1.1 -- j2ee 1.22001: ejb version 2.0 -- j2ee 1.32003: ejb version 2.1 -- j2ee 1.42 ...

  9. <mvc:annotation-driven /><context:annotation-config/><context:component-scan/>

    <context:annotation-config/> 隐式地向 Spring容器注册AutowiredAnnotationBeanPostProcessor. RequiredAnno ...

  10. koa2+koa-art-template利用日期管道实现在jat模板中将时间戳转为日期时间

    var sp = require("silly-datetime"); var render = require("koa-art-template"); va ...