2012-05-15 26 views
110

¿Cómo puedo guardar una Clasificador bayesiano entrenado a disco y lo utilizan para predecir datos?Guardar clasificador en el disco en scikit-learn

Tengo el siguiente programa de ejemplo de la página web 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() 

Respuesta

123

clasificadores son sólo objetos que pueden ser objeto de dumping en vinagre y como cualquier otro. Para continuar con su ejemplo:

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) 
+0

funciona como un encanto! Estaba tratando de usar np.savez y cargarlo todo el tiempo y eso nunca me ayudó. Muchas gracias. – Kartos

156

También puede utilizar joblib.dump y joblib.load que es mucho más eficiente en el manejo de matrices numéricas que el pickler pitón por defecto.

JOBLIB está incluido en 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 
+0

Pero, desde mi entender, la canalización funciona si es parte de un único flujo de trabajo. Si quiero construir el modelo, guárdelo en el disco y detenga la ejecución allí.Luego vuelvo una semana después y trato de cargar el modelo desde el disco, me arroja un error: – venuktan

+0

No hay forma de parar y reanudar la ejecución del método 'fit' si esto es lo que estás buscando. Dicho esto, 'joblib.load' no debería lanzar una excepción después de un' joblib.dump' exitoso si lo llamas desde un Python con la misma versión de la biblioteca scikit-learn. – ogrisel

+7

Si está usando IPython, no use el indicador de línea de comando '--pylab' o la magia'% pylab' ya que se sabe que la sobrecarga implícita del espacio de nombres interrumpe el proceso de decapado. Utilice las importaciones explícitas y la magia '% matplotlib inline' en su lugar. – ogrisel

49

Lo que usted está buscando se llama modelo de persistencia en palabras sklearn y se documenta en introduction y en model persistence secciones.

Por lo que han inicializado el clasificador y entrenado durante mucho tiempo con

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

Después de esto usted tiene dos opciones:

1) El uso de la salmuera

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

Una vez más, es útil leer los enlaces antes mencionados

5

En muchos casos, particularmente con clasificación de texto no es suficiente para almacenar el clasificador, pero que necesita para almacenar la Vectorizer así para que puedas vectorizar tu entrada en el futuro.

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

futuro caso de uso:

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) 

Antes de vaciar el Vectorizer, se puede eliminar la propiedad stop_words_ de Vectorizer por:

vectorizer.stop_words_ = None 

para hacer más eficiente el dumping. Además, si los parámetros de su clasificador son escasos (como en la mayoría de los ejemplos de clasificación de texto) puede convertir los parámetros de denso a disperso, lo que supondrá una gran diferencia en términos de consumo de memoria, carga y descarga. Sparsify el modelo por:

clf.sparsify() 

que trabajará automáticamente para SGDClassifier pero en caso de conocer su modelo es escaso (un montón de ceros en clf.coef_) entonces se puede convertir manualmente CLF.coef_ en un csr scipy sparse matrix por:

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

y luego se puede almacenar de manera más eficiente.

1

sklearn estimadores implementan métodos para hacer más fácil para que usted pueda guardar propiedades capacitado pertinente de un estimador. Algunos estimadores implementan __getstate__ métodos mismos, pero otros, como el GMM sólo tiene que utilizar el base implementation, que simplemente guarda los objetos diccionario interior:

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 

El método recomendado para guardar su modelo de disco consiste en usar el módulo 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) 

Sin embargo, debe guardar datos adicionales para que pueda entrenar a su modelo en el futuro, o sufrir graves consecuencias (como estar encerrado en una versión antigua de sklearn).

Desde el documentation:

Con el fin de reconstruir un modelo similar con versiones futuras de scikit-learn, metadatos adicionales sería salvo a lo largo del escabeche modelo:

Los datos de entrenamiento, por ejemplo, una referencia a una instantánea inmutable

El código fuente de Python utilizada para generar el modelo

Las versiones de scikit-learn y sus dependencias

La validación cruzada puntuación obtenida en los datos de entrenamiento

Esto es especialmente cierto para Ensemble estimadores que se basan en el módulo tree.pyx escrito en Cython (como IsolationForest), ya que crea un acoplamiento a la implemen ción, que no se garantiza que sea estable entre las versiones de sklearn. Ha visto cambios hacia atrás incompatibles en el pasado.

Si sus modelos se vuelven muy grandes y la carga se convierte en una molestia, también puede utilizar la más eficiente joblib. A partir de la documentación:

En el caso específico de la scikit, puede ser más interesante utilizar el reemplazo de JOBLIB de pickle (joblib.dump & joblib.load), que es más eficiente en los objetos que llevan grandes conjuntos numpy internamente como es a menudo el caso de armarios scikit-learn estimadores, pero sólo puede salmuera en el disco y no a una cadena:

Cuestiones relacionadas