Python: ¿qué es exactamente sklearn.pipeline.Pipeline?

118

No puedo entender cómo sklearn.pipeline.Pipelinefunciona exactamente.

Hay algunas explicaciones en el documento . Por ejemplo, ¿qué quieren decir con:

Pipeline de transformaciones con un estimador final.

Para aclarar mi pregunta, ¿cuáles son steps? ¿Cómo trabajan?

Editar

Gracias a las respuestas puedo aclarar mi pregunta:

Cuando llamo a la tubería y paso, como pasos, dos transformadores y un estimador, por ejemplo:

pipln = Pipeline([("trsfm1",transformer_1),
                  ("trsfm2",transformer_2),
                  ("estmtr",estimator)])

¿Qué pasa cuando llamo a esto?

pipln.fit()
OR
pipln.fit_transform()

No puedo entender cómo un estimador puede ser un transformador y cómo se puede instalar un transformador.

farhawa
fuente
3
Por lo que he entendido, la canalización te ayuda a automatizar varios pasos del proceso de aprendizaje. Como el entrenamiento y la prueba de modelos o la selección de características ... Entonces, si desea mezclar una regresión, úsela para alimentar un clasificador, por ejemplo, sus pasos serán el entrenamiento de esa regresión y luego del clasificador. editar: agregar detalles
M0rkHaV
1
queirozf.com/entries/scikit-learn-pipeline-examples Encontré esto útil
randomSampling

Respuestas:

180

Transformador en scikit-learn: alguna clase que tiene el método de ajuste y transformación, o el método de ajuste y transformación.

Predictor : alguna clase que tiene métodos de ajuste y predicción, o método fit_predict.

Pipeline es solo una noción abstracta, no es un algoritmo ml existente. A menudo, en las tareas de AA, es necesario realizar una secuencia de diferentes transformaciones (encontrar un conjunto de características, generar nuevas características, seleccionar solo algunas buenas características) del conjunto de datos sin procesar antes de aplicar el estimador final.

Este es un buen ejemplo del uso de Pipeline. Pipeline le ofrece una única interfaz para los 3 pasos de la transformación y el estimador resultante. Encapsula transformadores y predictores en su interior, y ahora puede hacer algo como:

    vect = CountVectorizer()
    tfidf = TfidfTransformer()
    clf = SGDClassifier()

    vX = vect.fit_transform(Xtrain)
    tfidfX = tfidf.fit_transform(vX)
    predicted = clf.fit_predict(tfidfX)

    # Now evaluate all steps on test set
    vX = vect.fit_transform(Xtest)
    tfidfX = tfidf.fit_transform(vX)
    predicted = clf.fit_predict(tfidfX)

Con solo:

pipeline = Pipeline([
    ('vect', CountVectorizer()),
    ('tfidf', TfidfTransformer()),
    ('clf', SGDClassifier()),
])
predicted = pipeline.fit(Xtrain).predict(Xtrain)
# Now evaluate all steps on test set
predicted = pipeline.predict(Xtest)

Con las canalizaciones, puede realizar fácilmente una búsqueda en cuadrícula sobre un conjunto de parámetros para cada paso de este metaestimador. Como se describe en el enlace anterior. Todos los pasos excepto el último deben ser transformados, el último paso puede ser transformador o predictor. Respuesta para editar : Cuando llame pipln.fit(), cada transformador dentro de la tubería se instalará en las salidas del transformador anterior (el primer transformador se aprende en el conjunto de datos sin procesar). El último estimador puede ser transformador o predictor, puede llamar a fit_transform () en la tubería solo si su último estimador es transformador (que implementa los métodos fit_transform o transformar y ajustar por separado), puede llamar a fit_predict () o predecir () en la tubería solo si su último estimador es el predictor. Por lo tanto, no puede llamar a fit_transform o transform on pipeline, cuyo último paso es el predictor.

Ibraim Ganiev
fuente
1
¿Qué quieres decir con predicted = pipeline.fit(Xtrain).predict(Xtrain)?
farhawa
@farhawa, prediciendo clases en el set de entrenamiento.
Ibraim Ganiev
4
¿Por qué esto no tiene más votos? Debería ser una publicación de blog.
R Claven
1
@iamgin, la interfaz de la mayoría de los transformadores scikit-learn no permite elegir las columnas necesarias que queremos transformar. Pero puede escribir su propio "Selector de elementos", que le ayudará a alimentar el transformador solo con las columnas necesarias. Aquí hay un buen ejemplo con ItemSelector y FeatureUnion scikit-learn.org/stable/auto_examples/…
Ibraim Ganiev
1
En el primer ejemplo, ¿no quiere evitar volver a instalar el equipo de prueba? ¿No debería solo llamar a transform en lugar de fit_transform? Y de manera similar, ¿la tubería predice internamente la llamada a fit_transform o simplemente la transforma? ¿Se puede controlar?
Steven
18

