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用呢? 的相关文章

  • 在 PyCharm 中运行命令行命令

    你好 我正在使用Python 但之前从未真正使用过它 我收到一些命令 需要在终端中运行 基本上 python Test py GET feeds 我正在使用 PyCharm 我想知道是否有办法从该 IDE 中运行这些相同的命令 按 Alt
  • Pythoncom - 将相同的 COM 对象传递给多个线程

    你好 对于 COM 对象 我是一个完全的初学者 非常感谢任何帮助 我正在开发一个Python程序 该程序应该以客户端 服务器的方式读取传入的MS Word文档 即客户端发送一个请求 一个或多个MS Word文档 服务器使用pythoncom
  • java.lang.ClassNotFoundException: org.jboss.logging.Logger

    我有一个奇怪的问题 我有一个JMS https en wiktionary org wiki JMS客户端应用程序和MDB https en wikipedia org wiki Enterprise JavaBeans Message d
  • 如何使用lxml和python更新xml文件?

  • 不使用 length() 方法的字符串长度[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 如何在不使用字符串的情况下找到字符串的长度length String类的方法 str toCharArray length应该管用 或者怎么
  • 替换 pandas 数据框中的点

    我有一个如图所示的数据框 数字实际上是对象 正在做df treasury rate pd to numeric df treasury rate 可预见的炸弹 然而 做df replace np nan 似乎没有摆脱这个点 所以我很困惑 有
  • 使用 python 写入 aws lambda 中的 /tmp 目录

    Goal 我正在尝试将 zip 文件写入 python aws lambda 中的 tmp 文件夹 因此我可以在压缩之前提取操作 并将其放入 s3 存储桶中 Problem 操作系统 Errno30 只读文件系统 这段代码在我的计算机上进行
  • Mac 上的 Errno 13 权限被拒绝

    我只是测试如何从一个 py 文件调用外部 py 文件 我有 2 个 py 文件 都在同一目录中 这是主要代码 runext py 假设调用 ext py import subprocess subprocess call Users tra
  • Log4j 2.0 中发现 ClassNotFoundException

    我已经设置了 log4j12 api beta2 jar 的构建路径 但它给出了 以下错误请帮我解决这个问题我的代码如下 java 文件 package com sst log4j class Product private int pro
  • pip-tools 的干净设置不会编译非常基本的 pyproject.toml

    使用全新的pip tools设置总是会导致Backend subprocess exited error pyproject toml project dependencies openpyxl gt 3 0 9 lt 4 在仅包含上述 p
  • SQlite 获取最近的位置(带有纬度和经度)

    我的 SQLite 数据库中存储有纬度和经度的数据 我想获取距我输入的参数最近的位置 例如我当前的位置 纬度 经度等 我知道这在 MySQL 中是可能的 并且我已经做了相当多的研究 SQLite 需要一个自定义外部函数来实现半正弦公式 计算
  • Eclipse Juno 指标插件

    Eclipse JUNO 版本有哪些 Eclipse 指标插件 我尝试了一些通用指标插件 但没有一个能够在 Eclipse 的 JUNO 版本中正常运行 差点忘了 我们正在使用 Java 作为编程语言 我想要诸如圈复杂度 代码行数 方法长度
  • gwt 文本框添加更改处理程序

    我有一个从设计师那里收到的文本框 但是我在 GWT 中编写了操作 问题是文本框为空 但是当通过按下按钮用值填充文本框时 将显示警报框 通知值已更改 但没有成功 帮助我 TextBox zip1 null function onModuleL
  • Flask APScheduler + Gunicorn 工作人员 - 在套接字修复后仍在运行任务两次

    我有一个 Flask 应用程序 我使用 Flask APScheduler 在我的数据库上运行计划查询并通过 cron 作业发送电子邮件 我通过 Gunicorn 使用以下配置运行我的应用程序并通过主管进行控制 program myapp
  • 空检查时可能未初始化错误

    我正在检查变量是否已初始化 但此时 netbeans 给了我variable reader might not have been initialized警告 我该如何解决 抑制这个问题 这是我的代码 摘要 final Reader rea
  • 在 servlet 会话和 java.io.NotSerializedException 中保存对象

    SEVERE IOException while loading persisted sessions java io WriteAbortedException writing aborted java io NotSerializabl
  • 有效积累稀疏 scipy 矩阵的集合

    我有一个 O N NxN 的集合scipy sparse csr matrix 每个稀疏矩阵都有 N 个元素集 我想将所有这些矩阵加在一起以获得一个常规的 NxN numpy 数组 N 约为 1000 矩阵内非零元素的排列使得所得总和肯定不
  • 需要在没有wsdl的情况下调用soap ws

    我是网络服务的新手 这个网络服务是由 siebel 提供的 我需要调用一项网络服务 我的客户向我提供了以下详细信息 这是 SOAP 对于产品 请使用它作为端点 Request
  • 将其元素添加到另一个列表后清除列表

    我正在做一个程序 它获取更多句子作为参数 我制作了 2 个列表 一个称为 propozitie 其中包含每个句子 另一个称为 propozitii 其中包含所有句子 问题是 当我在遇到 后清除 propozitie 列表时 它也会清除 pr
  • 无法在 Python 2.4 中解码 unicode 字符串

    这是Python 2 4 中的 这是我的情况 我从数据库中提取一个字符串 它包含一个变音的 o xf6 此时 如果我运行 type value 它会返回 str 然后我尝试运行 decode utf 8 但收到错误 utf8 编解码器无法解

随机推荐

  • 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 来了 有人把吴恩达老