1. 背景 R语言和Python用于数据分析和数据处理,生成相应的直方图和散点图,需要实现一个展示平台。后端使用Java,分别调用R语言和Python。并将数据和图形返回到前端,表明该平台主要实现了多维数据的特征选择和数据集中协变量偏移的校正。该函数的本质是一个Java调用R语言和Java调用Python的Demo。很简单,别喷了
2. 技术栈
3.Java调用R语言3.1 R语言安装Rserve服务器
在此之前,需要为Java和R做一些准备,首先,用R语言安装Rserve服务器
Java调用R语言时,需要启动Rserve,可以通过CMD命令行/RStudio执行
# 安装Rserve
install.packages("Rserve")
# 载入Rserve
library(Rserve())
# 启动Rserve
Rserve()
使用CMD命令行显示Rserve的启动,这就完成了从Java调用R语言的第一步
3.2 Springboot添加Rsession依赖
添加Rsession依赖后,可以直接调包
com.github.yannrichet
Rsession
1.8.3
3.3 Java 调用 R 常用命令
下面是我需要的Java调用R的一些方式,包括一些比较常用的方法
从Java调用R的基本说明,如何从R中保存和返回图像,如何从R中获取和过滤结果等
/**
* 这里是Java调用R语言,R语言对多维度的数据进行特征选择,并将特征选择的结果返回,写入MySQL
**/
public List<Map> featureSelection(){
RConnection c = null;// RConnection用于和Rserve建立连接
try{
c = new RConncetion();// 建立连接
String RPath = "../featureSelection.R";// R文件的地址
c.assign("path",Rpath);// assign命令是将Rpath添加到R中,命名为path
c.eval("source(path)");// eval命令是执行R命令,这里则是执行source方法根据路径加载R文件
String Dpath = fileMapper.selectFilePath("train",1);// 通过MySQL获取数据集路径
String str = "rfProfile <- fsFunction('"+Dpath+"')";// R命令,执行我的R文件中的方法
c.eval(str);//执行
// 出图,因为是个Demo,图片我就直接存储在了本地,图片以数据集名称命名
String fileName = fileMapper.selectFileName("train", 1);//文件名
String imgPath = "D:/fileAndData/imgs/" + fileName + ".png";// 图片保存路径
c.assign("imgPath",imgPath);
c.eval("png(imgPath)");// 使用R语言的png()方法保存图片
c.assign("mainName",fileName);
c.eval("print(plot(rfProfile,type='b',main=mainName))");// 想要出图一定要套一个print(),不然会是空白
c.eval("dev.off()");// 出图这个也是必不可少,自行百度了解
// 获取特征选择的结果,结果使用String接收,需要通过正则表达式过滤一下我们需要的结果
c.eval("features <- rfProfile$optVariables");
// 获取R的结果使用的是paste()以及capture.output()方法,相当于把输出全捕获过来了
String feature = c.eval("paste(capture.output(features),collapse='\n')").asString();
// 获取重要性得分
c.eval("impt <- varImp(rfProfile)");
String imptScores = c.eval("paste(capture.output(impt$Overall),collapse='\n')").asString();
// 写了个工具类过滤R返回的结果,可以根据你的输出结果去定义
handlerRresults = new HandlerRresults();
List<Map> stringStringMapList = handlerRresults.catchAndHandlerR(feature, imptScores);
fileMapper.deleteFileInfo(-1,"train");//-1 文件已使用
String featsStr = handlerRresults.getFeatsStr(feature);
featMapper.insertFeat(featsStr);
return stringStringMapList;
} catch (RserveException | REXPMismatchException e) {
e.printStackTrace();
} finally {
c.close(); // 一定要这一行!!!用完一定要关!!!
}
return null;
}
调用R的简单Java模板总结,R语言逐行执行,无情的eval()
public void JavaCallRDemo(){
RConnection c = null;
try{
c = new RConnection();
c.assign();//通过Java添加变量至R
c.eval();//Java执行R命令
} catch (RserveException | REXPMismatchException e) {
e.printStackTrace();
} finally {
c.close();
}
}
3.4 Java调用R的特征选择前端demo
我的数据集是 30 维的,结果选择了其中的 5 个(Best trade-off)
此处以表格的形式显示特征及其对应的重要性分数
图片通过Base64转码发送到前端
4 Java 调用 Python4.1 Java 调用 Python 代码部分
Java调用Python,我使用Process类,通过Runtime调用其他进程
runtime可以调用cmd、shell等,这里我以我的项目为例做个小演示
/**
* Java使用Runtime调用python
**/
public String callPy(){
StringBuffer arr = new StringBuffer();// 用于获取结果
String basePath = "d://fileAndData/process/";// demo都是将文件直接存本地了,图方便
// 以下为调用Python时传递的参数
String featName = featMapper.getFeat();
String trainPath = fileMapper.selectFilePath("train",-2);
String ptrainPath = basePath + fileMapper.selectFileName("train",-2);
String ptestPath = basePath + fileMapper.selectFileName("test",-2);
Process proc; //声明一下Process
try{
// 字符串数组保存一下调用命令:1.使用python3 2.调用某个.py文件 3-6.传递的参数
String[] args = new String[]{"python3","../kmm.py",featName,trainPath,ptrainPath,ptestPath};
proc = Runtime.getRuntime().exec(args);// 调用命令,cmd方式
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));// 得到输入流
String line = null;
while((line = in.readLine())!=null){
arr.append(line).append("n");// 写入
}
in.close();
proc.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return arr.toString();
}
因为在我的demo中,Python脚本执行后的结果都是散点图
我的做法是python直接把图保存在本地,python执行完后,调用接口以Base64格式传给前端
后来发现返回的Base64格式图片也可以直接扔到前端,不用这么麻烦
/**
* 这里是一个我用于获取某个文件夹下所有文件,并转为Base64格式的方法
* 因为我文件夹下只会有图片,我Demo也就只做了一个判空校验,直接开干
* Controller层
**/
public List getPyFigsListBase64(HttpServletResponse response){
String pyFilePath = "d://fileAndData/kmmImgs";// 图片本地路径
List res = new ArrayList();
handlerPyresults = new HandlerPyresults();// 写个了工具类
List pyFiles = handlerPyresults.getAllFile(pyFilePath);// 获取所有文件
for(File file : pyFiles) {
byte[] fig = handlerPyresults.file2Byte(file);// file类型转为byte[]类型
String base64str = Base64.encodeBase64String(fig);// byte[]转为base64
String img = "data:image/png;base64," + base64str;// 添加头,告诉前端这是个图片
res.add(img);
}
return res;
}
/**
* file转byte[]
**/
public byte[] file2Byte(File file){
if(file == null){
return null;
}
FileInputStream fileInputStream = null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
fileInputStream = new FileInputStream(file);
byteArrayOutputStream = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int n;
while ((n = fileInputStream.read(b))!=-1){
byteArrayOutputStream.write(b,0,n);
}
return byteArrayOutputStream.toByteArray();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInputStream.close();
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
4.2 Java调用Python结果演示
我的python脚本主要对数据集使用KMM算法,这是一种协变量移位校正的方法
通过散点图反映测试集和训练集的分布和差异,这里有点…
5.总结
这个项目是我的导师在我攻读硕士学位期间给我的一个要求。这就是我使用 Java 调用 R 和 Python 的原因。
首先,我使用多个传统机器学习模型在 R 中实现了伽马射线二进制分类任务。
在此之前,R语言用于实现多维数据集的数据预处理、特征选择等功能,而且绘制简单,代码简单。
Python实现了数据集协变量偏移校正的功能,得到的数据集用于丢入模型进行分类。
该平台集成了数据集预处理、调用R和Python的协变量偏移校正方法,可以通过多张图将分析结果可视化。平台还实现了数据集上传、下载等功能……
主要用于记录Java调用R语言和调用Python。其实平台的很多细节都没有考虑,相当于一个学习笔记。
暂无评论内容