Python - o que é exatamente sklearn.pipeline.Pipeline?

118

Não consigo descobrir como sklearn.pipeline.Pipelinefunciona exatamente.

Existem algumas explicações no documento . Por exemplo, o que eles querem dizer com:

Pipeline de transformações com um estimador final.

Para deixar minha pergunta mais clara, quais são steps? Como eles funcionam?

Editar

Graças às respostas, posso deixar minha pergunta mais clara:

Quando eu chamo o pipeline e passo, como etapas, dois transformadores e um estimador, por exemplo:

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

O que acontece quando eu ligo para isso?

pipln.fit()
OR
pipln.fit_transform()

Não consigo descobrir como um estimador pode ser um transformador e como um transformador pode ser instalado.

farhawa
fonte
3
Pelo que entendi, o pipeline ajuda a automatizar várias etapas do processo de aprendizagem. Como o treinamento e teste de modelos ou seleção de recursos ... Então, se você quiser misturar uma regressão e usá-la para alimentar um classificador, por exemplo, seus passos serão o treinamento daquela regressão e depois do classificador. editar: adicionar detalhes
M0rkHaV
1
queirozf.com/entries/scikit-learn-pipeline-examples Achei isso útil
randomSampling

Respostas:

180

Transformer no scikit-learn - alguma classe que possui o método fit e transform ou o método fit_transform.

Predictor - alguma classe que possui métodos de ajuste e predição ou método fit_predict.

Pipeline é apenas uma noção abstrata, não é um algoritmo de ml existente. Freqüentemente, em tarefas de ML, você precisa realizar uma sequência de transformações diferentes (encontrar o conjunto de recursos, gerar novos recursos, selecionar apenas alguns recursos bons) do conjunto de dados bruto antes de aplicar o estimador final.

Aqui está um bom exemplo de uso de pipeline. O Pipeline oferece uma única interface para todas as 3 etapas de transformação e o estimador resultante. Ele encapsula transformadores e preditores dentro, e agora você pode fazer 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)

Com apenas:

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)

Com pipelines, você pode facilmente realizar uma pesquisa em grade sobre um conjunto de parâmetros para cada etapa deste metaestimador. Conforme descrito no link acima. Todas as etapas, exceto a última, devem ser transformações, a última etapa pode ser transformador ou preditor. Resposta para editar : Quando você chama pipln.fit()- cada transformador dentro do pipeline será encaixado nas saídas do transformador anterior (o primeiro transformador é aprendido no conjunto de dados bruto). O último estimador pode ser transformador ou preditor, você pode chamar fit_transform () no pipeline apenas se seu último estimador for transformador (que implementa fit_transform ou métodos de transformação e ajuste separadamente), você pode chamar fit_predict () ou predizer () no pipeline apenas se seu último estimador é o preditor. Portanto, você simplesmente não pode chamar fit_transform ou transformar no pipeline, a última etapa é o preditor.

Ibraim Ganiev
fonte
1
O que você quer dizer com predicted = pipeline.fit(Xtrain).predict(Xtrain)?
farhawa
@farhawa, prevendo aulas no conjunto de treinamento.
Ibraim Ganiev
4
Por que isso não tem mais votos? Deve ser uma postagem no blog.
R Claven
1
@iamgin, a interface da maioria dos transformadores scikit-learn não permite escolher as colunas necessárias que queremos transformar. Mas você pode escrever seu próprio "Item Selector", que o ajudará a alimentar o transformador apenas com as colunas necessárias. Aqui está um bom exemplo com ItemSelector e FeatureUnion scikit-learn.org/stable/auto_examples/…
Ibraim Ganiev
1
No primeiro exemplo, você não quer evitar o ajuste novamente com o conjunto de teste? Não deveria estar chamando apenas transform em vez de fit_transform? E da mesma forma, o pipeline prevê internamente chamar fit_transform ou apenas transformar? Pode ser controlado?
Steven
18

Acho que M0rkHaV tem a ideia certa. Classe pipeline da scikit-learn é uma ferramenta útil para encapsular vários transformadores diferentes ao lado de um estimador em um objeto, de modo que você só tem que chamar seus métodos importantes uma vez ( fit(), predict(), etc). Vamos dividir os dois componentes principais:

  1. Transformers são classes que implementam fit()e transform(). Você deve estar familiarizado com algumas das ferramentas de pré-processamento do sklearn, como TfidfVectorizere Binarizer. Se você olhar a documentação dessas ferramentas de pré-processamento, verá que elas implementam ambos os métodos. O que eu acho muito legal é que alguns estimadores também podem ser usados ​​como etapas de transformação, por exemplo LinearSVC!

  2. Estimadores são classes que implementam ambos fit()e predict(). Você descobrirá que muitos dos classificadores e modelos de regressão implementam esses dois métodos e, como tal, pode testar prontamente muitos modelos diferentes. É possível usar outro transformador como o estimador final (ou seja, não necessariamente implementa predict(), mas definitivamente implementa fit()). Tudo isso significa que você não conseguiria ligar predict().

Quanto à sua edição: vamos examinar um exemplo baseado em texto. Usando LabelBinarizer, queremos transformar uma lista de rótulos em uma lista de valores binários.

bin = LabelBinarizer()  #first we initialize

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

Agora, quando o binarizador for encaixado em alguns dados, ele terá uma estrutura chamada classes_que contém as classes exclusivas que o transformador 'conhece'. Sem chamar fit()o binarizador não tem ideia de como os dados se parecem, então chamar transform()não faria sentido. Isso é verdade se você imprimir a lista de classes antes de tentar ajustar os dados.

print bin.classes_  

Recebo o seguinte erro ao tentar isso:

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

Mas quando você coloca o binarizador na veclista:

bin.fit(vec)

e tente novamente

print bin.classes_

Eu obtenho o seguinte:

['cat' 'dog']


print bin.transform(vec)

E agora, depois de chamar transform no vecobjeto, obtemos o seguinte:

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

Quanto aos estimadores sendo usados ​​como transformadores, vamos usar o DecisionTreeclassificador como um exemplo de extrator de características. Árvores de decisão são ótimas por vários motivos, mas, para nossos objetivos, o importante é que elas têm a capacidade de classificar recursos que a árvore considerou úteis para previsão. Quando você chama transform()uma árvore de decisão, ela pega seus dados de entrada e encontra o que pensa ser os recursos mais importantes. Portanto, você pode pensar em transformar sua matriz de dados (n linhas por m colunas) em uma matriz menor (n linhas por k colunas), onde as k colunas são as k características mais importantes que a Árvore de Decisão encontrou.

NBartley
fonte
Qual é a diferença entre fit()e transform()são os Transformers? , como estimadores podem ser usados ​​como transformadores?
farhawa
2
fit()é o método que você chama para ajustar ou 'treinar' seu transformador, como faria com um classificador ou modelo de regressão. Quanto a transform(), esse é o método que você chama para realmente transformar os dados de entrada em dados de saída. Por exemplo, chamar Binarizer.transform([8,2,2])(após o ajuste!) Pode resultar em [[1,0],[0,1],[0,1]]. Quanto ao uso de estimadores como transformadores, vou editar um pequeno exemplo em minha resposta.
NBartley
9

Os algoritmos de ML geralmente processam dados tabulares. Você pode querer fazer o pré-processamento e o pós-processamento desses dados antes e depois do algoritmo de ML. Um pipeline é uma forma de encadear essas etapas de processamento de dados.

O que são pipelines de ML e como funcionam?

Um pipeline é uma série de etapas nas quais os dados são transformados. Ele vem do antigo padrão de design "tubo e filtro" (por exemplo, você pode pensar em comandos bash unix com tubos “|” ou operadores de redirecionamento “>”). No entanto, os pipelines são objetos no código. Assim, você pode ter uma classe para cada filtro (também conhecido como cada etapa do pipeline) e, em seguida, outra classe para combinar essas etapas no pipeline final. Alguns pipelines podem combinar outros pipelines em série ou em paralelo, ter várias entradas ou saídas e assim por diante. Gostamos de ver os pipelines de aprendizado de máquina como:

  • Tubulação e filtros . As etapas do pipeline processam dados e gerenciam seu estado interno, que pode ser aprendido a partir dos dados.
  • Compósitos . Os pipelines podem ser aninhados: por exemplo, um pipeline inteiro pode ser tratado como uma única etapa do pipeline em outro pipeline. Uma etapa de pipeline não é necessariamente um pipeline, mas um pipeline é, por definição, pelo menos uma etapa de pipeline.
  • Gráficos acíclicos dirigidos (DAG) . A saída de uma etapa do pipeline pode ser enviada para muitas outras etapas e, em seguida, as saídas resultantes podem ser recombinadas e assim por diante. Nota lateral: apesar dos pipelines serem acíclicos, eles podem processar vários itens um por um, e se seu estado mudar (por exemplo: usando o método fit_transform a cada vez), eles podem ser vistos como se desdobrando recorrentemente ao longo do tempo, mantendo seus estados (pense como um RNN). Essa é uma maneira interessante de ver os canais de aprendizagem online ao colocá-los em produção e treiná-los em mais dados.

