Сохранить классификатор на диск в 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()
Ответы
Ответ 1
Классификаторы - это просто объекты, которые можно мариновать и сбрасывать, как и любые другие. Чтобы продолжить свой пример:
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)
Ответ 2
Вы также можете использовать joblib.dump и joblib.load, что намного эффективнее при обработке числовых массивы, чем стандартный сортировщик питона.
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
Ответ 3
То, что вы ищете, называется Сохранение модели в словах sklearn, и оно задокументировано в введении и в .
Итак, вы инициализировали свой классификатор и долго обучали его с помощью
clf = some.classifier()
clf.fit(X, y)
После этого у вас есть два варианта:
1) Использование Pickle
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')
Еще раз полезно прочитать вышеупомянутые ссылки
Ответ 4
Во многих случаях, особенно с классификацией текста, недостаточно просто хранить классификатор, но вам также нужно будет хранить векторизатор, чтобы вы могли векторизовать свои данные в будущем.
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_ в csr scipy разреженную матрицу:
clf.coef_ = scipy.sparse.csr_matrix(clf.coef_)
а затем вы можете сохранить его более эффективно.
Ответ 5
Оценщики 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-learn, дополнительные метаданные должны быть сохранены вдоль маринованного модель:
Данные обучения, например. ссылка на неизменяемый снимок
Исходный код python, используемый для генерации модели
Версии scikit-learn и его зависимостей
Баллы перекрестной проверки, полученные по данным обучения
Это особенно верно для оценок Ensemble, которые полагаются на модуль tree.pyx
, написанный в Cython (такой как IsolationForest
), поскольку он создает связь с реализацией, которая не гарантируется быть стабильной между версиями sklearn. В прошлом он видел назад несовместимые изменения.
Если ваши модели становятся очень большими, а загрузка становится неудобством, вы также можете использовать более эффективный joblib
. Из документации:
В конкретном случае scikit может быть более интересно использовать замена трудозатрат pickle
(joblib.dump
и joblib.load
), которая более эффективен для объектов, несущих большие массивы numpy внутри часто бывает для оснащенных оценками scikit-learn, но может мариновать на диск, а не на строку: