Lutando para integrar sklearn e pandas na tarefa simples do Kaggle


7

Estou tentando usar o módulo sklearn_pandas para estender o trabalho que faço nos pandas e mergulhar no aprendizado de máquina, mas estou com um erro que realmente não entendo como corrigir.

Eu estava trabalhando no seguinte conjunto de dados no Kaggle .

É essencialmente uma tabela sem cabeçalho (1000 linhas, 40 recursos) com valores de ponto flutuante.

import pandas as pdfrom sklearn import neighbors
from sklearn_pandas import DataFrameMapper, cross_val_score
path_train ="../kaggle/scikitlearn/train.csv"
path_labels ="../kaggle/scikitlearn/trainLabels.csv"
path_test = "../kaggle/scikitlearn/test.csv"

train = pd.read_csv(path_train, header=None)
labels = pd.read_csv(path_labels, header=None)
test = pd.read_csv(path_test, header=None)
mapper_train = DataFrameMapper([(list(train.columns),neighbors.KNeighborsClassifier(n_neighbors=3))])
mapper_train

Resultado:

DataFrameMapper(features=[([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39], KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
       n_neighbors=3, p=2, weights='uniform'))])

Por enquanto, tudo bem. Mas então eu tento o ajuste

mapper_train.fit_transform(train, labels)

Resultado:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-e3897d6db1b5> in <module>()
----> 1 mapper_train.fit_transform(train, labels)

//anaconda/lib/python2.7/site-packages/sklearn/base.pyc in fit_transform(self, X, y,     **fit_params)
    409         else:
    410             # fit method of arity 2 (supervised transformation)
--> 411             return self.fit(X, y, **fit_params).transform(X)
    412 
    413 

//anaconda/lib/python2.7/site-packages/sklearn_pandas/__init__.pyc in fit(self, X, y)
    116         for columns, transformer in self.features:
    117             if transformer is not None:
--> 118                 transformer.fit(self._get_col_subset(X, columns))
    119         return self
    120 

