python机器学习模型pkl和pmml文件的保存加载使用

pkl和pmml.png

1.pkl文件和pmml文件简介

python机器学习模型训练完之后可以保存为pkl文件,也可以保存为pmml文件。

那么什么时候保存为pkl文件,什么时候保存为pmml文件呢?

专业点说:模型需要跨平台使用,交由技术部门用java上线运行,需要使用pmml文件。

简单点说:给python开发用就保存为pkl文件,给java开发用就保存为pmml文件。

本章就讲讲机器学习模型pkl和pmml文件的保存加载使用,以及常见的报错和解决方式。

2.pkl文件的保存,加载,使用

机器学习模型保存为pkl文件有两种方式:可以使用joblib包,也可以使用pickle包。

2.1 joblib包和pickle包保存加载pkl区别

joblib包是由scikit-learn外带的,常用于保存机器学习模型。对于大数据而言,joblib比pickle更加高效。

其实实际使用时用joblib包和pickle包没什么差异。重点是:不要混用!!!

用joblib包保存的模型,最好还是用joblib包加载。因为用joblie包保存模型,加载时却用pickle包会报错:invalid load key, '\x00'。所以保存加载模型的时候建议使用同一个包,不要混着用。

接下来就用鸢尾花数据集,具体演示一下使用joblib包和pickle包保存加载pkl模型,以及用加载的pkl模型文件来预测结果。

2.2 使用joblib包保存加载pkl模型文件

2.2.1 joblib保存pkl模型文件joblib.dump()

# 导入并处理鸢尾花数据集import pandas as pdfrom sklearn.datasets import load_iris  iris = load_iris() # 导入鸢尾花数据集df = pd.DataFrame(data=iris.data, columns=[i.replace(' ', '_')for i in iris.feature_names]) # 特征转DataFramedf['target'] = iris.target # 添加目标值df = df[df.target.isin([0, 1 ])] # 取目标值中的0,1类型的数据,用来做二分类算法# 分割数据集,用来训练模型x_train = df.drop('target', axis=1)y_train = df['target']# 使用LGBM训练模型from lightgbm import LGBMClassifiermodel = LGBMClassifier()model.fit(x_train, y_train)# 使用joblib保存模型为pkl文件import joblibjoblib.dump(model, filename='./model_joblib.pkl')

joblib.dump()参数说明: 参数model:要保存的模型(fit训练后的)。

参数filename:要保存的模型路径和名称。

2.2.2 joblib加载pkl模型文件joblib.load()

import joblibmodel = joblib.load(filename='./model_joblib.pkl')

joblib.load()参数说明: 参数filename:要加载的模型路径和名称。

2.3 使用pickle包保存加载pkl模型文件

2.3.1 pickle保存pkl模型文件pickle.dump()

# 导入并处理鸢尾花数据集import pandas as pdfrom sklearn.datasets import load_iris  iris = load_iris() # 导入鸢尾花数据集df = pd.DataFrame(data=iris.data, columns=[i.replace(' ', '_')for i in iris.feature_names]) # 特征转DataFramedf['target'] = iris.target # 添加目标值df = df[df.target.isin([0, 1 ])] # 取目标值中的0,1类型的数据,用来做二分类算法# 分割数据集,用来训练模型x_train = df.drop('target', axis=1)y_train = df['target']# 使用LGBM训练模型from lightgbm import LGBMClassifiermodel = LGBMClassifier()model.fit(x_train, y_train)# 使用pickle保存模型为pkl文件import picklepickle.dump(model, file=open('./model_pickle.pkl', 'wb+'))

pickle.dump()参数说明: 参数model:要保存的模型(fit训练后的)。

参数file:简单点说就是要保存的模型路径和名称外加个open。

2.3.2 pickle加载pkl模型文件pickle.load()

import picklemodel = pickle.load(file=open('./model_pickle.pkl', 'rb'))

pickle.load()参数说明: 参数file:简单点说就是要加载的模型路径和名称外加个open。

2.4 使用pickle包加载joblib包保存的pkl模型文件会报错

让我们来试一下,使用pickle包来加载刚刚用joblib包保存的pkl模型文件会怎样。

果然报错啦,invalid load key, '\x00'。所以joblib包和pickle包最好不要混用。