Creo que M0rkHaV tiene la idea correcta. Scikit-learn de la clase de tuberías es una herramienta útil para encapsular varios transformadores diferentes junto con un estimador en un solo objeto, por lo que sólo tiene que llamar a sus métodos importantes una vez ( fit(), predict(), etc.). Analicemos los dos componentes principales:

  1. Los transformadores son clases que implementan fit()y transform(). Es posible que esté familiarizado con algunas de las herramientas de preprocesamiento de sklearn, como TfidfVectorizery Binarizer. Si observa los documentos de estas herramientas de preprocesamiento, verá que implementan ambos métodos. Lo que me parece bastante interesante es que algunos estimadores también se pueden usar como pasos de transformación, por ejemplo LinearSVC.

  2. Los estimadores son clases que implementan fit()y predict(). Descubrirá que muchos de los clasificadores y modelos de regresión implementan ambos métodos y, como tal, puede probar fácilmente muchos modelos diferentes. Es posible utilizar otro transformador como estimador final (es decir, no necesariamente implementa predict(), pero definitivamente implementa fit()). Todo esto significa que no podrá llamar predict().

En cuanto a su edición: veamos un ejemplo basado en texto. Usando LabelBinarizer, queremos convertir una lista de etiquetas en una lista de valores binarios.

bin = LabelBinarizer()  #first we initialize

vec = ['cat', 'dog', 'dog', 'dog'] #we have our label list we want binarized

Ahora, cuando el binarizador se ajusta a algunos datos, tendrá una estructura llamada classes_que contiene las clases únicas que el transformador 'conoce'. Sin llamar, fit()el binarizador no tiene idea de cómo se ven los datos, por lo que llamar transform()no tendría ningún sentido. Esto es cierto si imprime la lista de clases antes de intentar ajustar los datos.

print bin.classes_  

Recibo el siguiente error al intentar esto:

AttributeError: 'LabelBinarizer' object has no attribute 'classes_'

Pero cuando encaja el binarizador en la veclista:

bin.fit(vec)

e intenta de nuevo

print bin.classes_

Obtengo lo siguiente:

['cat' 'dog']


print bin.transform(vec)

Y ahora, después de llamar a transform en el vecobjeto, obtenemos lo siguiente:

[[0]
 [1]
 [1]
 [1]]

En cuanto a los estimadores que se utilizan como transformadores, usemos el DecisionTreeclasificador como ejemplo de extractor de características. Los árboles de decisión son excelentes por muchas razones, pero para nuestros propósitos, lo importante es que tienen la capacidad de clasificar las características que el árbol encontró útiles para predecir. Cuando llama transform()a un árbol de decisión, tomará sus datos de entrada y encontrará lo que cree que son las características más importantes. Entonces, puede pensar en transformar su matriz de datos (n filas por m columnas) en una matriz más pequeña (n filas por k columnas), donde las k columnas son las k características más importantes que encontró el árbol de decisión.

NBartley
fuente
¿Cuál es la diferencia entre fit()y transform()son los Transformers? , ¿cómo se pueden utilizar los estimadores como transformadores?
farhawa
2
fit()es el método al que llama para ajustar o 'entrenar' su transformador, como lo haría con un clasificador o modelo de regresión. En cuanto a transform(), ese es el método al que llama para transformar realmente los datos de entrada en datos de salida. Por ejemplo, llamar Binarizer.transform([8,2,2])(¡después de ajustar!) Podría resultar en [[1,0],[0,1],[0,1]]. En cuanto al uso de estimadores como transformadores, editaré un breve ejemplo en mi respuesta.
NBartley
9

Los algoritmos ML normalmente procesan datos tabulares. Es posible que desee realizar un procesamiento previo y posterior de estos datos antes y después de su algoritmo de ML. Una canalización es una forma de encadenar esos pasos de procesamiento de datos.

¿Qué son las canalizaciones de ML y cómo funcionan?

Una canalización es una serie de pasos en los que se transforman los datos. Viene del antiguo patrón de diseño de "tubería y filtro" (por ejemplo, podría pensar en comandos bash de Unix con tuberías "|" o operadores de redireccionamiento ">"). Sin embargo, las canalizaciones son objetos del código. Por lo tanto, puede tener una clase para cada filtro (también conocido como cada paso de canalización) y luego otra clase para combinar esos pasos en la canalización final. Algunas tuberías pueden combinar otras tuberías en serie o en paralelo, tener múltiples entradas o salidas, etc. Nos gusta ver las canalizaciones de Machine Learning como:

  • Tubería y filtros . Los pasos de la tubería procesan datos y administran su estado interno, que se puede aprender de los datos.
  • Composites . Las canalizaciones se pueden anidar: por ejemplo, una canalización completa se puede tratar como un solo paso de la canalización en otra canalización. Un paso de canalización no es necesariamente una canalización, pero una canalización en sí misma es al menos un paso de canalización por definición.
  • Gráficos acíclicos dirigidos (DAG) . La salida de un paso de canalización puede enviarse a muchos otros pasos, y luego las salidas resultantes pueden recombinarse, y así sucesivamente. Nota al margen: a pesar de que los pipelines son acíclicos, pueden procesar varios elementos uno por uno, y si su estado cambia (por ejemplo, usando el método fit_transform cada vez), entonces pueden verse como un desarrollo recurrente en el tiempo, manteniendo sus estados (piense como un RNN). Esa es una forma interesante de ver las canalizaciones para el aprendizaje en línea al ponerlas en producción y capacitarlas en más datos.

