Сохранить классификатор на диск в scikit-learn


Как сохранить обученный наивный байесовский классификатор до диск и использовать его в предсказания данные?

У меня есть следующий пример программы с сайта scikit-learn:

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()
5 138

5 ответов:

классификаторы-это просто объекты, которые могут быть замаринованы и сброшены, как и любые другие. Чтобы продолжить ваш пример:

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.дамп и joblib.загрузить который гораздо более эффективен при обработке числовых массивов, чем по умолчанию 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 слов и это задокументировано в введение и модель настойчивость разделы.

таким образом, вы инициализировали свой классификатор и обучали его в течение длительного времени с

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

после этого у вас есть два варианта:

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')

один еще раз полезно прочитать вышеупомянутые ссылки

во многих случаях, особенно при классификации текста, недостаточно просто сохранить классификатор, но вам также нужно будет сохранить векторизатор, чтобы вы могли векторизовать свой ввод в будущем.

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)

перед сбросом векторизатора можно удалить свойство stop_words_ векторизатора с помощью:

vectorizer.stop_words_ = None

чтобы сделать демпинг более эффективным. Также, если ваши параметры классификатора разрежены (как и в большинстве текстов примеры классификации) вы можете конвертировать параметры из плотных в разреженные, что будет иметь огромное значение с точки зрения потребления памяти, загрузки и сброса. Sparsify модель:

clf.sparsify()

который будет автоматически работать для SGDClassifier но если вы знаете, что ваша модель разрежена (много нулей в clf.coef_), то вы можете вручную конвертировать clf.coef_ в A csr scipy разреженная матрица by:

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

и затем вы можете хранить его более эффективно.

sklearn сметчиков реализовать методы, чтобы сделать его легким для вас, чтобы сохранить соответствующие обученные свойства оценки. Некоторые оценки реализуют __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)

тем не менее, вы должны сохранить дополнительные данные, так что вы можете переподготовить свою модель в будущем, или страдают от тяжелых последствий (например, быть заблокированным в старой версии sklearn).

С документация:

для того чтобы перестроить подобную модель с будущими версиями scikit-узнайте, дополнительные метаданные должны быть сохранены вдоль маринованного модель:

обучающие данные, например ссылка на неизменяемый снимок

исходный код python, используемый для создания модели

версии scikit-learn и его зависимости

оценка перекрестной проверки, полученная на данных обучения

это особенно верно для ансамблевых оценок, которые полагаются на tree.pyx модуль написан на языке Cython(например IsolationForest), так как он создает связь с реализацией, которая не гарантируется стабильной между версии sklearn. В прошлом он видел обратные несовместимые изменения.

если ваши модели становятся очень большими и загрузка становится неприятностью, вы также можете использовать более эффективный joblib. Из документации:

в конкретном случае scikit, это может быть более интересно использовать замена joblib-х pickle (joblib.dump & joblib.load), которая более эффективно для объектов, которые несут большие массивы numpy внутри, как это часто бывает для установлен пакет scikit-узнать оценки, но только мариновать на диск, а не на строку: