Python - Cos'è esattamente sklearn.pipeline.Pipeline?


118

Non riesco a capire come sklearn.pipeline.Pipelinefunziona esattamente.

Ci sono alcune spiegazioni nel documento . Ad esempio cosa intendono per:

Pipeline di trasformazioni con uno stimatore finale.

Per rendere più chiara la mia domanda, cosa sono steps? Come funzionano?

modificare

Grazie alle risposte posso rendere più chiara la mia domanda:

Quando chiamo pipeline e passo, come passaggi, due trasformatori e uno stimatore, ad esempio:

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

Cosa succede quando lo chiamo?

pipln.fit()
OR
pipln.fit_transform()

Non riesco a capire come uno stimatore possa essere un trasformatore e come possa essere montato un trasformatore.


3
Da quello che ho capito, la pipeline ti aiuta ad automatizzare diverse fasi del processo di apprendimento. Come l'addestramento e il test di modelli o la selezione di funzionalità ... Quindi, se si desidera combinare una regressione, utilizzarla per alimentare un classificatore, ad esempio, i passaggi saranno l'addestramento di quella regressione e quindi del classificatore. modifica: aggiungi dettagli
M0rkHaV

Risposte:


180

Transformer in scikit-learn - alcune classi che hanno il metodo fit and transform o il metodo fit_transform

Predittore : una classe che ha metodi di adattamento e previsione o metodo fit_predict.

Pipeline è solo una nozione astratta, non è un algoritmo ml esistente. Spesso nelle attività ML è necessario eseguire sequenze di diverse trasformazioni (trovare un insieme di funzionalità, generare nuove funzionalità, selezionare solo alcune buone funzionalità) del set di dati grezzi prima di applicare lo stimatore finale.

Ecco un buon esempio di utilizzo della pipeline. Pipeline offre un'unica interfaccia per tutti e 3 i passaggi della trasformazione e lo stimatore risultante. Incapsula trasformatori e predittori al suo interno e ora puoi fare qualcosa come:

    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 le pipeline puoi facilmente eseguire una ricerca griglia su un insieme di parametri per ogni fase di questo meta-estimatore. Come descritto nel collegamento sopra. Tutti i passaggi tranne l'ultimo devono essere trasformazioni, l'ultimo passaggio può essere trasformatore o predittore. Risposta per modificare : quando si chiama pipln.fit(), ogni trasformatore all'interno della pipeline verrà montato sulle uscite del trasformatore precedente (il primo trasformatore viene appreso sul set di dati non elaborato). L'ultimo stimatore può essere trasformatore o predittore, puoi chiamare fit_transform () sulla pipeline solo se il tuo ultimo stimatore è trasformatore (che implementa i metodi fit_transform o transform and fit separatamente), puoi chiamare fit_predict () o forecast () sulla pipeline solo se il tuo ultimo stimatore è predittore. Quindi non puoi chiamare fit_transform o transform on pipeline, l'ultimo passaggio di cui è predittore.


1
Cosa intendi con predicted = pipeline.fit(Xtrain).predict(Xtrain)?
farhawa

@farhawa, previsione delle lezioni sul set di allenamento.
Ibraim Ganiev

4
Perché questo non ha più voti? Dovrebbe essere un post sul blog.
R Claven

1
@iamgin, l'interfaccia della maggior parte dei trasformatori di scikit-learn non consente di scegliere le colonne necessarie che vogliamo trasformare. Ma puoi scrivere il tuo "Selettore articolo", che ti aiuterà ad alimentare il trasformatore solo con le colonne necessarie. Ecco un buon esempio con ItemSelector e FeatureUnion scikit-learn.org/stable/auto_examples/…
Ibraim Ganiev

1
Nel primo esempio, non vuoi evitare di adattarti nuovamente al set di prova? Non dovrebbe chiamare solo transform invece di fit_transform? Allo stesso modo, la pipeline prevede la chiamata interna fit_transform o semplicemente trasforma? Può essere controllato?
Steven

18

Penso che M0rkHaV abbia l'idea giusta. Scikit-learn della classe gasdotto è uno strumento utile per incapsulare più trasformatori diversi a fianco di un estimatore in un unico oggetto, in modo da avere solo per chiamare i tuoi metodi importanti una volta ( fit(), predict(), ecc). Analizziamo le due componenti principali:

  1. I trasformatori sono classi che implementano sia fit()e transform(). Potresti avere familiarità con alcuni degli strumenti di preelaborazione sklearn, come TfidfVectorizere Binarizer. Se guardi la documentazione di questi strumenti di preelaborazione, vedrai che implementano entrambi questi metodi. Quello che trovo piuttosto interessante è che alcuni stimatori possono essere utilizzati anche come passaggi di trasformazione, ad esempio LinearSVC!

  2. Gli stimatori sono classi che implementano sia fit()e predict(). Scoprirai che molti dei classificatori e dei modelli di regressione implementano entrambi questi metodi e come tali puoi testare prontamente molti modelli diversi. È possibile utilizzare un altro trasformatore come stimatore finale (cioè, non necessariamente implementa predict(), ma sicuramente implementa fit()). Tutto ciò significa che non saresti in grado di chiamare predict().