import picklemodel = pickle.load(file=open('./model_joblib.pkl', 'rb'))---------------------------------------------------------------------------UnpicklingError                           Traceback (most recent call last)<ipython-input-30-1fe488e0924a> in <module>      1 import pickle----> 2 model = pickle.load(file=open('./model_joblib.pkl', 'rb'))UnpicklingError: invalid load key, '\x00'.

2.5 其他加载pkl文件的异常报错

No module named 'sklearn.preprocessing._label'

报错原因:训练模型和加载模型环境的sklearn版本不同。加载模型环境的sklearn的版本太低了。

解决方式:将加载模型环境的sklearn升级,版本>=0.22.X。(安装后重启服务)

pip install scikit-learn==0.22.0

2.6 pkl模型文件加载后预测结果prdict_proba()

pkl模型文件加载后的模型,和建模时训练后的模型是一模一样的,所以建模时怎么预测,加载后就怎么预测。(注:pmml模型文件加载后的模型,预测结果的方式是不同的。)

predict_proba预测结果时,不需要输入变量的名称,但输入的变量顺序必须和模型训练时相同。对比以下两种方式:

# 导入并处理鸢尾花数据集import pandas as pdfrom sklearn.datasets import load_iris  iris = load_iris() # 导入鸢尾花数据集df = pd.DataFrame(data=iris.data, columns=[i.replace(' ', '_')for i in iris.feature_names]) # 特征转DataFramedf['target'] = iris.target # 添加目标值df = df[df.target.isin([0, 1 ])] # 取目标值中的0,1类型的数据,用来做二分类算法# 方式1import joblibmodel = joblib.load(filename='./model_joblib.pkl')feature = model.booster_.feature_name() # 查看模型的入模变量df['predict_proba_pkl1'] = model.predict_proba(df[feature])[:, 1] # 预测结果# 方式2import joblibimport numpy as npmodel = joblib.load(filename='./model_joblib.pkl')feature = model.booster_.feature_name() # 查看模型的入模变量df['predict_proba_pkl2'] = model.predict_proba(np.array(df[feature]))[:, 1] # 预测结果# 方式1:predict_proba的输入是DataFrame,DataFrame的变量顺序和入模变量顺序必须相同# 方式2:predict_proba的输入是二维数组,二维数组中的变量顺序和入模变量顺序必须相同# 总结:predict_proba预测结果时,不需要输入变量的名称,但输入的变量顺序必须和模型训练时相同

3.pmml文件的保存,加载,使用

pmml文件一般是给java开发部署的时候才会用到,如果只是pyhton开发使用,建议使用pkl文件。

机器学习模型保存为pmml文件也有两种方式:

(1)在管道pipeline中进行fit后保存为pmml文件。

(2)直接将pkl文件转为pmml文件。

这两种方式保存的pmml文件结果是不同的,当然加载后使用其预测结果的方式也是不同的。

3.1 方式1:在管道pipeline中进行fit后保存为pmml文件,加载,使用

3.1.1 方式1:保存pmml文件

代码如下,可以看到模型在管道pipeline中进行了fit,然后保存为了pmml文件。

# 导入并处理鸢尾花数据集import pandas as pdfrom sklearn.datasets import load_iris  iris = load_iris() # 导入鸢尾花数据集df = pd.DataFrame(data=iris.data, columns=[i.replace(' ', '_')for i in iris.feature_names]) # 特征转DataFramedf['target'] = iris.target # 添加目标值df = df[df.target.isin([0, 1 ])] # 取目标值中的0,1类型的数据,用来做二分类算法# 分割数据集,用来训练模型x_train = df.drop('target', axis=1)y_train = df['target']# 加载LGBM模型(不需要训练)from lightgbm import LGBMClassifiermodel = LGBMClassifier()# fit后保存为pmml文件from sklearn2pmml import PMMLPipeline, sklearn2pmmlpipeline = PMMLPipeline([('classifier', model)])pipeline.fit(x_train, y_train)sklearn2pmml(pipeline, 'model_fit_to_pmml.pmml', with_repr=True)

让我们打开生成的pmml文件看一下,里面是些什么内容: 可以看到pmml文件中保存了变量的名称。

image.png

<figcaption style="text-align: center; line-height: 1.75; color: rgb(136, 136, 136); font-size: 0.8em;">图片</figcaption>

3.1.2 方式1:加载pmml文件