Métodos de una canalización de Scikit-Learn

Las canalizaciones (o pasos en la canalización) deben tener esos dos métodos :

  • " Encajar " para aprender sobre los datos y adquirir el estado (por ejemplo: los pesos neuronales de la red neuronal son ese estado)
  • " Transformar " (o "predecir") para procesar realmente los datos y generar una predicción.

También es posible llamar a este método para encadenar ambos:

  • Fit_transform ” para ajustar y luego transformar los datos, pero en una sola pasada, lo que permite posibles optimizaciones de código cuando los dos métodos deben realizarse uno tras otro directamente.

Problemas de la clase sklearn.pipeline.Pipeline

El patrón de diseño de “tubería y filtro” de Scikit-Learn es simplemente hermoso. Pero, ¿cómo usarlo para Deep Learning, AutoML y canalizaciones complejas a nivel de producción?

Scikit-Learn tuvo su primer lanzamiento en 2007, que fue una era previa al aprendizaje profundo . Sin embargo, es una de las bibliotecas de aprendizaje automático más conocidas y adoptadas, y aún está creciendo. Además de todo, utiliza el patrón de diseño de tuberías y filtros como estilo de arquitectura de software: es lo que hace que Scikit-Learn sea tan fabuloso, además del hecho de que proporciona algoritmos listos para usar. Sin embargo, tiene problemas enormes cuando se trata de hacer lo siguiente, que ya deberíamos poder hacer en 2020:

  • Aprendizaje automático automático (AutoML),
  • Canalizaciones de aprendizaje profundo,
  • Canalizaciones de aprendizaje automático más complejas.

Soluciones que hemos encontrado para los problemas de Scikit-Learn

Sin duda, Scikit-Learn es muy conveniente y está bien construido. Sin embargo, necesita una actualización. ¡Aquí están nuestras soluciones con Neuraxle para hacer que Scikit-Learn sea nuevo y utilizable en proyectos informáticos modernos!

Funciones y métodos de canalización adicionales ofrecidos a través de Neuraxle

Nota: si un paso de una canalización no necesita tener uno de los métodos de ajuste o transformación, podría heredar de NonFittableMixin o NonTransformableMixin para recibir una implementación predeterminada de uno de esos métodos para no hacer nada.

Como punto de partida, es posible que las canalizaciones o sus pasos también definan opcionalmente esos métodos :

  • " Configuración " que llamará al método de "configuración" en cada uno de sus pasos. Por ejemplo, si un paso contiene una red neuronal TensorFlow, PyTorch o Keras, los pasos podrían crear sus gráficos neuronales y registrarlos en la GPU en el método de "configuración" antes de ajustar. Se desaconseja crear los gráficos directamente en los constructores de los pasos por varias razones, como si los pasos se copian antes de ejecutarse muchas veces con diferentes hiperparámetros dentro de un algoritmo de aprendizaje automático automático que busca los mejores hiperparámetros para usted.
  • Desmontaje ”, que es lo opuesto al método de “configuración”: borra recursos.

Los siguientes métodos se proporcionan de forma predeterminada para permitir la gestión de hiperparámetros:

  • " Get_hyperparams " le devolverá un diccionario de los hiperparámetros. Si su canalización contiene más canalizaciones (canalizaciones anidadas), las claves de los hiperparámetros están encadenadas con separadores de subrayado doble “__”.
  • " Set_hyperparams " le permitirá establecer nuevos hiperparámetros en el mismo formato en el que los obtiene.
  • Get_hyperparams_space ” le permite obtener el espacio del hiperparámetro, que no estará vacío si definió uno. Entonces, la única diferencia con "get_hyperparams" aquí es que obtendrá distribuciones estadísticas como valores en lugar de un valor preciso. Por ejemplo, un hiperparámetro para el número de capas podría ser a, lo RandInt(1, 3)que significa de 1 a 3 capas. Puedes llamar.rvs() utilizar este dict para elegir un valor al azar y enviarlo a "set_hyperparams" para intentar entrenarlo.
  • Set_hyperparams_space ” se puede usar para establecer un nuevo espacio usando las mismas clases de distribución de hiperparámetros que en “get_hyperparams_space”.

Para obtener más información sobre nuestras soluciones sugeridas, lea las entradas en la lista grande con enlaces arriba.

Guillaume Chevalier
fuente