python xgboost代码_模型转代码:XGBoost等模型也能快速转纯C或Java代码

你是否常训练炫酷的机器学习模型,用来分析数据或执行某些新奇的任务?你是否发现你的模型只能在一定开发环境上才能跑起来,很难部署也很难加入其它程序?今天我们将介绍一个炫酷的工具,它可以把构建在 scikit-learn 或XGBoost等库上的 ML 模型直接转化为不需要任何依赖项的 Java/Python/C 源代码。

项目地址:https://github.com/BayesWitnesses/m2cgen/

那么转化为 Java/Python/C 源代码有什么用呢?想象一下如果我们使用 ML 框架(scikit-learn\XGBoost\LightGBM)训练了一个模型,现在我们希望把这个模型做成应用或嵌入到已有的模型中,那么我们肯定需要考虑这些问题:

如果产品环境并没有 Python 运行时怎么办?

如果产品不能通过云服务器进行计算,只能在本地进行怎么办?

ML 模型的推断速度太慢又怎么办?

这些问题都很难解决,也是开发者在做自己项目时常遇到的问题。如果我们能将用 Python 和 ML 库构建的模型转换一下,变成纯 Java 或 C 写的代码,且这些代码不会依赖各种库,那么部署或嵌入不就简单了么。在 m2cgen 这个项目中,它就可以将 ML 模型转化为不带有依赖项的纯代码。

m2cgen(Model 2 Code Generator)是一个轻量级的 Python 库,它能快速便捷地将已训练统计模型转化为 Python、C 和 Java 代码。目前 m2cgen 已经支持各种分类模型与回归模型,包括 支持向量机 、 决策树 、 随机森林 和梯度提升树等,注意这些都是统计机器学习模型,深度神经网络还是老老实实使用 DL 框架吧。

模型转换效果

我们可以通过几个简单案例了解 m2cgen 是如何转换为纯代码的,简单而言即把模型架构和权重显化了。如下所示如果我们简单地训练一个线性回归模型,当然代码看着简单是因为我们直接调用了 scikit-learn 库中的模型。

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)

上面最后一行将 scikit-learn 中的线性回归模型转化为 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));

}

}

如上 return 后面的语句,它就是一个线性回归的表达式,每一个 input[ * ] 都是一种特征,它后面的数值就是训练后的权重。所以整个线性模型有 13 个特征及对应权重,以及另外一个偏置项。

我们还可以找到更多的案例,如果我们用XGBoost训练一个简单的分类模型,我们可以看到转化的代码会大量使用 if-else 大法,不过我们本身也不用维护生成的代码,所以这种结构也没什么关系了。

import numpy as np

def score(input):

if (input[2]) >= (2.5999999):

var0 = -0.0731707439

else:

var0 = 0.142857149

if (input[2]) >= (2.5999999):

var1 = -0.0705206916

else:

var1 = 0.12477719

var2 = np.exp(((0.5) + (var0)) + (var1))

if (input[2]) >= (2.5999999):

if (input[2]) >= (4.85000038):

var3 = -0.0578680299

else:

var3 = 0.132596686

else:

var3 = -0.0714285821

if (input[2]) >= (2.5999999):

if (input[2]) >= (4.85000038):

var4 = -0.0552999191

else:

var4 = 0.116139404

else:

var4 = -0.0687687024

var5 = np.exp(((0.5) + (var3)) + (var4))

if (input[2]) >= (4.85000038):

if (input[3]) >= (1.75):

var6 = 0.142011836

else:

var6 = 0.0405405387

else:

if (input[3]) >= (1.6500001):

var6 = 0.0428571403

else:

var6 = -0.0730659068

if (input[2]) >= (4.85000038):

if (input[3]) >= (1.75):

var7 = 0.124653712

else:

var7 = 0.035562478

else:

if (input[3]) >= (1.6500001):

var7 = 0.0425687581

else:

var7 = -0.0704230517

var8 = np.exp(((0.5) + (var6)) + (var7))

var9 = ((var2) + (var5)) + (var8)

return np.asarray([(var2) / (var9), (var5) / (var9), (var8) / (var9)])

不过上面这种代码也非常合理,本身决策树就可以视为一种 if-else 的规则集合,不同输入特征 input[ * ] 满足不同的条件就能得到不同的值,这些值最后能联合计算分类结果。

项目细节

工具的安装很简单,直接用 pip 就行了:

pip install m2cgen

除了前面那样在代码中调用转换工具,我们还能通过命令行使用序列化的模型目标(pickle protocol)生成代码:

$ m2cgen --language [--indent ]

[--class_name ] [--package_name ]

[--recursion-limit ]

目前项目支持以下分类和回归模型的转换:

20190306192154_61.png

分类模型输出结果:

20190306192154_569.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值