在訓練完 scikit-learn 模型之后,最好有一種方法來將模型持久化以備將來使用,而無需重新訓練。 以下部分為您提供了有關如何使用 pickle 來持久化模型的示例。 在使用 pickle 序列化時,我們還將回顧一些安全性和可維護性方面的問題。
pickle的另一種方法是使用相關項目中列出的模型導出工具之一將模型導出為另一種格式。與pickle不同,一旦導出,就不能恢復完整的Scikit-learn estimator對象,但是可以部署模型進行預測,通常可以使用支持開放模型交換格式的工具,如“ONNX”或“PMML”。
1. 持久化示例
可以通過使用 Python 的內置持久化模型將訓練好的模型保存在 scikit 中,它名為 pickle:
>>> from sklearn import svm >>> from sklearn import datasets >>> clf = svm.SVC() >>> iris = datasets.load_iris() >>> X, y = iris.data, iris.target >>> clf.fit(X, y) SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf', max_iter=-1, probability=False, random_state=None, shrinking=True, tol=0.001, verbose=False) >>> import pickle >>> s = pickle.dumps(clf) >>> clf2 = pickle.loads(s) >>> clf2.predict(X[0:1]) array([0]) >>> y[0] 0
在這個 scikit 的特殊示例中,使用 joblib 來替換 pickle(joblib.dump
& joblib.load
)可能會更有意思,這對於內部帶有 numpy 數組的對象來說更為高效, 通常情況下適合 scikit-learn estimators(預估器),但是也只能是 pickle 到硬盤而不是字符串:
>>> from sklearn.externals import joblib >>> joblib.dump(clf, 'filename.pkl')
之后你可以使用以下方式回調 pickled model 可能在另一個 Python 進程中):
>>> clf = joblib.load('filename.pkl')
注意 joblib.dump
和 joblib.load
函數也接收類似 file-like 的對象而不是文件名。 更多有關使用 Joblib 來持久化數據的信息可以參閱 這里.
2. 安全性和可維護性的局限性
pickle(和通過擴展的 joblib),在安全性和可維護性方面存在一些問題。 有以下原因,
- 絕對不要使用未經 pickle 的不受信任的數據,因為它可能會在加載時執行惡意代碼。
- 雖然一個版本的 scikit-learn 模型可以在其他版本中加載,但這完全不建議並且也是不可取的。 還應該了解到,對於這些數據執行的操作可能會產生不同及意想不到的結果。
為了用以后版本的 scikit-learn 來重構類似的模型, 額外的元數據應該隨着 pickled model 一起被保存:
- 訓練數據,例如:引用不可變的快照
- 用於生成模型的 python 源代碼
- scikit-learn 的各版本以及各版本對應的依賴包
- 在訓練數據的基礎上獲得的交叉驗證得分
這樣可以檢查交叉驗證得分是否與以前相同。
由於模型內部表示可能在兩種不同架構上不一樣,因此不支持在一個架構上轉儲模型並將其加載到另一個體系架構上。