Métodos de um pipeline Scikit-Learn

Pipelines (ou etapas no pipeline) devem ter esses dois métodos :

  • Apto ” para aprender sobre os dados e adquirir o estado (por exemplo: os pesos neurais da rede neural são esse estado)
  • " Transformar " (ou "prever") para realmente processar os dados e gerar uma previsão.

Também é possível chamar este método para encadear ambos:

  • Fit_transform ” para ajustar e transformar os dados, mas em uma passagem, o que permite otimizações de código em potencial quando os dois métodos devem ser executados um após o outro diretamente.

Problemas da classe sklearn.pipeline.Pipeline

O padrão de design “tubo e filtro” do Scikit-Learn é simplesmente lindo. Mas como usá-lo para Deep Learning, AutoML e pipelines de nível de produção complexos?

O Scikit-Learn teve seu primeiro lançamento em 2007, que era uma era pré-aprendizado profundo . No entanto, é uma das bibliotecas de aprendizado de máquina mais conhecidas e adotadas e ainda está crescendo. Acima de tudo, ele usa o padrão de design Pipe e Filter como um estilo de arquitetura de software - é o que torna o Scikit-Learn tão fabuloso, somado ao fato de fornecer algoritmos prontos para uso. No entanto, ele tem grandes problemas quando se trata de fazer o seguinte, o que deveríamos ser capazes de fazer em 2020:

  • Aprendizado de máquina automático (AutoML),
  • Deep Learning Pipelines,
  • Pipelines de aprendizado de máquina mais complexos.

Soluções que encontramos para os problemas do Scikit-Learn

Com certeza, o Scikit-Learn é muito conveniente e bem construído. No entanto, ele precisa ser atualizado. Aqui estão nossas soluções com Neuraxle para tornar o Scikit-Learn novo e utilizável em projetos de computação modernos!

Métodos e recursos adicionais de pipeline oferecidos por meio do Neuraxle

Nota: se uma etapa de um pipeline não precisa ter um dos métodos de ajuste ou transformação, ela pode herdar de NonFittableMixin ou NonTransformableMixin para ser fornecida uma implementação padrão de um desses métodos para não fazer nada.

Para começar, é possível que os pipelines ou suas etapas também definam opcionalmente esses métodos :

  • Setup ” que chamará o método “setup” em cada uma de suas etapas. Por exemplo, se uma etapa contém uma rede neural TensorFlow, PyTorch ou Keras, as etapas podem criar seus gráficos neurais e registrá-los na GPU no método de "configuração" antes do ajuste. Não é recomendável criar os gráficos diretamente nos construtores das etapas por vários motivos, como se as etapas fossem copiadas antes de serem executadas muitas vezes com diferentes hiperparâmetros em um algoritmo de Aprendizado de Máquina Automático que procura os melhores hiperparâmetros para você.
  • Desmontagem ”, que é o oposto do método “setup”: limpa recursos.

Os seguintes métodos são fornecidos por padrão para permitir o gerenciamento de hiperparâmetros:

  • Get_hyperparams ” retornará um dicionário dos hiperparâmetros. Se o pipeline contiver mais pipelines (pipelines aninhados), as chaves do hiperparâmetro serão encadeadas com sublinhados duplos separadores “__”.
  • Set_hyperparams ” permitirá que você defina novos hiperparâmetros no mesmo formato de quando você os obteve.
  • Get_hyperparams_space ” permite que você obtenha o espaço do hiperparâmetro, que não estará vazio se você definiu um. Portanto, a única diferença com “get_hyperparams” aqui é que você obterá distribuições estatísticas como valores em vez de um valor preciso. Por exemplo, um hiperparâmetro para o número de camadas pode ser a, o RandInt(1, 3)que significa 1 a 3 camadas. Você pode chamar .rvs()este dict para escolher um valor aleatoriamente e enviá-lo para “set_hyperparams” para tentar treinar nele.
  • Set_hyperparams_space ” pode ser usado para definir um novo espaço usando as mesmas classes de distribuição de hiperparâmetros como em “get_hyperparams_space”.

Para mais informações sobre nossas soluções sugeridas, leia as entradas na grande lista com os links acima.

Guillaume Chevalier
fonte