Python训练了个模型,怎么交给Java用呢?

2023-11-15

最近碰到几个人问,如何实现 java 调用他们写好的 Python 应用(模型),这里我就把几种常见的办法做下汇总整理。喜欢本文记得收藏、关注、点赞。

【注】文末提供技术交流群

推荐文章

1. 通过命令行调用

如使用 java 的 ProcessBuilder API,

#hello.py
print("Hello ProcessBuilder!")
import java.util.stream.Collectors;
import java.util.List;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.IOException;

public class PyEx0{
    private static List<String> readOutput(InputStream inputStream) throws IOException {
        try (BufferedReader output = new BufferedReader(new InputStreamReader(inputStream))) {
            return output.lines()
                .collect(Collectors.toList());
        }
    }
    public static void main(String[] args) throws Exception {
        ProcessBuilder processBuilder = new ProcessBuilder("python", "hello.py");
        processBuilder.redirectErrorStream(true);
        Process process = processBuilder.start();
        List<String> results = readOutput(process.getInputStream());
        System.out.println(results);
        int exitCode = process.waitFor();
        System.out.println(exitCode);
    }

}

2. 通过 REST API

REST 是表现层状态转换(英语:Representational State Transfer)的英文缩写,是 Roy Thomas Fielding 博士于 2000 年在他的博士论文中提出来的一种万维网软件架构风格,目的是便于不同软件/程序在网络(例如互联网)中互相传递信息。表现层状态转换是根基于超文本传输协议(HTTP)之上而确定的一组约束和属性,是一种设计提供万维网络服务的软件构建风格。符合或兼容于这种架构风格(简称为 REST 或 RESTful)的网络服务,允许客户端发出以统一资源标识符访问和操作网络资源的请求,而与预先定义好的无状态操作集一致化。因此表现层状态转换提供了在互联网络的计算系统之间,彼此资源可交互使用的协作性质(interoperability)。相对于其它种类的网络服务,例如 SOAP 服务,则是以本身所定义的操作集,来访问网络上的资源。

目前在三种主流的 Web 服务实现方案中,因为 REST 模式与复杂的 SOAP 和 XML-RPC 相比更加简洁,越来越多的 Web 服务开始采用 REST 风格设计和实现。例如,Amazon.com 提供接近 REST 风格的 Web 服务执行图书查询;雅虎提供的 Web 服务也是 REST 风格的。

使用你熟悉的 Python 开发框架构建 Restful Server, 我之前介绍过一个 基于 Flask 的,也介绍过一个专门用于部署机器学习框架的,

有兴趣的同学也可以尝试下试下比较流行的 GraphQL,网上关于基于 GraphQL 开发模型 API 的文章也不少。

3. GraphQL

GraphQL 是一个开源的,面向 API 而创造出来的数据查询操作语言以及相应的运行环境。于 2012 年仍处于 Facebook 内部开发阶段,直到 2015 年才公开发布。2018 年 11 月 7 日,Facebook 将 GraphQL 项目转移到新成立的 GraphQL 基金会(隶属于非营利性的 Linux 基金会)。

GraphQL 相较于 REST 以及其他 web service 架构提供了一种更加高效、强大和灵活的开发 web APIs 的方式。它通过由客户端根据所需定义数据结构,同时由服务端负责返回相同数据结构的对应数据的方式避免了服务端大量冗余数据的返回,但与此同时也意味着这种方式不能有效利用起查询结果的 web 缓存。GraphQL 这种查询语言所带来的灵活性和丰富性的同时也增加了复杂性,导致简单的 APIs 有可能并不适合这种方式。

GraphQL 支持数据读取、写入(操作)和数据变更订阅(实时更新)。

主要的 GraphQL 客户端有 Apollo Clien 和 Relay. GraphQL 的服务端在多个语言都有实现包括 Haskell, JavaScript, Python,Ruby, Java, C#, Scala, Go, Elixir, Erlang, PHP, R,和 Clojure.

2018 年 2 月 9 日 GraphQL 的部分模式定义语言(SDL)规范制定完成。

4. PMML