TypeError: fit() takes exactly 3 arguments (2 given)`

O que estou fazendo errado? Embora os dados neste caso sejam todos iguais, estou planejando criar um fluxo de trabalho para misturas de recursos de ponto categórico, nominal e de ponto flutuante e sklearn_pandas parecia um ajuste lógico.


11
Sua segunda importação não está recuada corretamente. Eu mesmo corrigiria o código se a edição fosse longa o suficiente.
logc 07/07

Respostas:


6

Aqui está um exemplo de como obter pandas e aprender a jogar bem

digamos que você tenha 2 colunas que são ambas cadeias e deseja vetorizar - mas não tem idéia de quais parâmetros de vetorização resultarão no melhor desempenho a jusante.

crie o vetorizador

to_vect = Pipeline([('vect',CountVectorizer(min_df =1,max_df=.9,ngram_range=(1,2),max_features=1000)),
                    ('tfidf', TfidfTransformer())])

crie o objeto DataFrameMapper.

full_mapper = DataFrameMapper([
        ('col_name1', to_vect),
        ('col_name2',to_vect)
    ])

este é o pipeline completo

full_pipeline  = Pipeline([('mapper',full_mapper),('clf', SGDClassifier(n_iter=15, warm_start=True))])

defina os parâmetros que você deseja que a verificação considere

full_params = {'clf__alpha': [1e-2,1e-3,1e-4],
                   'clf__loss':['modified_huber','hinge'],
                   'clf__penalty':['l2','l1'],
                   'mapper__features':[[('col_name1',deepcopy(to_vect)),
                                        ('col_name2',deepcopy(to_vect))],
                                       [('col_name1',deepcopy(to_vect).set_params(vect__analyzer= 'char_wb')),
                                        ('col_name2',deepcopy(to_vect))]]}

É isso aí! - observe, no entanto, que mapper_features é um item único neste dicionário - portanto, use um loop for ou itertools.product para gerar uma lista FLAT de todas as opções to_vect que você deseja considerar - mas essa é uma tarefa separada fora do escopo da pergunta.

Continue criando o classificador ideal ou o que mais o seu pipeline terminar com

gs_clf = GridSearchCV(full_pipe, full_params, n_jobs=-1)

7

Eu nunca usei sklearn_pandas, mas ao ler o código-fonte, parece que isso é um bug do lado deles. Se você procurar a função que está lançando a exceção , poderá observar que elas estão descartando o yargumento (ele nem sobrevive até a sequência de caracteres), e a fitfunção interna espera mais um argumento, o que provavelmente é y:

def fit(self, X, y=None):
    '''
    Fit a transformation from the pipeline

    X       the data to fit
    '''
    for columns, transformer in self.features:
        if transformer is not None:
            transformer.fit(self._get_col_subset(X, columns))
    return self

Eu recomendo que você abra um problema no rastreador de erros .

ATUALIZAÇÃO :

Você pode testar isso se executar seu código no IPython. Para resumir, se você usar a %pdb onmágica imediatamente antes de executar a chamada problemática, a exceção será capturada pelo depurador Python, para que você possa brincar um pouco e ver se a chamada da fitfunção com os valores de rótulo y[0]funciona - veja a última linha com o pdb>prompt. (Os arquivos CSV são baixados do Kaggle, exceto o maior, que é apenas uma parte do arquivo real).

In [1]: import pandas as pd

In [2]: from sklearn import neighbors

In [3]: from sklearn_pandas import DataFrameMapper, cross_val_score

In [4]: path_train ="train.csv"

In [5]: path_labels ="trainLabels.csv"

In [6]: path_test = "test.csv"

In [7]: train = pd.read_csv(path_train, header=None)

In [8]: labels = pd.read_csv(path_labels, header=None)

In [9]: test = pd.read_csv(path_test, header=None)

In [10]: mapper_train = DataFrameMapper([(list(train.columns),neighbors.KNeighborsClassifier(n_neighbors=3))])

In [13]: %pdb on

In [14]: mapper_train.fit_transform(train, labels)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-e3897d6db1b5> in <module>()
----> 1 mapper_train.fit_transform(train, labels)

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sklearn/base.pyc in fit_transform(self, X, y, **fit_params)
    409         else:
    410             # fit method of arity 2 (supervised transformation)
--> 411             return self.fit(X, y, **fit_params).transform(X)
    412
    413

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sklearn_pandas/__init__.pyc in fit(self, X, y)
    116         for columns, transformer in self.features:
    117             if transformer is not None:
--> 118                 transformer.fit(self._get_col_subset(X, columns))
    119         return self
    120

TypeError: fit() takes exactly 3 arguments (2 given)
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sklearn_pandas/__init__.py(118)fit()
    117             if transformer is not None:
--> 118                 transformer.fit(self._get_col_subset(X, columns))
    119         return self

ipdb> l
    113
    114         X       the data to fit
    115         '''
    116         for columns, transformer in self.features:
    117             if transformer is not None:
--> 118                 transformer.fit(self._get_col_subset(X, columns))
    119         return self
    120
    121
    122     def transform(self, X):
    123         '''
ipdb> transformer.fit(self._get_col_subset(X, columns), y[0])
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           n_neighbors=3, p=2, weights='uniform')

Obrigado. Eu não saberia o que causou isso. Eu só sei que na maioria das vezes é o meu trabalho que é a culpa :)
elksie5000

@ elksie5000: adicionei como depurar a chamada. Espero que a última chamada seja o que você esperaria de uma chamada bem-sucedida para a função (?). Caso contrário, é sempre bom saber como passo para o código com pdb:)
logC

Devo admitir que pdb era algo que eu estava olhando novamente depois de trabalhar no livro Python for Data Analysis de Wes McKinney. Eu já trabalho no IPython, mas estava razoavelmente satisfeito com as instruções de impressão. Mais uma vez obrigado.
precisa saber é o seguinte

Como uma observação lateral, o prompt do depurador diz "ipdb" porque é o depurador ipython - esta é uma instalação extra na minha instalação. Sob circunstâncias normais, seria o pdb comum chamado. Só notei essa diferença.
logc 07/07
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.