序言
寻找一个准确的机器学习模型并不是项目结束的时候。在本文中,我们将发现如何使用scikit-learn保存和加载机器学习模型。这让我们可以把模型保存到文件中,并在以后加载它来进行预测。学完本文,我们将了解:
1. 为了重复使用而序列化模型的重要性。
2. 如何使用pickle来序列化和反序列化机器学习模型。
3. 如何使用joblib来序列化和反序列化机器学习模型。
使用pickle序列化模型
Pickle是在Python中序列化对象的标准方法。我们可以使用pickle操作序列化机器学习算法并将序列化格式保存到文件中。以便后续可以加载此文件以反序列化模型并使用它来进行新的预测。
下面示例演示了如何在皮马印第安人的发病时训练逻辑回归模型糖尿病数据集,将模型保存到文件并加载它以对看不见的测试集进行预测。
使用joblib序列化模型
Joblib库是SciPy生态系统的一部分,提供了用于流水线化Python任务的工具。它提供了用于保存和加载使用NumPy数据结构的Python对象的实用程序,效率很高。这对于某些需要大量参数或存储整个数据集的机器学习算法(例如k-最近邻)非常有用。
下面的示例展示了如何使用皮马印第安人糖尿病发病数据集训练逻辑回归模型,使用Joblib将模型保存到文件中,并加载它来对未见的测试集进行预测。
案例源码分享
# coding=utf-8
"""
本脚本主要用于演示如何使用pickle和joblib对机器学习模型进行序列化和反序列化。
流程包括:加载数据、数据清洗、特征标准化、模型训练及序列化。
"""
# 导入必要的库
from pathlib import Path # 用于处理文件路径
import pandas as pd # 用于数据处理和分析
from sklearn.preprocessing import StandardScaler # 用于数据标准化
from sklearn.model_selection import train_test_split # 用于数据划分
from sklearn.linear_model import LogisticRegression # 用于逻辑回归模型
import pickle # 用于模型的保存和加载
import joblib # 提供了更高效的方式保存和加载模型
# 加载数据并重命名列名
filename = Path(__file__).parent / 'data/pima-indians-diabetes.csv'
data = pd.read_csv(filename)
column_names = {'Pregnancies': 'pregnant_times',
'Glucose': 'glucose',
'BloodPressure': 'blood_pressure',
'SkinThickness': 'skin_thickness',
'Insulin': 'insulin',
'BMI': 'BMI',
'DiabetesPedigreeFunction': 'DPF',
'Age': 'age',
'Outcome': 'outcome'}
data.rename(columns=column_names, inplace=True)
# 数据清洗,删除含有缺失值的行
data.dropna(inplace=True)
# 特征标准化
scaler = StandardScaler()
X = scaler.fit_transform(data.iloc[:, :-1])
# 提取目标变量
Y = data.iloc[:, -1]
print(X.shape, Y.shape)
###### 使用pickle序列化模型 ######
print("\n使用pickle序列化模型:")
# 数据集划分
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.33, random_state=7)
# 模型训练
model = LogisticRegression()
model.fit(X_train, Y_train)
# 模型序列化
filename = Path(__file__).parent / 'model/finalized_logistic_regression_with_pickle.pkl'
pickle.dump(model, open(filename, 'wb'))
# 模型反序列化
loaded_model = pickle.load(open(filename, 'rb'))
# 计算模型准确率
result = loaded_model.score(X_test, Y_test)
print("Accuracy: %.2f%%" % (result * 100.0))
###### 使用joblib序列化模型 ######
print("\n使用joblib序列化模型:")
# 数据集划分
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.33, random_state=7)
# 模型训练
model = LogisticRegression()
model.fit(X_train, Y_train)
# 模型序列化
filename = Path(__file__).parent / 'model/finalized_logistic_regression_with_joblib.sav'
joblib.dump(model, filename)
# 模型反序列化
loaded_model = joblib.load(filename)
# 计算模型准确率
result = loaded_model.score(X_test, Y_test)
print("Accuracy: %.2f%%" % (result * 100.0))
# 输出(略)
总结
在最终确定机器学习模型时,还有一些重要的考虑因素:
1. Python 版本。请注意 Python 的版本。在以后加载和反序列化模型时,几乎肯定需要与序列化模型时使用的 Python 的主要(可能还包括次要)版本相同。
2. 库版本。在机器学习项目中使用的所有主要库的版本,在反序列化保存的模型时几乎肯定需要保持一致。这不仅限于 NumPy 的版本和 scikit-learn 的版本。
3. 手动序列化。我们可能希望手动输出所学模型的参数,以便将来可以直接在 scikit-learn 或另一个平台上使用它们。通常,机器学习算法内部用于做出预测的技术比用于学习参数的技术要简单得多,这可能很容易在您控制的自定义代码中实现。
注意版本,以便如果出于某种原因我们无法在稍后的另一台机器或另一个平台上重新加载您的模型,您可以重新创建环境。