PMML(Predictive Model Markup Language)是预测模型的通用描述语言,简单的说就是用 XML 语法保存模型的一种标准规范,按照这个格式保存模型,其他编程语言也可以加载模型完成预测。

更多 PMML 信息,可以访问 https://github.com/jpmml

5. m2cgen

m2cgen[1], 模型转代码生成器,是一个轻量级库,它提供了一种将经过训练的统计模型转换为本机代码(Python、C、Java、Go、JavaScript、Visual Basic、C#、PowerShell、R、PHP、Dart、 Haskell、Ruby、F#、Rust)。

  • 安装
pip install m2cgen
  • 支持模型

在这里插入图片描述

  • 使用方法

  • 将训练好的模型转为 Java code,只需一行代码(最后一行)

from sklearn.datasets import load_boston
from sklearn import linear_model
import m2cgen as m2c

boston = load_boston()
X, y = boston.data, boston.target

estimator = linear_model.LinearRegression()
estimator.fit(X, y)

code = m2c.export_to_java(estimator)

生成一个 Java 类

public class Model {

    public static double score(double[] input) {
        return (((((((((((((36.45948838508965)
 + ((input[0]) * (-0.10801135783679647)))
 + ((input[1]) * (0.04642045836688297)))
 + ((input[2]) * (0.020558626367073608)))
 + ((input[3]) * (2.6867338193449406)))
 + ((input[4]) * (-17.76661122830004)))
 + ((input[5]) * (3.8098652068092163)))
 + ((input[6]) * (0.0006922246403454562)))
 + ((input[7]) * (-1.475566845600257)))
 + ((input[8]) * (0.30604947898516943)))
 + ((input[9]) * (-0.012334593916574394)))
 + ((input[10]) * (-0.9527472317072884)))
 + ((input[11]) * (0.009311683273794044)))
 + ((input[12]) * (-0.5247583778554867));
    }
}

6. Jython

Jython(原 JPython),是一个用 Java 语言写的 Python 解释器。

Jython 程序可以和 Java 无缝集成。除了一些标准模块,Jython 使用 Java 的模块。Jython 几乎拥有标准的 Python 中不依赖于 C 语言的全部模块。比如,Jython 的用户界面将使用 Swing,AWT 或者 SWT。Jython 可以被动态或静态地编译成 Java 字节码。

Jython 还包括 jythonc,一个将 Python 代码转换成 Java 代码的编译器。这意味着 Python 程序员能够将自己用 Python 代码写的类库用在 Java 程序里。

这东西是不错,但有个致命的问题,不支持 Python3,除非你仍然在使用 Python2,否则没有啥用。

7. GraalVM Python Runtime

GraalVM 提供了一个兼容 Python 3.8 的运行时。GraalVM Python 运行时的主要目标是支持 SciPy 及其组成库,以及与来自丰富 Python 生态系统的其他数据科学和机器学习库一起使用。

官方的数据说:graalpython(企业版) 比 CPython 快 8.92 倍,比 Jython 快 8.34 倍。

python benchmarking

我装的是社区版,没有做过对比测试。

以后我会另外写文章介绍 GraalVM,今天就简单介绍下如何写一个简单的 Python 程序。

  • 安装 GraalVM

目前 GraalVM 提供了 四种平台的预编译版本(对应的 Java 版本有 11 和 17),以及 Docker 的支持。

  • Linux

  • Linux AArch64

  • macOS

  • Windows

  • Docker Container

平台的安装方式都一样,下载解压缩,以 macOS java17 为例,

wget https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.3.0/graalvm-ce-java17-darwin-amd64-21.3.0.tar.gz
tar xf graalvm-ce-java17-darwin-amd64-21.3.0.tar.gz
sudo mv graalvm-ce-java17-21.3.0 /Library/Java/JavaVirtualMachines/
sudo xattr -r -d com.apple.quarantine /Library/Java/JavaVirtualMachines/graalvm-ce-java17-21.3.0/Contents/Home

验证下 所安装的 java 版本和默认的 java 版本,

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (3):
    17.0.1 (x86_64) "GraalVM Community" - "GraalVM CE 21.3.0" /Library/Java/JavaVirtualMachines/graalvm-ce-java17-21.3.0/Contents/Home
    1.8.311.11 (x86_64) "Oracle Corporation" - "Java" /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home
    1.8.0_31 (x86_64) "Oracle Corporation" - "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home
/Library/Java/JavaVirtualMachines/graalvm-ce-java17-21.3.0/Contents/Home
  • 安装 Python
$ gu install python
$ gu install llvm-toolchain
$ graalpython --version
Python 3.8.5 (GraalVM CE Native 21.3.0)
  • 创建虚拟环境以及安装包
$ graalpython -m venv .venv
$ source .venv/bin/activate
#下面这个编译过程有些长
$ graalpython -m ginstall install pandas
$ pip list
Package         Version
--------------- -------
hpy             0.0.3
numpy           1.16.4
pandas          0.25.0
pip             20.1.1
polyglot        16.7.4
python-dateutil 2.7.5
pytz            2018.7
setuptools      47.1.0
setuptools-scm  1.15.0
six             1.12.0

pandas 版本有些低 0.25.0。

  • 例子

python 代码

#hello.py
import pandas as pd

def get_data():
    d = {'col1': [1, 2], 'col2': [3, 4]}
    df = pd.DataFrame(data=d)
    return df

get_data()

java 代码

import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Paths;

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;

public class Pandas {
    private static String PYTHON = "python";
    private static String VENV_EXECUTABLE =Paths.get(".venv", "bin", "graalpython").toString();
    private static String SOURCE_FILE_NAME = "ex.py";
    public static void main(String[] args) throws Exception {
        Context context = Context.newBuilder(PYTHON).
            allowAllAccess(true).
            option("python.Executable", VENV_EXECUTABLE).
            option("python.ForceImportSite", "true").
            build();
        try {
            FileInputStream input = new FileInputStream(SOURCE_FILE_NAME);
            InputStreamReader code = new InputStreamReader(input);
            Source source = Source.newBuilder(PYTHON, code, SOURCE_FILE_NAME).build();
     Value value = context.eval(source);
            System.out.println(value);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

该方案还不够成熟。

参考资料

[1]

m2cgen: https://github.com/BayesWitnesses/m2cgen

技术交流

欢迎转载、收藏、有所收获点赞支持一下!

在这里插入图片描述

目前开通了技术交流群,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友

  • 方式①、发送如下图片至微信,长按识别,后台回复:加群;
  • 方式②、添加微信号:dkl88191,备注:来自CSDN
  • 方式③、微信搜索公众号:Python学习与数据挖掘,后台回复:加群

长按关注

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python训练了个模型,怎么交给Java用呢? 的相关文章

随机推荐

  • 408知识框架总结——计算机网络

    个人复习用 有用自取 欢迎转载 标明出处即可 不推荐在第一遍复习时使用 第一遍建议还是认认真真看书做题 第二遍复习时可以配合框架来过知识点 哪里不熟翻书来强化记忆 重点难点不构成参考建议 仅为个人想法 第一章 计算机网络体系结构 1 1计算
  • 基于若依对接微信jssdk

    基于若依对接微信jssdk java package com ruoyi system controller import com alibaba fastjson2 JSONObject import com ruoyi common c
  • 电脑键盘练习_电脑初学者指法练习的基本知识

    对于电脑初学者来说 打字无疑是最基本的电脑操作 经常有人问笔者 如何才能提升打字的速度 我每次回答的都是让他多玩玩电脑 多打打字 熟能生巧 此外 打字指法也是提高打字速度的最有效训练基础 朋友们在练习的时候一定要使用正确的手指去按按键 下面
  • 文件管理.

    1 touch 创建测试用的空文件修改文件的时间戳记 格式 touch 选项 文件名 2 echo 创建文件并编辑内容 格式 echo 123 gt 111 3 dd转换和拷贝文件 格式 dd if 拿取容量的文件名 of 要创建的文件名
  • 多路查找树——2-3树和2-3-4树

    目录 2 3树定义 2 3树的插入 2 3树的删除 PS 2 3 4树定义 2 3 4树插入 2 3 4树删除 PS 2 3树定义 定义 多路查找树 其中每一个结点都具有两个孩子 称为2结点 或三个孩子 称为3结点 所有叶节点都在树结构的同
  • IBM MQ开发通用方法,包括客户端连接、服务器端连接、发送接受消息

    1 接口方法 IQueueManager java author weiya public interface IQueueManager 发送消息 param b param queueName roseuid 447BE52F01C2
  • cs寄存器 x86 特权模式_segmentation和保护模式(二)

    segmentation和保护模式 一 上文讲到了segment descriptor 把这些descriptors放在一起 在内存里连续分布 就构成了GDT Global Descriptor Table 所以GDT也可以被称为段 描述符
  • 总离差平方和推导公式

    总离差平方和推导
  • 使用股票程序交易系统应该注意哪些问题?

    尽管使用了程序交易系统 但交易者应该明白 交易的主体是人而不是程序交易系统 交易系统不过是贯彻交易者的思想 执行了交易者的指令而已 交易者仍是交易的主体 这一点不因使用了程序交易系统而改变 交易系统有其高峰期和低谷期 交易系统从大类来分可分
  • stream新特性

    package com jeethink system domain public class Employee public Integer age public String name public Integer getAge ret
  • 十几行代码就可以让你的微信小程序挂掉

    mpvue github 地址请参见 是一个使用Vue js 开发小程序的前端框架 框架基于 Vue js核心 mpvue 修改了 Vue js 的runtime 和compiler 实现 使其可以运行在小程序环境中 从而为小程序开发引入了
  • HTML5

    文章目录 前言 滚动长画幅 实现细节 语义化标签 语言的本地化 前言 本文将分析 AirPods Pro 产品介绍使用的技巧与有趣的第三方库 滚动长画幅 这次AirPods Pro 的产品介绍以一个由用户手动进行滚动推进的长画幅组成 这个长
  • day02-HTML5列表/表格/媒体元素/结构元素

    0目录 补充知识点 HTML5列表 HTML5表格 HTML5媒体元素 HTML5结构元素 1 行内元素和块元素 行内元素 不独占一行 例如 a 标签 strong标签 em标签 块级元素 独占一行 例如 p 标签 h1 h6标签 2 HT
  • Python爬虫系列之爬取猫眼电影,没办法出门就补一下往期电影吧

    前言 今天给大家介绍利用Python爬取并简单分析猫眼电影影评 让我们愉快地开始吧 开发工具 Python版本 3 6 4 相关模块 requests模块 pyecharts模块 jieba模块 scipy模块 wordcloud模块 以及
  • 运行Pangolin时提示以下错误: terminate called after throwing an instance of 'std::runtime_error'

    在运行Pangolin时提示以下错误 terminate called after throwing an instance of std runtime error what Pangolin X11 Unable to retrieve
  • 增强现实代码+注释解析(三)

    1 书名 Mastering OpenCV with Practical Computer Vision Projects 2 章节 Chapter 3 Marker less Augmented Reality 3 书中源代码的最新更新可
  • CustomEditor+ScripableObject 简单用法

    写在前面 看了一整天 算是明白了点 记录一下 要是不知道怎么入门可以看一下 希望能帮到您 Ps 本文一律采用c 进行讲解 用途 自定义inspector 监视器 面板 举个例子 你在ScriptableObejct里声明了一个string类
  • Linux安装——VMware + RedHat

    文章目录 1 安装VMware虚拟机 2 安装RedHat红帽系统 2 1 虚拟机设置 2 2 开启虚拟机 3 cannot updata read only repo 3 1 删除自带yum包 3 2 下载centos版本yum包替换 3
  • Mysql 5.7 / 5.8 性能测试

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 转载于 https my oschina net u 582827 blog 1802981
  • Python训练了个模型,怎么交给Java用呢?

    最近碰到几个人问 如何实现 java 调用他们写好的 Python 应用 模型 这里我就把几种常见的办法做下汇总整理 喜欢本文记得收藏 关注 点赞 注 文末提供技术交流群 推荐文章 李宏毅 机器学习 国语课程 2022 来了 有人把吴恩达老