跨平台机器学习模型交互–PMML简述
问题导读
1.跨语言,跨平台之间的机器学习模型如何共享交互?
2.机器学习模型如何上线?
PMML简介
模型预测标记语言(Predictive Model Markup Language)是由Dr. Robert Lee Grossman 提出的一种基于XML的存储模型的格式标准。
这里的模型是指那些由数据挖掘和机器学习算法生成的预测模型。PMML为不同的数据分析软件或者编程语言,提供了一种轻松共享预测分析模型的方式。它支持常见的模型,比如逻辑回归和前馈神经网络等。
常见的就是,公司的数据分析人员使用的是R,线上的生产的环境是Java,分析人员在R中将模型训练好之后,就可以将模型导出为PMML,然后在Java中导入,实现模型在R与Java之间的共享与快速上线。
PMML的第一个版本 Version 0.7 是在1997年7月发布的。 第二个版本 Version 0.9 在1998年7月发布的。随后的版本由Data Mining Group 组织维护开发。
因为PMML是一个基于XML的格式标准,所有定义都是和XML schema保持一致的。PMML本身也是一个成熟的标准,已经有超过30个组织声明他们的产品支持PMML。
机器学习模型上线过程与PMML的作用
一个机器学习的上线过程,主要包括:分析、特征工程、模型训练、调优、上线。
其中,PMML的便捷性,主要体现在模型上线的过程中。
模型上线是将训练好的模型有效地应用于生产环境的过程。一般而言,生产环境和数据分析人员所使用的环境差距巨大。以我们目前的实践为例,线上DMP是基于Hadoop的,计算框架用的Spark + MR。线下人员建模主要使用的是R、python 中的sklearn库 以及 部分使用keras。(这里需要吐槽下Spark MLlib 库中的优化算法,效率和精度都差sklearn太多了。)
如果没有PMML,因为不同的系统采用不同的方式呈现其计算,模型上线时就必须经历一个漫长的、容易出现错误和误呈现的翻译过程。
此外,还需要对模型结构了解非常深入的工程人员。
比如,将R中的LR迁移至Java中,就需要工程人员根据训练好模型的参数,裸写一个java类。
以最简单的LR为例,就是一个数据表示权重向量,权重向量和参数向量相乘之后求一次激活函数。
但复杂一点的模型,就要求对模型结构了解非常深入的工程人员,严格按照模型的计算逻辑,来编写该类。
有了PMML,就可以从应用程序A到B再到C轻松共享模型,并且在训练完成之后,迅速将模型上线(只需替换模型文件即可)。现在的实践就是,线下分析人员,使用R等训练好一版的模型之后,导出为PMML,在线上只需替换该PMML文件即可。
PMML 基础知识
注:以下内容基于PMML 4.3版本
PMML 包含数据预处理和数据后处理(即模型预测结果的处理)和预测模型本身,见下图:
PMML文件的结构遵从了用于构建预测模型的常用步骤。
文头件:包含了PMML文档的基本信息,例如模型的版权信息,模型的描述,以及生成该文件所用软件的信息(比如软件的名字和版本)。头文件中也会包含该PMML文件的生成时间。
数据字典:包含了模型可能用到的所有字段名。并定义了字段的类型,可以是连续型(continuous)、类别型(categorical)、定序型(ordinal)。和字段值的类型,如String、Double。
数据挖掘模式:数据挖掘模式,可以看做是模型的一个看门人。所有进入模型的数据,必须经过数据挖掘模式。每个模型都包含且只包含一个数据挖掘模式,用于列出该模型使用的数据。数据挖掘模式包含针对特定模型不同的信息,相对的,数据字典中定义则是稳定的,不会随模型变化而变化。数据挖掘模式的主要目的是列出使用模型需要的数据。
数据挖掘模式也定义了每个字段的使用用途(激活、追加、目标)以及针对空值、非法数据的策略。
数据转化:数据转化操作可以用于对进入模型之前的数据进行预处理。类比python sklearn中的DataFrameMapper,以及Spark中特征预处理相关算子。
PMML定义了如下简单的数据转化操作:标准化、离散化、值映射、自定义函数、聚合
模型:包含了模型的定义和结构信息。
输出:定义了模型输出。对于一个分类任务来说,输出可以包括预测类及与所有可能类相关的概率。
目标:定义了应用于模型输出的后处理步骤。对于一个回归任务来说,此步骤支持将输出转变为人们很容易就可以理解的分数(预测结果)。
模型解释:定义了将测试数据传递至模型时获得的性能度量标准(与训练数据相对)。这些度量标准包括字段相关性、混淆矩阵、增益图及接收者操作特征(ROC)曲线图。
模型验证:定义了一个包含输入数据记录和预期模型输出的示例集。这是非常重要的一个步骤,因为在应用程序之间移动模型时,该模型需要通过匹配测试。这样就可以确保,在呈现相同的输入时,新系统可以生成与旧系统同样的输出。如果实际情况是这样的话,一个模型将被认为经过了验证,且随时可用于实践。
实例解析
在这里,我们使用R语言生成一个LR模型。
其中使用了r2pmml工具,使用参见
使用的数据集是经典的iris。可以说是机器学习中入门的helloworld了,感兴趣的可以查看。
R的代码如下
# 二分类实例# 去掉setosa类index <- which(iris$Species == 'setosa')iris <- iris[- index,]training <-iris#抽样方法ind<-sample(2,nrow(training),replace=TRUE,prob=c(0.7,0.3)) #对数据分成两部分,70%训练数据,30%检测数据nrow(training)行数traindata<- training [ind==1,] #训练集testdata<- training [ind==2,]#二项分布族binomial--正态、指数、gamma、逆高斯、Poisson、二项fit <- glm(Species ~.,family=binomial(link='logit'),data=traindata)predict <- predict(fit,type='response',newdata=testdata)real <- testdata$Speciesres <- data.frame(real,predict =ifelse(predict>0.5,'virginca','versicorlor'))table(real,predict =ifelse(predict>0.5,'virginca','versicorlor'))# 存成pmmllibrary("r2pmml")r2pmml(fit,"iris.pmml")生成的PMML文档,有三个子元素
文件头
<Header> <Application name="JPMML-R" version="1.2.20"/> <Timestamp>2018-06-26T12:10:20Z</Timestamp></Header>
表名该PMML文件是用1.2.20版本的JPMML-R生成的。
生成时间为2018-06-26T12:10:20Z
数据字典
<DataDictionary> <DataField name="Species" optype="categorical" dataType="string"> <Value value="versicolor"/> <Value value="virginica"/> </DataField> <DataField name="Sepal.Length" optype="continuous" dataType="double"/> <DataField name="Sepal.Width" optype="continuous" dataType="double"/> <DataField name="Petal.Length" optype="continuous" dataType="double"/> <DataField name="Petal.Width" optype="continuous" dataType="double"/></DataDictionary>
该模型共涉及5个字段,其中Species字段为类别类型,共有两个可能值。 数据集应该是在三个,为了实现,在代码中删除了一个。
其余四个字段分别为连续型,值都是double型的。
模型部分
具体定义</GeneralRegressionModel>模型是一个 普通的线性二分类模型。激活函数式logit。具体内容定义在其子元素中。
数据挖掘模式
<MiningSchema> <MiningField name="Species" usageType="target"/> <MiningField name="Sepal.Length"/> <MiningField name="Sepal.Width"/> <MiningField name="Petal.Length"/> <MiningField name="Petal.Width"/></MiningSchema>
定义了该模型使用到的字段。数据字典中的5个字段都使用了,其中Species是作为结果的。其余都是模型输入
这里是将数据字典中的所有字段都用上了,实际操作过程中,存在数据字典中的部分字段,对最后的结果无影响,在数据挖掘模式中,便不会包括这部分字段。
输出
<Output> <OutputField name="probability(versicolor)" optype="continuous" dataType="double" feature="probability" value="versicolor"/> <OutputField name="probability(virginica)" optype="continuous" dataType="double" feature="probability" value="virginica"/></Output>定义了模型预测结果的输出格式,包括判断为某一分类的概率,是一个连续型,值为double型。
参数部分
<ParamMatrix> <PCell targetCategory="virginica" parameterName="p0" beta="-732.0440201835713"/> <PCell targetCategory="virginica" parameterName="p1" beta="-23.885379989132485"/> <PCell targetCategory="virginica" parameterName="p2" beta="-205.83327893055016"/> <PCell targetCategory="virginica" parameterName="p3" beta="129.4711031033915"/> <PCell targetCategory="virginica" parameterName="p4" beta="494.71600981992856"/></ParamMatrix>
Java中使用
在Java中使用pmml,主要是用到一个开源的包[jpmml]()
先load 模型
PMML pmml;try(InputStream is = ...){ pmml = org.jpmml.model.PMMLUtil.unmarshal(is);}[Java]
Map<FieldName, FieldValue> arguments = new LinkedHashMap<>();List<InputField> inputFields = evaluator.getInputFields();for(InputField inputField : inputFields){ FieldName inputFieldName = inputField.getName(); // The raw (ie. user-supplied) value could be any Java primitive value Object rawValue = ...; // The raw value is passed through: 1) outlier treatment, 2) missing value treatment, 3) invalid value treatment and 4) type conversion FieldValue inputFieldValue = inputField.prepare(rawValue); arguments.put(inputFieldName, inputFieldValue);}[Java]
Map<FieldName, ?> results = evaluator.evaluate(arguments);
PMML主要用于跨平台,跨语言之间的模型共享和交互,对于模型快速上线,具有非常重大的意义。
Reference
时间:2018-08-31 13:26 来源: 转发量:次
声明:本站部分作品是由网友自主投稿和发布、编辑整理上传,对此类作品本站仅提供交流平台,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,不为其版权负责。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。
相关文章:
相关推荐:
网友评论:
