Per quanto riguarda la tua modifica: esaminiamo un esempio basato su testo. Utilizzando LabelBinarizer, vogliamo trasformare un elenco di etichette in un elenco di valori binari.

bin = LabelBinarizer()  #first we initialize

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

Ora, quando il binarizzatore viene adattato su alcuni dati, avrà una struttura chiamata classes_che contiene le classi uniche di cui il trasformatore "conosce". Senza chiamare fit()il binarizzatore non ha idea di come siano i dati, quindi chiamare transform()non avrebbe alcun senso. Questo è vero se si stampa l'elenco delle classi prima di provare ad adattare i dati.

print bin.classes_  

Ottengo il seguente errore quando provo questo:

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

Ma quando inserisci il binarizzatore vecnell'elenco:

bin.fit(vec)

e prova ancora

print bin.classes_

Ottengo quanto segue:

['cat' 'dog']


print bin.transform(vec)

E ora, dopo aver chiamato la trasformazione vecsull'oggetto, otteniamo quanto segue:

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

Per quanto riguarda gli stimatori usati come trasformatori, usiamo il DecisionTreeclassificatore come esempio di un estrattore di caratteristiche. Gli alberi decisionali sono ottimi per molte ragioni, ma per i nostri scopi, ciò che è importante è che abbiano la capacità di classificare le caratteristiche che l' albero ha trovato utili per la previsione. Quando si richiama transform()un albero decisionale, esso prenderà i dati di input e troverà quelle che ritiene siano le caratteristiche più importanti. Quindi puoi pensare di trasformare la tua matrice di dati (n righe per m colonne) in una matrice più piccola (n righe per k colonne), dove le k colonne sono le k caratteristiche più importanti trovate dall'albero decisionale.


Qual è la differenza tra fit()e transform()è i Transformers? , come si possono utilizzare gli stimatori come trasformatori?
farhawa

