Java调用R与Python
作者: 徐静 硕士研究生、算法工程师
兴趣方向:统计机器学习,深度学习,模型的线上化部署、网络爬虫,前端可视化。
个人博客:https://dataxujing.github.io/
1. 为什么我们要Java调用Python或R
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等;Python和R在数据科学中有较高的地位,能够快速的实现特征工程、数据挖掘的建模。因此在生产中可能需要上线一些数据挖掘模型时,此时软件工程师(往往不懂数据科学)使用的工具Java和数据分析师的Python或R会有交集。
模型的线上化部署的方式有很多,比如我们可以把训练的模型转预测模型标记语言(PMML),这样Java就可以直接调用PMML;也可以做成REST API,Java通过API接口与模型进行交互,以上这些R与Python都有成熟的解决办法;最直接的办法莫过于代码与代码的对接(code2code),我们可以通过Java直接调用开发好的R模型或Python模型,完成训练,评价和预测的目的,下面我们会依次展示一个Java调用Python代码的例子和Java调用R的例子。
2.Java调用Python举栗
首先我们知道Python和Java是可以相互调用的,而本节仅举一个Java调用Python的栗子,Java调用Python的方式有很多,比如Jython(不过我不推荐大家使用,Jython版本更新缓慢,很多Python模块并没有包含,在调用的过程中会出现各种问题),我推荐大家使用命令行的方式调用Python代码或脚本,其核心方法为:
java Runtime.getRuntime().exec(args1);
注意这种方式只能接收到python里print的数据。所以如果你需要返回值,可以把返回值打印出来由Java接收就OK了,请后退,我要上代码了:
首先我们要有一个Python脚本文件,比如:
```Python import sys import pandas as pd import numpy as np import sklearn import xgboost import lightgbm import tensorflow as tf import keras
def my_test(str1,str2,str3,str4): return "Python函数运行:java调Python测试:"+str1+str2+str3+str4
if name=="main": print("脚本名:", sys.argv[0])
my_arg = []
for i in range(0, len(sys.argv)):my_arg.append(sys.argv[i])
print("Java传入的参数长度为:"+str(len(my_arg)))result = my_test(my_arg[1],my_arg[2],my_arg[3],my_arg[4])
print(result)
```
其次我们构造一个J2py类用来调用上述Python脚本,并且实现Java数据与Python的交互(动态传参的过程):
```Java import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; import java.util.ArrayList; import java.util.List;
/** * @title J2py.java * @author 作者:XuJing * @date 创建时间:2018年7月13日下午2:39:05 * @version 1.0.0 * @parameter 参数及其意义: * @return 返回值: */
public class J2py {
public static void main(String[] args) {// 需传入的参数String a = "你好", b = "123", c = "徐静", d = "qingdao";System.out.println("Java中动态参数已经初始化,准备传参");// 设置命令行传入参数String[] args1 = new String[] { "python","java\\03_project\\J2py\\src\\my_model.py", a,b, c, d }; //Java数据a,b,c,d传入PythonProcess pr;try {pr = Runtime.getRuntime().exec(args1); //最核心的函数BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream(), "gbk"));String line;List<String> lines = new ArrayList<String>();System.out.println("-----------------------------------------------");while ((line = in.readLine()) != null) {System.out.println(line);lines.add(line); //把Python的print值保存了下来}System.out.println("-------------------------------------------------");in.close();pr.waitFor();} catch (Exception e) {e.printStackTrace();}System.out.println("Java调Python结束");}
} ```
在Eclipse下运行的结果如下:
```powershell
Java中动态参数已经初始化,准备传参
脚本名: java\03project\J2py\src\mymodel.py Java传入的参数长度为:5
Python函数运行:java调Python测试:你好123徐静qingdao
Java调Python结束 ```
OK,成功了,虚线中间的部分就是我Python脚本实现的功能,并且我们实现了Java数据与Python代码的参数传递。注意一点我在Python脚本中导入了部分我们常用到的模块,这种方式Java并没有报错,也就意味着我们均可以通过Java调用这些模块构造的模型,简直是太棒了。
附:我的测试环境是Win7,Python3.6.4,JDK10.0.1,这里需要说明的是我们也可以调用Python的虚拟环境,只是把Python的代码稍作修改就可以实现。
3.Java调用R举栗
R与Java同样可以进行相互调用,实际中很多R包都是由Java完成的,本节重点依然放在Java调用R代码或脚本中,要注意的是Java调用R的方式也有很多,我们本节主要举一个Java通过Rserve调用R代码或脚本的例子,同时实现Python数据与R脚本的交互。翠花,上代码:
首先我们要有一段R脚本,在现实中可能是你用R开发好的模型,等待上线:
```R library(tidyverse) library(ggplot2) library(mlr) library(xgboost) library(tensorflow) library(keras)
getSum <- function(x,y){ m <- x + y print("成功执行了该R函数") return(m) } ```
其次,我们构造一个J2r的Java类,用来调用上面的R脚本,并且实现数据交互和在Java中自动开启Rserve:
```Java import org.rosuda.REngine.REXP; import org.rosuda.REngine.REXPMismatchException; import org.rosuda.REngine.Rserve.RConnection; import org.rosuda.REngine.Rserve.RserveException;
/** * @title J2r2.java * @author 作者:XuJing * @date 创建时间:2018年7月13日下午5:31:12 * @version 1.0.0 * @parameter 参数及其意义: * @return 返回值: */
public class J2r2 {
public static void main(String[] args) {System.out.println(StartRserve.checkLocalRserve());System.out.println("准备开始Java调用R");System.out.println("-----------------------------------------------");RConnection rConnection = null;try {rConnection = new RConnection();rConnection.eval("source('C:/test.R')");} catch (RserveException e) {e.printStackTrace();} // 文件名不能带中文,否则报错:eval failed, request status: error code: 127int a = 2;int b = 3;int c = 4;int sum = 0;try {sum = rConnection.eval("getSum(" + a + "," + b + ")").asInteger();} catch (Exception e) {e.printStackTrace();}System.out.println("the sum = " + sum);rConnection.close();// 调用R代码System.out.println("调用R代码");RConnection rc = null;try {rc = new RConnection();} catch (RserveException e) {e.printStackTrace();}REXP x = null;try {x = rc.eval("library(xgboost);R.version.string");} catch (RserveException e) {e.printStackTrace();}try {System.out.println(x.asString());} catch (REXPMismatchException e) {e.printStackTrace();}rc.close();System.out.println("-----------------------------------------------");System.out.println("回到Java");}
} ```
在Eclipse下运行的结果如下:
```powershell
准备开始Java调用R
the sum = 5 调用R代码
R version 3.4.0 (2017-04-21)
回到Java ```
OK成功。java同时可以调用第三方的R包,执行R脚本传参,并把数据返回给Java,这里要注意的是需要导入Rengine.jar和Rserve.jar两个压缩包,并且如果要实现Java中自动开启Rserve需要在Rserve包中找到Rserve.java源文件进行调用。
附:我的测试环境是Win7,R3.4.0,JDK10.0.1, 特别注意:不建议在Windows系统使用Rserve.
4.小结
通过以上两种简单方式我们就可以非常容易的通过Java调用R和Python封装的数据挖掘模型。实际上这是一种最简单直接的模型线上化部署的办法,在生产中我们要基于硬件和系统要求选择合理的模型线上化部署的办法。同时也可以直接使用Java或C等底层的语言开发自己的模型,减少不同代码间相互调用,提高模型的生产效率和运行速度。
公众号后台回复关键字即可学习
回复 爬虫 爬虫三大案例实战
回复 Python 1小时破冰入门
回复 数据挖掘 R语言入门及数据挖掘
回复 人工智能 三个月入门人工智能
回复 数据分析师 数据分析师成长之路
回复 机器学习 机器学习的商业应用
回复 数据科学 数据科学实战
回复 常用算法 常用数据挖掘算法
Java调用R与Python相关推荐
- centOS6.5中部署java调用h2o中python包环境
centOS6.5中部署java调用h2o中python包环境 升级centOS6.5中的python版本 6.5版本中自带了python2.6.6的环境,但对于使用h2o版本过低,建议升级至3.6或 ...
- JAVA调用R语言之Rserve(二)
之前,我写了一篇文章是java调用R语言之Rserve,但我发现那种方法比较麻烦.后来我发现了一个比较方便的方法,所以今天从又写了一篇博客,来简单说说. 这次我们需要写一个简单的R语言脚本,然后通过运 ...
- JAVA调用R语言之Rserve
为什么要用java调用R? Java作为一个非常流行的编程语言,具有功能强大和简单易用两个特征.Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂 ...
- R语言实战应用精讲50篇(十三)-如何使用JAVA调用R语言,两种语言的完美结合
前言 为什么要用java调用R? Java作为一个非常流行的编程语言,具有功能强大和简单易用两个特征.Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进 ...
- Java调用R脚本的方法总结
0 前言 R是一种非常方便易用的绘图.统计分析.ML算法设计方面的脚本语言.实际中有这样一种场景:算法工程师用R搭建了机器学习算法模型,想用于javaweb之中但是又不想重新用java写一遍算法模型, ...
- java矩阵传递给r_从JAVA调用R得到卡方统计和p值
我在JAVA中有两个4 * 4矩阵,其中一个矩阵包含观察计数和其他预期计数. 我需要一种自动的方法来计算这两个矩阵之间的卡方统计量的p值; 但是,就我所知,JAVA没有这样的功能. 我可以通过将两个矩 ...
- java 调用r语言包传参数_Java与R语言的配置,调用
我是最近才接触到了R语言,所以用起来有很多的问题,之前只是想单纯想用java调用到R语言中的一些东西,没有想到这个事情并不是想象的那么简单的.好了,闲话不多说,下面我来说说我在运用R的时候遇上的问题吧 ...
- Java调用Javascript、Python算法总结
最近项目中经常需要将Javascript或者Python中的算法发布为服务,而发布Tomcat服务则需要在Java中调用这些算法,因此就不免要进行跨语言调用,即在Java程序中调用这些算法. 不管是调 ...
- java调用R 画词云
一直想找个java包画词云,但是网上并没有什么现成方案.在github上用关键词wordcloud搜一下,发现用java开发的没有比较好的开源项目(获得星星都很少,最多也就个位数).但是又想在java ...
- java调用R语言传参数时,RserveException: eval failed Syntax error
首先将执行的source语句如下 source('D:/xxx/xxx/xxx/py/test.R') ,如果有函数,则继续执行如下 myFunc(1,2) //myFunc是R脚本中的方法名,其中参 ...
最新文章
- 推荐搜索系统论文干货集锦
- maven-resources-plugin include 通配符
- SQL Azure十月份更新
- Dijkstrala算法
- 用电脑更新手机ios系统_macOS 11 正式版体验:大更新!苹果把 iOS 风格搬到了电脑上...
- 扫描指定ip的指定端口,识别开放的端口所对应的服务
- H264格式 I帧 P帧 B帧 基础知识
- Unity之物理引擎
- 2008-2019年高等学校科技统计资料汇编
- 传化智联如何拿下第248张第三方支付牌照
- php斗鱼弹幕接口,php实现斗鱼弹幕,一起来欣赏弹幕吧~
- 数据库数据模型(关系型模型与非关系模型的区别)
- 【python】2行代码实现gif动图压缩(pygifsicle)
- 为什么会显示贵州云服务器,为什么云服务器都放在贵州
- solidworks属性管理器_SOLIDWORKS BOM快捷生成第一步 | 完善产品属性
- 2021年Android面试心得,系列教学
- python解决数学问题
- 【java毕业设计】基于java+swing+Eclipse的俄罗斯方块游戏GUI设计与实现(毕业论文+程序源码)——俄罗斯方块游戏
- 一个著名的调度系统是怎么设计的?
- 编程计算1 * 2 * 3+3 * 4 * 5+5 * 6 * 7+...+99 * 100 * 101的值。