sklearn recall learning confusion classification_report accuracy python scikit-learn pickle statsmodels dill

python - recall - sklearn metrics



¿Cuáles son los inconvenientes de usar Dill para serializar modelos de scikit-learn/statsmodels? (3)

Bien, para empezar, en su código de ejemplo, pickle podría funcionar bien, uso pickle todo el tiempo para empaquetar un modelo y usarlo más tarde, a menos que desee enviar el modelo directamente a otro servidor o guardar el interpreter state del interpreter state , porque eso es lo que Dill es bueno en y pickle no puede hacer. También depende de su código, de los tipos, etc. que utilice, ya que el pickle podría fallar, Dill es más estable.

Dill se basa primordialmente en pickle y por lo tanto son muy similares, algunas cosas que debes tener en cuenta / considerar:

  1. Limitaciones del Dill

    frame tipos estándar de frame , generator y traceback no pueden ser empaquetados.

  2. cloudpickle puede ser una buena idea para su problema, tiene mejor soporte para los objetos de decapado (que pickle, no para ver mejor que Dill) y también puede declinar el código fácilmente.

Una vez que la máquina de destino tenga cargadas las bibliotecas correctas (tenga cuidado también con las diferentes versiones de python , ya que pueden cloudpickle errores en su código), todo debería funcionar bien tanto con Dill como con cloudpickle , siempre y cuando no use los tipos estándar no admitidos.

Espero que esto ayude.

Necesito serializar modelos de scikit-learn / statsmodels para que todas las dependencias (código + datos) estén empaquetadas en un artefacto y este artefacto se pueda usar para inicializar el modelo y hacer predicciones. El uso del module pickle no es una opción porque solo se hará cargo de la dependencia de los datos (el código no se empaquetará). Entonces, he estado realizando experimentos con Dill . Para que mi pregunta sea más precisa, el siguiente es un ejemplo en el que construyo un modelo y lo persisto.

from sklearn import datasets from sklearn import svm from sklearn.preprocessing import Normalizer import dill digits = datasets.load_digits() training_data_X = digits.data[:-5] training_data_Y = digits.target[:-5] test_data_X = digits.data[-5:] test_data_Y = digits.target[-5:] class Model: def __init__(self): self.normalizer = Normalizer() self.clf = svm.SVC(gamma=0.001, C=100.) def train(self, training_data_X, training_data_Y): normalised_training_data_X = normalizer.fit_transform(training_data_X) self.clf.fit(normalised_training_data_X, training_data_Y) def predict(self, test_data_X): return self.clf.predict(self.normalizer.fit_transform(test_data_X)) model = Model() model.train(training_data_X, training_data_Y) print model.predict(test_data_X) dill.dump(model, open("my_model.dill", ''w''))

Correspondiente a esto, aquí es cómo inicializo el modelo persistente (en una nueva sesión) y hago una predicción. Tenga en cuenta que este código no se inicializa explícitamente ni tiene conocimiento de la class Model .

import dill from sklearn import datasets digits = datasets.load_digits() training_data_X = digits.data[:-5] training_data_Y = digits.target[:-5] test_data_X = digits.data[-5:] test_data_Y = digits.target[-5:] with open("my_model.dill") as model_file: model = dill.load(model_file) print model.predict(test_data_X)

¿Alguien ha usado Dill? ¿No es así? La idea es que un científico de datos extienda una ModelWrapper class para cada modelo que implementen y luego construya la infraestructura en torno a esto que persista en los modelos, implemente los modelos como servicios y administre todo el ciclo de vida del modelo.

class ModelWrapper(object): __metaclass__ = abc.ABCMeta def __init__(self, model): self.model = model @abc.abstractmethod def predict(self, input): return def dumps(self): return dill.dumps(self) def loads(self, model_string): self.model = dill.loads(model_string)

Aparte de las implicaciones de seguridad (ejecución de código arbitrario) y el requisito de que los módulos como scikit-learn se tengan que instalar en la máquina que está sirviendo al modelo, ¿existen otras dificultades en este enfoque? Cualquier comentario o consejo sería de gran ayuda.

Creo que YHat y Dato han adoptado un enfoque similar, pero han implementado implementaciones propias de Dill para propósitos similares.


Empaqueté el proceso gaussiano (GP) de scikit-learn usando pickle .

La razón principal es porque el GP tarda mucho tiempo en construirse y se carga mucho más rápido usando pickle . Por lo tanto, en la inicialización de mi código, compruebo si los archivos de datos para el modelo se actualizaron y, si fuera necesario, volvía a generar el modelo. De lo contrario, ¡simplemente elimine la serialización de pickle !

Yo usaría pickle , dill , cloudpickle en el orden respectivo.

Tenga en cuenta que pickle incluye un argumento de palabra clave de protocol y algunos valores pueden acelerar y reducir significativamente el uso de memoria. Finalmente, si es necesario, envuelvo el código pickle con compresión de CPython STL.


Soy el autor del dill . dill fue creado para hacer exactamente lo que está haciendo ... (para mantener los ajustes numéricos dentro de las instancias de clase para las estadísticas) donde estos objetos pueden distribuirse a diferentes recursos y ejecutarse de una manera vergonzosamente paralela. Entonces, la respuesta es sí. He ejecutado un código como el tuyo, usando mystic y / o sklearn .

Tenga en cuenta que muchos de los autores de sklearn utilizan cloudpickle para habilitar la computación paralela en los objetos de sklearn , y no el dill . dill puede escoger más tipos de objetos que cloudpickle ; sin embargo, cloudpickle es ligeramente mejor (en este momento de la escritura) en los objetos de decapado que hacen referencia al diccionario global como parte de un cierre; de ​​forma predeterminada, dill hace esto por referencia, mientras que cloudpickle Almacena físicamente las dependencias. Sin embargo, el dill tiene un modo "recurse" , que actúa como cloudpickle , por lo que la diferencia cuando se usa este modo es menor. (Para habilitar el modo "recurse" , haga dill.settings[''recurse''] = True , o use recurse=True como una bandera en dill.dump ). Otra diferencia menor es que cloudpickle contiene soporte especial para cosas como scikits.timeseries y PIL.Image , mientras que dill no lo hace.

En el lado positivo, dill no escurre las clases por referencia, por lo que al esclarecer una instancia de clase, serializa el objeto de clase en sí, lo cual es una gran ventaja, ya que serializa instancias de clases derivadas de clasificadores, modelos, etc. de sklearn en su estado exacto al momento del decapado ... así que si realiza modificaciones en el objeto de clase, la instancia aún se deselecciona correctamente. Hay otras ventajas del dill sobre cloudpickle , aparte de la gama más amplia de objetos (y normalmente un pickle más pequeño), sin embargo, no los enumeraré aquí. Pidiste escollos, por lo que las diferencias no son escollos.

Los principales escollos:

  • Debe tener todo lo que se refiera a sus clases instalado en la máquina remota, en caso de que dill (o cloudpickle ) lo cloudpickle por referencia.

  • Debe intentar que sus clases y métodos de clase sean lo más autónomos posible (por ejemplo, no haga referencia a los objetos definidos en el ámbito global de sus clases).

  • sklearn objetos de sklearn pueden ser grandes, por lo que guardar muchos de ellos en un solo pickle no siempre es una buena idea ... es posible que desee utilizar klepto que tiene una interfaz de klepto para almacenar en caché y archivar, y le permite configurar la interfaz de archivo para almacenar cada clave -valor par individual (por ejemplo, una entrada por archivo).