from pypmml import Modelmodel_pmml = Model.fromFile('model_fit_to_pmml.pmml')model_pmml.inputNames # 查看变量

加载后可以用model_pmml.inputNames来查看入模的变量:输出是具体的入模变量名称。

image.png

<figcaption style="text-align: center; line-height: 1.75; color: rgb(136, 136, 136); font-size: 0.8em;">图片</figcaption>

3.1.3 方式1:使用pmml文件预测结果predict()

上文中,pkl文件预测结果的时候,不需要输入变量的名称,但输入的变量顺序必须和模型训练时相同。

那么使用方式1,保存的pmml文件,加载后预测结果输入应该是什么呢?和pkl文件相同吗?

当然是不同的,不然pmml文件内部为什么要保存变量的名称呢。

使用方式1,保存的pmml文件,预测结果时,需要输入变量的名称,但输入的变量顺序无所谓(可以是一个字典)。代码如下:

df['predict_proba_fit_to_pmml'] = model_pmml.predict(df)['probability(1)']# 预测结果时,需要输入变量的名称,但输入的变量顺序无所谓(可以是一个字典)model_pmml.predict(df.to_dict(orient='records')[0])['probability(1)']

3.1.4 方式1:和pkl文件预测结果对比有偏差

使用方式1保存的pmml文件,如果加载后预测结果和pkl文件预测结果对比有偏差。但偏差样本的占比在1%以内,并且偏差的预测概率值在小数点10位之后,那么是正常情况。

原因是:pmml用的是64位浮点,pkl用的是32位浮点。

如果偏差样本占比很大,并且偏差值相差也很大,那么就要检查一下数据和模型了的问题了。

3.2 方式2:直接将pkl文件转为pmml文件

3.2.1 方式2:pkl文件转pmml文件

方式2,直接将pkl文件转成pmml文件,在管道pipeline中省去了fit的步骤。

import joblibmodel = joblib.load(filename='./model_joblib.pkl')from sklearn2pmml import PMMLPipeline, sklearn2pmmlpipeline = PMMLPipeline([('classifier', model)])sklearn2pmml(pipeline, 'model_pkl_to_pmml.pmml', with_repr=True)

让我们打开生成的pmml文件看一下,对比一下方式1生成的pmml文件有什么区别: 我们可以看到,方式1生成的pmml文件原本保存具体变量名的地方,变成了x1、x1...。

image.png

<figcaption style="text-align: center; line-height: 1.75; color: rgb(136, 136, 136); font-size: 0.8em;">图片</figcaption>

3.2.2 方式2:加载pmml文件

from pypmml import Modelmodel_pmml = Model.fromFile('model_pkl_to_pmml.pmml')model_pmml.inputNames

加载后可以用model_pmml.inputNames来查看入模的变量:输出x1、x2...,没有具体的指标名。

image.png

<figcaption style="text-align: center; line-height: 1.75; color: rgb(136, 136, 136); font-size: 0.8em;">图片</figcaption>

3.2.3 方式2:使用pmml文件预测结果predict()

使用方式2保存的pmml文件因为内部没有保存具体的变量名,所以加载后预测结果,输入和pkl文件一样,不需要输入变量的名称,输入是一个数组,但输入的变量顺序必须和模型训练时相同。

df['predict_proba_pkl_to_pmml'] = [c[1] for c in model_pmml.predict(np.array(df[feature]))]

3.2.4 方式2:和pkl文件预测结果对比有偏差

使用方式2保存的pmml文件,如果加载后预测结果和pkl文件预测结果对比有偏差。

如果偏差占比占比很大,并且偏差值相差特别大,那么应该是数据和模型有问题,需要核查一下。但是如果是偏差值在(-0.005~+0.005)左右,偏差比较大,基本是可以排除数据和模型的问题。这个时候不妨直接把pmml交给java开发,说不定就能对上了。这也许是java环境造成的差异。

3.3 保存pmml文件时报错

RuntimeError: The SkLearn2PMML application has failed. The Java executable should have printed more information about the failure into its standard output and/or standard error streams

报错原因1:没java环境,java环境匹配。

解决方式:安装配置java1.8环境。

报错原因2:sklearn的版本太高了,而sklearn2pmml的版本太低了。

解决方式:升级sklearn2pmml。如果sklearn版本>=0.22.0,sklearn2pmml可以升级到0.51.0。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容