2
fit()è il metodo che chiami per adattare o "addestrare" il tuo trasformatore, come faresti con un classificatore o un modello di regressione. Per quanto riguarda transform(), questo è il metodo che chiami per trasformare effettivamente i dati di input nei dati di output. Ad esempio, la chiamata Binarizer.transform([8,2,2])(dopo l'adattamento!) Potrebbe risultare in [[1,0],[0,1],[0,1]]. Per quanto riguarda l'utilizzo di stimatori come trasformatori, modifico un breve esempio nella mia risposta.
NBartley

9

Gli algoritmi ML elaborano tipicamente dati tabulari. Potresti voler eseguire la pre-elaborazione e la post-elaborazione di questi dati prima e dopo il tuo algoritmo ML. Una pipeline è un modo per concatenare queste fasi di elaborazione dei dati.

Cosa sono le pipeline ML e come funzionano?

Una pipeline è una serie di passaggi in cui i dati vengono trasformati. Deriva dal vecchio design pattern "pipe e filtro" (per esempio, potresti pensare a comandi bash unix con pipe "|" o operatori di reindirizzamento ">"). Tuttavia, le pipeline sono oggetti nel codice. Pertanto, potresti avere una classe per ogni filtro (ovvero ogni passaggio della pipeline) e quindi un'altra classe per combinare questi passaggi nella pipeline finale. Alcune pipeline possono combinare altre pipeline in serie o in parallelo, avere più input o output e così via. Ci piace vedere le pipeline di Machine Learning come:

  • Tubo e filtri . I passaggi della pipeline elaborano i dati e gestiscono il loro stato interno che può essere appreso dai dati.
  • Compositi . Le pipeline possono essere nidificate: ad esempio, un'intera pipeline può essere trattata come un singolo passaggio della pipeline in un'altra pipeline. Un passaggio della pipeline non è necessariamente una pipeline, ma una pipeline è essa stessa almeno un passaggio della pipeline per definizione.
  • Grafici aciclici diretti (DAG) . L'output di un passaggio della pipeline può essere inviato a molti altri passaggi, quindi gli output risultanti possono essere ricombinati e così via. Nota a margine: nonostante le pipeline siano acicliche, possono elaborare più elementi uno per uno e se il loro stato cambia (ad esempio: utilizzando il metodo fit_transform ogni volta), possono essere visti come ricorrenti nel tempo, mantenendo i loro stati (pensa come un RNN). È un modo interessante per vedere le pipeline per l'apprendimento online quando le si mette in produzione e si addestra su più dati.

Metodi di una pipeline Scikit-Learn

Le pipeline (o passaggi nella pipeline) devono avere questi due metodi :

  • " Fit " per apprendere sui dati e acquisire lo stato (es: i pesi neurali della rete neurale sono tale stato)
  • " Trasformare " (o "prevedere") per elaborare effettivamente i dati e generare una previsione.

È anche possibile chiamare questo metodo per concatenare entrambi:

  • " Fit_transform " per adattare e quindi trasformare i dati, ma in un passaggio, il che consente potenziali ottimizzazioni del codice quando i due metodi devono essere eseguiti uno dopo l'altro direttamente.

Problemi della classe sklearn.pipeline.Pipeline

Il design pattern "pipe and filter" di Scikit-Learn è semplicemente bellissimo. Ma come utilizzarlo per Deep Learning, AutoML e pipeline complesse a livello di produzione?

Scikit-Learn è uscito per la prima volta nel 2007, un'era pre-deep learning . Tuttavia, è una delle librerie di machine learning più conosciute e adottate ed è ancora in crescita. Soprattutto, utilizza il modello di progettazione di tubi e filtri come stile architettonico del software: è ciò che rende Scikit-Learn così favoloso, oltre al fatto che fornisce algoritmi pronti per l'uso. Tuttavia, ha enormi problemi quando si tratta di fare quanto segue, cosa che dovremmo essere in grado di fare già nel 2020:

  • Apprendimento automatico automatico (AutoML),
  • Pipeline di deep learning,
  • Pipeline di Machine Learning più complesse.

Soluzioni che abbiamo trovato a quei problemi di Scikit-Learn

Di sicuro, Scikit-Learn è molto comodo e ben costruito. Tuttavia, ha bisogno di un aggiornamento. Ecco le nostre soluzioni con Neuraxle per rendere Scikit-Learn fresco e utilizzabile nei progetti informatici moderni!

Metodi di pipeline e funzionalità aggiuntivi offerti tramite Neuraxle

Nota: se un passaggio di una pipeline non necessita di uno dei metodi di adattamento o trasformazione, potrebbe ereditare da NonFittableMixin o NonTransformableMixin per ricevere un'implementazione predefinita di uno di questi metodi per non eseguire alcuna operazione.

Per iniziare, è possibile che le pipeline oi relativi passaggi definiscano anche facoltativamente tali metodi :

  • " Setup " che chiamerà il metodo "setup" in ciascuno dei suoi passaggi. Ad esempio, se un passaggio contiene una rete neurale TensorFlow, PyTorch o Keras, i passaggi potrebbero creare i loro grafici neurali e registrarli sulla GPU nel metodo di "configurazione" prima dell'adattamento. È sconsigliato creare i grafici direttamente nei costruttori dei passaggi per diversi motivi, ad esempio se i passaggi vengono copiati prima di essere eseguiti più volte con diversi iperparametri all'interno di un algoritmo di Machine Learning automatico che cerca i migliori iperparametri per te.
  • " Smontaggio ", che è l'opposto del metodo "setup": cancella le risorse.

I seguenti metodi vengono forniti per impostazione predefinita per consentire la gestione degli iperparametri:

  • " Get_hyperparams " ti restituirà un dizionario degli iperparametri. Se la pipeline contiene più pipeline (pipeline nidificate), le chiavi dell'iperparametro vengono concatenate con doppi caratteri di sottolineatura "__" separatori.
  • " Set_hyperparams " ti permetterà di impostare nuovi iperparametri nello stesso formato di quando li ottieni.
  • " Get_hyperparams_space " ti permette di ottenere lo spazio dell'iperparametro, che non sarà vuoto se ne hai definito uno. Quindi, l'unica differenza con "get_hyperparams" qui è che otterrai distribuzioni statistiche come valori invece di un valore preciso. Ad esempio, un iperparametro per il numero di livelli potrebbe essere a RandInt(1, 3)che significa da 1 a 3 livelli. Puoi chiamare .rvs()questo dict per scegliere un valore a caso e inviarlo a "set_hyperparams" per provare ad allenarti su di esso.
  • " Set_hyperparams_space " può essere utilizzato per impostare un nuovo spazio utilizzando le stesse classi di distribuzione di iperparametri di "get_hyperparams_space".

Per maggiori informazioni sulle nostre soluzioni suggerite, leggi le voci nell'elenco grande con i link sopra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.