Zapisz klasyfikator na dysku w scikit-dowiedz się

Jak zapisać wytrenowany naiwny klasyfikator Bayesa na dysku i użyć go do przewidywania danych?

Mam następujący przykładowy program ze strony 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()
Author: alichaudry, 2012-05-15

5 answers

Klasyfikatory to tylko przedmioty, które można wytrawić i wyrzucić jak każdy inny. Aby kontynuować przykład:

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)
 152
Author: mwv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-15 01:41:50

Możesz również użyć joblib.dump i joblib.load , który jest znacznie bardziej wydajny w obsłudze tablic numerycznych niż domyślny pickler Pythona.

Joblib jest zawarty w 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
 174
Author: ogrisel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-23 13:16:28

To, czego szukasz, nazywa się Model persistenceW słowach sklearn i jest udokumentowane w wprowadzenieoraz w Model persistence Sekcje.

Więc zainicjowałeś swój klasyfikator i trenowałeś go przez długi czas z

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

Po tym masz dwie opcje:

1) Using 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) Korzystanie Z 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')

Jeszcze raz warto przeczytać wyżej wymienione linki

 68
Author: Salvador Dali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-24 04:17:11

W wielu przypadkach, szczególnie w przypadku klasyfikacji tekstu, nie wystarczy tylko przechowywać klasyfikator, ale będziesz musiał również przechowywać vectorizer, aby w przyszłości móc wektoryzować swoje dane wejściowe.

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

Future use case:

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)

Przed zrzuceniem vectorizera, można usunąć właściwość stop_words_ vectorizera przez:

vectorizer.stop_words_ = None

Aby dumping był bardziej efektywny. Również jeśli parametry klasyfikatora są rzadkie (jak w większości przykładów klasyfikacji tekstu), możesz przekonwertować parametry od gęstego do rzadkiego, co zrobi ogromną różnicę pod względem zużycia pamięci, ładowania i wyrzucania. Sparsify model by:

clf.sparsify()

Który automatycznie będzie działał dla SGDClassifier ale jeśli wiesz, że twój model jest rzadki (wiele zer w clf.coef_) następnie można ręcznie konwertować clf.coef_ do CSR scipy sparse matrix by:

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

I wtedy można go przechowywać bardziej efektywnie.

 9
Author: Ash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-23 03:30:03

sklearn estymatory wdrażają metody ułatwiające zapisanie odpowiednich właściwości estymatora. Niektóre estymatory implementują same metody __getstate__, ale inne, jak GMM po prostu używają implementacji bazowej , która po prostu zapisuje wewnętrzny słownik obiektów:

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

Zalecaną metodą zapisania modelu na dysku jest użycie pickle Moduł:

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)

Należy jednak zapisać dodatkowe dane, aby móc przekwalifikować swój model w przyszłość, lub ponieść straszne konsekwencje (np być zamknięty w starej wersji sklearn) .

Z dokumentacji :

W celu przebudowy podobnego modelu z przyszłymi wersjami scikit-dowiedz się, dodatkowe metadane powinny być zapisywane wzdłuż marynowanej model:

[12]} dane treningowe, np. odniesienie do niezmiennej migawki

Kod źródłowy Pythona użyty do wygenerowania modelu

Wersje scikit-Nauka i jej zależności]}

Wynik weryfikacji krzyżowej uzyskany na danych treningowych

Jest to szczególnie prawdziwe dla estymatorów Ensemble , które opierają się na tree.pyx Moduł napisany w Cythonie (np. IsolationForest), ponieważ tworzy sprzężenie z implementacją, które nie ma gwarancji stabilności pomiędzy wersjami sklearn. W przeszłości zdarzały się zmiany niezgodne wstecz.

Jeśli twoje modele stają się bardzo duże i ładują staje się uciążliwe, można również użyć bardziej wydajne joblib. Z dokumentacji:

W konkretnym przypadku scikit, może być bardziej interesujące użycie zastępstwo joblibpickle (joblib.dump & joblib.load), czyli bardziej wydajne na obiektach, które przenoszą wewnątrz duże tablice numpy jako często ma to miejsce w przypadku dopasowanych estymatorów scikit-learn, ale może tylko ogórek do dysku a nie do struny:

 2
Author: Sebastian Wozny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-07 11:53:23