机器学习——Java调用sklearn生成好的Logistic模型进行鸢尾花的预测
机器学习是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模型进行鸢尾花的预测的更多相关文章
- JAVA调用 keytool 生成keystore 和 cer 证书
keytool是一个Java数据证书的管理工具, keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中在keystore里, 包含两种数据: 密钥实体( ...
- java 调用 keytool 生成keystore 和 cer 证书
keytool是一个Java数据证书的管理工具, keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中在keystore里, 包含两种数据:密钥实体(K ...
- java调用wkhtmltopdf生成pdf文件,美观,省事
最近项目需要导出企业风险报告,文件格式为pdf,于是搜了一大批文章都是什么Jasper Report,iText ,flying sauser ,都尝试了一遍,感觉不是我想要的效果, 需要自己调整好多 ...
- windows文本转语音 通过java 调用python 生成exe可执行文件一条龙
我已记不清 我失败过多少次 ,找过多少资料 ,但是功夫不负有心人 ,还是成功了. 所有资料和需要的语音模块的资料以放置在文章末尾, 有些是引用别人的博客的部分内容, 原文是在有道云笔记,所以没有图,请 ...
- java调用matlab生成exe文件
一.Matlab生成Java Package 1.在MATLAB的Command Window输入deploytool命令,选择Library Compiler. 2.在弹出的窗口选择Java Pac ...
- java调用c++生成的动态和静态库时遇到的问题
java.lang.UnsatisfiedLinkError: no jacob in java.library.path -Djava.library.path 关于java用jni调用 dll动态 ...
- [转载]java调用PageOffice生成word
一.在开发OA办公或与文档相关的Web系统中,难免会遇到动态生成word文档的需求,为了解决工作中遇到导出word文档的需求,前一段时间上网找了一些资料,在word导出这方面有很多工具可以使用,jac ...
- [原创]java调用PageOffice生成word
一.在开发OA办公或与文档相关的Web系统中,难免会遇到动态生成word文档的需求,为了解决工作中遇到导出word文档的需求,前一段时间上网找了一些资料,在word导出这方面有很多工具可以使用,jac ...
- java调用jacob生成pdf,word,excel横向
/* * 传进一个office文件的byte[]以及后缀,生成一个pdf文件的byte[] */ public byte[] jacob_Office2Pdf(byte[] srcFileBytes, ...
随机推荐
- iptables在我们的网络机房实现NAT共享上网
工作环境:上层代理192.168.60.6(4480),只授予教师机(192.168.62.111)使用该代理的权限 目标:不使用squid代理上网,而是使用NAT的方式上网 方法: 1) 确保停止教 ...
- H3C Easy IP配置举例
- 前端开发之BOM和DOM
BOM BOM:是指浏览器对象模型,它使JavaScript可以和浏览器进行交互. 1,navigator对象:浏览器对象,通过这个对象可以判定用户所使用的浏览器,包含了浏览器相关信息. naviga ...
- H3C 显示OSPF的链路状态数据库
- P1000 A+B Problem
题目描述 给定两个整数\(a,b\),输出它们的和. 输入格式 输入两个整数,表示\(a,b(1 \le a,b \le 10^9)\). 输出格式 输出一个整数,表示答案. 样例输入 20 30 样 ...
- java 注解(Annotation)
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记. 以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就 ...
- H3C TFTP文件传输过程
- 大众点评实时监控系统CAT的那些坑
首先,感谢大众点评开源监控系统CAT.CAT是一款非常使用的功能建全的监控系统.作为一个知名的开源软件,真的是太差了. 想把CAT用起来,没有多年的Java经验是不行的.先吐槽一下,再写一篇如何用的文 ...
- post提交方式为什么要序列化,而Get提交方式就不用?序列化做了什么?
这是因为后台能够直接处理的数据格式,是一种经过序列化的键值对数据,比如前端要向后台提交三个参数,分别是a=1,b=2,c=3,那么后台接收到的数据就应该是a=1&b=2&c=3(可以看 ...
- Linux 内核 低级 sysfs 操作
kobject 是在 sysfs 虚拟文件系统之后的机制. 对每个在 sysfs 中发现的目录, 有一个 kobject 潜伏在内核某处. 每个感兴趣的 kobject 也输出一个或多个属性, 它出现 ...