在scikit-learn中将分类器保存到磁盘

如何将经过训练的朴素贝叶斯分类器保存到磁盘并使用它来预测数据?

我从scikit学习网站有以下示例程序:

from sklearn import datasets iris = datasets.load_iris() from sklearn.naive_bayes import GaussianNB gnb = GaussianNB() y_pred = gnb.fit(iris.data, iris.target).predict(iris.data) print "Number of mislabeled points : %d" % (iris.target != y_pred).sum() 

分类器只是可以像其他任何东西一样被腌制和倾倒的对象。 继续你的例子:

 import cPickle # save the classifier with open('my_dumped_classifier.pkl', 'wb') as fid: cPickle.dump(gnb, fid) # load it again with open('my_dumped_classifier.pkl', 'rb') as fid: gnb_loaded = cPickle.load(fid) 

你也可以使用joblib.dump和joblib.load ,它比缺省的python pickler更有效地处理数组。

Joblib包含在scikit-learn中:

 >>> from sklearn.externals import joblib >>> from sklearn.datasets import load_digits >>> from sklearn.linear_model import SGDClassifier >>> digits = load_digits() >>> clf = SGDClassifier().fit(digits.data, digits.target) >>> clf.score(digits.data, digits.target) # evaluate training error 0.9526989426822482 >>> filename = '/tmp/digits_classifier.joblib.pkl' >>> _ = joblib.dump(clf, filename, compress=9) >>> clf2 = joblib.load(filename) >>> clf2 SGDClassifier(alpha=0.0001, class_weight=None, epsilon=0.1, eta0=0.0, fit_intercept=True, learning_rate='optimal', loss='hinge', n_iter=5, n_jobs=1, penalty='l2', power_t=0.5, rho=0.85, seed=0, shuffle=False, verbose=0, warm_start=False) >>> clf2.score(digits.data, digits.target) 0.9526989426822482 

你正在寻找什么称为模型持久性 sklearn单词,它是介绍和模型持久性部分logging。

所以你已经初始化你的分类器并且用很长时间来训练它

 clf = some.classifier() clf.fit(X, y) 

之后你有两个select:

1)使用泡菜

 import pickle # now you can save it to a file with open('filename.pkl', 'wb') as f: pickle.dump(clf, f) # and later you can load it with open('filename.pkl', 'rb') as f: clf = pickle.load(f) 

2)使用Joblib

 from sklearn.externals import joblib # now you can save it to a file joblib.dump(clf, 'filename.pkl') # and later you can load it clf = joblib.load('filename.pkl') 

再一次阅读上述链接是有帮助的

在很多情况下,特别是在文本分类方面,仅存储分类器是不够的,但是您还需要存储vector化工具,以便将来能够vector化您的input。

 import pickle with open('model.pkl', 'wb') as fout: pickle.dump((vectorizer, clf), fout) 

未来的使用案例:

 with open('model.pkl', 'rb') as fin: vectorizer, clf = pickle.load(fin) X_new = vectorizer.transform(new_samples) X_new_preds = clf.predict(X_new) 

在转储vector化器之前,可以通过以下方法删除vector化器的stop_words_属性:

 vectorizer.stop_words_ = None 

使倾销更有效率。 此外,如果您的分类器参数是稀疏的(如在大多数文本分类示例中),则可以将参数从密集转换为稀疏,这会在内存消耗,加载和转储方面带来巨大差异。 通过以下方式分离模型:

 clf.sparsify() 

这将自动为SGDClassifier工作,但如果你知道你的模型是稀疏的(在clf.coef_大量零),那么你可以通过手动将clf.coef_转换为csr scipy稀疏matrix :

 clf.coef_ = scipy.sparse.csr_matrix(clf.coef_) 

然后您可以更有效地存储它。

sklearn估计器实现方法,使您可以轻松保存估算人员的相关训练属性。 有些评估__getstate__自己实现了__getstate__方法,但是其他的方法,比如GMM只是使用基本的实现来保存对象的内部字典:

 def __getstate__(self): try: state = super(BaseEstimator, self).__getstate__() except AttributeError: state = self.__dict__.copy() if type(self).__module__.startswith('sklearn.'): return dict(state.items(), _sklearn_version=__version__) else: return state 

将模型保存到光盘的推荐方法是使用pickle模块:

 from sklearn import datasets from sklearn.svm import SVC iris = datasets.load_iris() X = iris.data[:100, :2] y = iris.target[:100] model = SVC() model.fit(X,y) import pickle with open('mymodel','wb') as f: pickle.dump(model,f) 

但是,您应该保存更多的数据,以便将来可以重新训练模型,或者承受可怕的后果(例如locking旧版本的sklearn)

从文档 :

为了使用scikit-learn的未来版本重build一个类似的模型,应该在pickled模型中保存附加的元数据:

训练数据,例如对不可变快照的引用

用于生成模型的python源代码

scikit-learn及其依赖的版本

交叉validation得分在训练数据上得分

对于依赖tree.pyx编写的tree.pyx模块(比如IsolationForest )的集合估计器来说尤其如此 ,因为它创build了一个耦合到实现,在sklearn版本之间不保证是稳定的。 过去看到了倒退不相容的变化。

如果您的模型变得非常大并且加载变得麻烦,您也可以使用更高效的joblib 。 从文档:

在scikit的特定情况下,使用joblibreplacepicklejoblib.dumpjoblib.load )可能会更有趣,这对于内部携带大型numpy数组的对象来说效率更高,这通常适用于scikit-学习估计,但只能腌到磁盘而不是string: