PMML简介
预测模型标记语言(PMML) 是一种开放、标准化的语言,用于表示和存储机器学习模型。其主要目的是提供一种跨平台、跨工具的方式来分享和部署预测模型。PMML是由数据挖掘组织(DMG)开发和维护的标准,从最初的版本1.1发展到现在的4.4版本,涵盖了越来越多的模型类型和功能。
历史发展
PMML 1.1(2001年发布):最初版本,支持基本的模型表示。 PMML 4.4(2019年发布):最新版本,支持17种模型类型,并提供组合多模型的挖掘模型(Mining Model)。
应用广泛
PMML得到了广泛的应用,超过30家厂商和开源项目在它们的数据挖掘分析产品中支持并应用PMML。这些厂商包括SAS、IBM SPSS、KNIME、RapidMiner等主流厂商。
PMML标准介绍
PMML是一种基于XML的标准,通过XML Schema定义了使用的元素和属性,主要由以下核心部分组成:
核心部分
- 数据字典(Data Dictionary):描述输入数据的结构和类型。
- 数据转换(Transformation Dictionary和Local Transformations):定义如何将输入数据转换为模型所需的格式。
- 模型定义(Model):每种模型类型都有其特定的定义,包括模型的参数和结构。
- 输出(Output):指定模型的输出结果和格式。
预测过程
PMML预测过程符合数据挖掘分析流程,确保模型在不同平台和环境中具有一致的表现。
PMML优点
- 平台无关性:PMML允许模型在不同的开发和生产环境中跨平台部署。例如,使用Python建立的模型可以导出为PMML,然后在Java生产环境中部署。
- 互操作性:PMML的标准协议使得兼容PMML的预测程序可以读取其他应用导出的标准PMML模型。
- 广泛支持性:超过30家厂商和开源项目支持PMML,许多流行的开源数据挖掘模型都可以转换为PMML。
- 可读性:PMML模型是基于XML的文本文件,可以使用任意文本编辑器打开和查看,比二进制序列化文件更安全可靠。
PMML开源类库
模型转换库
Python模型
- Nyoka:支持Scikit-Learn,LightGBM,XGBoost,Statsmodels和Keras。nyoka-pmml/nyoka
- JPMML系列:例如JPMML-SkLearn、JPMML-XGBoost、JPMML-LightGBM等,提供命令行程序导出模型到PMML。Java PMML API
R模型
- R pmml包:CRAN - Package pmml
- r2pmml:jpmml/r2pmml
- JPMML-R:提供命令行程序导出R模型到PMML。jpmml/jpmml-r
Spark:
- Spark mllib:仅支持模型本身,不支持Pipelines,不推荐使用。
- JPMML-SparkML:支持Spark ML Pipelines。jpmml/jpmml-sparkml
模型评估库
Java:
- JPMML-Evaluator:纯Java的PMML预测库,开源协议是AGPL V3。JPMML-Evaluator
- PMML4S:使用Scala开发,支持Java和Scala,接口简单,开源协议为Apache 2。PMML4S
Python
- PyPMML:Python库用于调用PMML,是PMML4S的Python接口包装。PyPMML
Spark
- JPMML-Evaluator-Spark:JPMML-Evaluator-Spark
- PMML4S-Spark:PMML4S-Spark
PySpark
- PyPMML-Spark:PyPMML-Spark
REST API
- AI-Serving:同时为PMML模型提供REST API和gRPC API,开源协议为Apache 2。AI-Serving
- Openscoring:提供REST API,开源协议为AGPL V3。Openscoring
PMML演示
构建模型要查看完整的Jupyter Notebook,请参考:xgb-iris-pmml.ipynb。
使用Iris数据集构建一个XGBoost模型,并在建模之前对浮点数据进行标准化,利用Scikit-learn中的Pipeline:
代码语言:javascript复制from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
import pandas as pd
from xgboost import XGBClassifier
# 设置随机种子
seed = 123456
# 加载Iris数据集
iris = datasets.load_iris()
target = 'Species'
features = iris.feature_names
iris_df = pd.DataFrame(iris.data, columns=features)
iris_df[target] = iris.target
# 划分训练集和测试集
X, y = iris_df[features], iris_df[target]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=seed)
# 构建Pipeline
pipeline = Pipeline([
('scaling', StandardScaler()),
('xgb', XGBClassifier(n_estimators=5, seed=seed))
])
# 训练模型
pipeline.fit(X_train, y_train)
# 预测
y_pred = pipeline.predict(X_test)
y_pred_proba = pipeline.predict_proba(X_test)
导出PMML使用Nyoka库将Pipeline导出为PMML格式:
代码语言:javascript复制from nyoka import xgboost_to_pmml
# 导出为PMML
xgboost_to_pmml(pipeline, features, target, "xgb-iris.pmml")
验证PMML使用PyPMML库验证PMML预测值是否与原生Python模型一致:
代码语言:javascript复制from pypmml import Model
# 加载PMML模型
model = Model.load("xgb-iris.pmml")
# 进行预测
model.predict(X_test)
使用PMML4S进行预测读取PMML并进行预测。以下代码使用PMML4S的Scala接口,您也可以使用它的Java接口。完整程序请参考:pmml4s-demo.json。
由于GitHub不支持浏览Zeppelin Notebook,可以访问以下链接进行浏览:Zeppelin Notebook。
代码语言:javascript复制import org.pmml4s.model.Model
// 加载PMML模型
val model = Model.fromFile("xgb-iris.pmml")
// 进行预测
val result = model.predict(Map("sepal length (cm)" -> 5.7, "sepal width (cm)" -> 4.4, "petal length (cm)" -> 1.5, "petal width (cm)" -> 0.4))
PMML的缺点
尽管PMML有很多优点,但也存在一些不足之处:
- 数据预处理和后处理支持有限:虽然PMML已经涵盖了几乎所有的标准数据处理方式,但对于用户的一些自定义操作,仍缺乏有效支持,难以将这些操作包含在PMML中。
- 模型类型支持有限:特别是对于深度学习模型的支持较为欠缺。虽然PMML的下一版本(5.0)将添加对深度模型的支持,目前Nyoka可以支持Keras等深度模型,但生成的是扩展的PMML模型。
- 规范标准松散:PMML是一个较为松散的规范标准,不同厂商生成的PMML可能不完全符合标准定义的Schema。此外,PMML规范允许厂商添加自己的扩展,这些都可能对使用这些模型造成一定障碍。
总结
本文介绍了PMML这一跨平台的机器学习模型表示标准,包括其优缺点、常用的PMML开源库,以及如何生成和使用PMML的示例。
尽管PMML存在一些缺点,但其优点远远超过这些不足。如果您训练的模型可以导出为PMML,建议使用PMML来进行部署。如果导出的PMML不能包含整个Pipeline,可以参考文章《自动部署PMML模型生成REST API》中介绍的部署自定义实时预测Web服务的方法。
参考资料:
- Data Mining Group (DMG) 官网: http://dmg.org/
- AutoDeployAI 项目:
- PMML4S
- PyPMML
- AI-Serving
- JPMML 项目: https://github.com/jpmml
- Nyoka 项目: https://github.com/nyoka-pmml/nyoka