机器学习模型部署,常因开发语言或环境的不同,导致系统或应用无法直接使用离线模型,如在模型训练使用Python,而应用使用Java等其他语言开发。而在此状况下,模型部署上线,通常采用Falsk API服务、PMML、MLflow和Mleap等方法。以下将分别介绍Flask API 和PMML模型上线的方法。
1 Flask API服务
Flask 安装:pip install flask
Flask是一个使用 Python 编写的轻量级 Web 应用框架,通过Flask将Sklearn机器学习模型上线,是将Sklarn的模型保存为pkl文件,并在Flask 服务中加载,从而以接口的形式接收数据预测结果。以iris鸢尾花数据集训练模型,并上线部署为例:
(1)Sklearn模型训练并生成pkl文件,脚本如下:
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import MinMaxScaler
from sklearn.externals import joblib
#加载iris数据
iris = load_iris()
x = iris.data
y = iris.target
scaler = MinMaxScaler()
x_sc = scaler.fit_transform(x)
clf = LogisticRegression()
clf.fit(x_sc,y)
# 模型保存
joblib.dump(scaler,'MinMaxScalerModel.pkl')
joblib.dump(clf, 'LogisticRegressionModel.pkl')
(2)在Flask中加载pkl文件,脚本如下:
from flask import Flask,request,jsonify
from sklearn.externals import joblib
app = Flask(__name__)
# /invocation是路由地址,methods是支持http方法,可以分为POST和GET
@app.route('/invocation',methods=["POST"])
def invocation():
# 获得post传过来的数据
data = request.get_json(force=True)
# 加载MinMaxScalerModel和LogisticRegressionModel
scaler = joblib.load('MinMaxScalerModel.pkl')
model = joblib.load('LogisticRegressionModel.pkl')
#数据归一化及预测
sc_data = scaler.transform(data)
pro = model.predict_proba(sc_data)
info = {'result': str(pro)}
return jsonify(info)#返回结果
if __name__ == '__main__':
# host='0.0.0.0'是为了接口能被局域网中其他机器访问,port为端口号
app.run(host='0.0.0.0', port=8080)
根据上述代码,在Flask中加载pkl运行后,http://本机IP:8080/invocation接口即可接收数据并返回预测结果。至此,即可通过该接口,由其他应用或系统调用。测试如下图所示。
服务测试:curl http://本机IP:8080/invocation -X post -d [[1,2,3,4]]
结果:{“result”:"[[0.01766997 0.3667034 0.61562663]]"}
2 PMML
PMML4.4地址:http://dmg.org/pmml/v4-4/GeneralStructure.html
Sklearn2PMML:https://github.com/jpmml/sklearn2pmml
Sklearn2PMML安装:pip install sklearn2pmml
PMML(Predictive Model Markup Language)预测模型标记语言,是一种基于XML来描述和存储机器学习模型的方法。通过XML将机器学习模型的描述,导出为PMML文件。从而在不同系统或应用中应用,起到模型跨平台部署的功能。在Python中Sklearn、Xgboost、LightGBM和Kears等库生成的模型,可通过sklearn2pmml或Nyoka库进行转换。需注意的是,PMML的预测结果与原模型存在较小偏差。
特征名 | 类型 | 缺失填补 | 特征编码 |
---|---|---|---|
sepal length (cm) | 连续型 | 1 | StandardScaler |
sepal width (cm) | 连续型 | 0.5 | MinMaxScaler |
petal length (cm) | 连续型 | 0.6 | None |
petal width (cm) | 连续型 | None | None |
以iris鸢尾花数据集为例,按上表对特征处理的基础上,使用sklearn2pmml生成PMML文件,脚本如下:
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import MinMaxScaler,StandardScaler
from sklearn2pmml import sklearn2pmml
from sklearn_pandas import DataFrameMapper
from sklearn2pmml.decoration import ContinuousDomain
from sklearn2pmml.pipeline import PMMLPipeline
# 加载iris数据
iris = load_iris()
x = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target
# 特征缺失填补和编码
# 离散型特征,('特征名',[CategoricalDomain(……),编码方法])
# 连续型特征,([特征名],[ContinuousDomain(……),编码方法])
mapper = DataFrameMapper([(['sepal length (cm)'], [ContinuousDomain(missing_value_replacement=1, with_data=False),StandardScaler()]),
(['sepal width (cm)'], [ContinuousDomain(missing_value_replacement=0.5, with_data=False),MinMaxScaler()]),
(['petal length (cm)'], [ContinuousDomain(missing_value_replacement=0.6, with_data=False)]),
(['petal width (cm)'], None)])
model = LogisticRegression()
pipeline = PMMLPipeline([("mapper", mapper),("pca", PCA(n_components = 3)), ("classifier", model)])
pipeline.fit(x, y)
sklearn2pmml(pipeline, "LogisticRegressionIris.pmml", with_repr=True)
在PMML生成后,Java可使用开源库jpmml-evaluator对PMML加载使用。