scikit-learn 模型持久性

2023-02-20 14:25 更新

在訓(xùn)練一個(gè)scikit-learn模型后,最好有一種方法可以將模型持久化以備重復(fù)使用,而不需要重新訓(xùn)練模型。隨后將會(huì)提供例子以解釋如何使用pickle來始模型更加持久。當(dāng)使用pickle序列化時(shí),需要回顧一些安全性和可維護(hù)性問題。

pickle的另一個(gè)選擇是以另一種形式輸出模型,通過使用模型輸出工具,詳見 Related Projects。 與pickle不同的是,一旦輸出就不能恢復(fù)完整的Scikit-learn估計(jì)器對像,但是你可以使用模型進(jìn)行預(yù)測,通常使用支持開放模型交換格式的工具,例如 ONNX或者 PMML。

3.4.1 持久性例子

通過使用Python內(nèi)置的持久性模型,可以將模型保存在scikit-learn中,即pickle

>>> from sklearn import svm
>>> from sklearn import datasets
>>> clf = svm.SVC()
>>> X, y= datasets.load_iris(return_X_y=True)
>>> clf.fit(X, y)
SVC()

>>> import pickle
>>> s = pickle.dumps(clf)
>>> clf2 = pickle.loads(s)
>>> clf2.predict(X[0:1])
array([0])
>>> y[0]

在scikit-learn的具體例子中,最好使用joblib替換pickle(joblib.dump & joblib.load),它在處理內(nèi)部攜帶大型numpy數(shù)組的對象時(shí)更有效,這通常適用于用scikit-learn估計(jì)器擬合大型numpy數(shù)組,但是只能pickle到硬盤而不是字符串:

>>> from joblib import dump, load
>>> dump(clf, 'filename.joblib')  

然后,你可以裝回pickle好的模型(可能在另一個(gè)Python過程):

>>> clf = load('filename.joblib')  

**注意:**轉(zhuǎn)存和加載各類函數(shù)也可以接受類文件對象而不是文件名。關(guān)于Joblib的數(shù)據(jù)持久性的更多信息參見here。

3.4.2 安全性和可維護(hù)性限制

pickle(和通過擴(kuò)展的joblib),有一些關(guān)于可維護(hù)性和安全性的例子。因?yàn)椋?/p>

  • 不要使用未pickle的不信任數(shù)據(jù),因?yàn)樗赡軐?dǎo)致在運(yùn)行過程中執(zhí)行惡意文件。
  • 當(dāng)模型保存在scikit-learn的某個(gè)版本中,然后加載在另一個(gè)版本中, 這是完全不支持且不建議的。始終應(yīng)該牢記的是在這樣的數(shù)據(jù)上執(zhí)行操作可能會(huì)得到不同且意想不到的結(jié)果。

為了在未來版本的scikit-learn中重新構(gòu)建一個(gè)相似的模型,額外的元數(shù)據(jù)應(yīng)該被保存在pickle模型中:

  • 訓(xùn)練數(shù)據(jù),例如參考不可改變的快照
  • python源代碼被用來生成模型
  • scikit-learn的版本和它的依賴性
  • 在訓(xùn)練集中交叉驗(yàn)證的得分

這樣可以檢查交叉驗(yàn)證的得分是否與以前的在同樣的范圍內(nèi)。

由于模型的內(nèi)部表示在兩個(gè)不同的結(jié)構(gòu)體系中可能表示不同,在一個(gè)結(jié)構(gòu)體系上轉(zhuǎn)存模型,并在另一個(gè)結(jié)構(gòu)體系上加載是不被允許的。

如果想了解更多的相關(guān)問題及其它可能的序列方法,可以參考 talk by Alex Gaynor 。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號