Scikit-learn: LabelBinarizer e LabelEncoder ajustam e transformam assinaturas não compatíveis com Pipeline

Criado em 26 abr. 2014  ·  6Comentários  ·  Fonte: scikit-learn/scikit-learn

Recebo este erro quando tento usar LabelBinarizer e LabelEncoder em um pipeline:

sklearn/pipeline.pyc in fit_transform(self, X, y, **fit_params)
    141         Xt, fit_params = self._pre_transform(X, y, **fit_params)
    142         if hasattr(self.steps[-1][-1], 'fit_transform'):
--> 143             return self.steps[-1][-1].fit_transform(Xt, y, **fit_params)
    144         else:
    145             return self.steps[-1][-1].fit(Xt, y, **fit_params).transform(Xt)

TypeError: fit_transform() takes exactly 2 arguments (3 given)

Parece que isso ocorre porque as assinaturas de fit e transform das classes são diferentes da maioria dos outros estimadores e aceitam apenas um único argumento.

Acho que essa é uma solução muito fácil (basta alterar a assinatura para def(self, X, y=None) ) para a qual ficaria feliz em enviar uma solicitação de pull, mas gostaria de verificar se há algum outro motivo para as assinaturas serem maneira como eles são que eu não pensei.

API

Comentários muito úteis

Vejo que houve muitas reações negativas nesta página. Eu acho que há um longo mal-entendido sobre o propósito do LabelBinarizer e do LabelEncoder. Estes são para alvos, não recursos. Embora reconhecidamente eles foram projetados (e mal nomeados) antes do meu tempo.

Embora eu ache que os usuários poderiam estar usando CountVectorizer (ou DictVectorizer com dataframe.to_dict(orient='records') se você estiver vindo de um dataframe) para essa finalidade por um longo tempo, recentemente mesclamos um CategoricalEncoder (# 9151 ) no mestre, embora isso possa ser transferido para OneHotEncoer e um novo OrdinalEncoder antes do lançamento (# 10521).

Espero que isso satisfaça as necessidades de uma população claramente insatisfeita.

Devo dizer que, como alguém que tem oferecido enormes quantidades de tempo livre para o desenvolvimento deste projeto há quase cinco anos (e recentemente foi contratado para trabalhar nele também), vendo a magnitude das reações negativas, ao invés de contribuições construtivas para a biblioteca é bastante triste. Embora reconheço que minha resposta acima de que você deve escrever uma nova coisa do tipo Pipeline, em vez de um novo transformador para entradas categóricas, foi um mal-entendido de minha parte (e deveria / poderia ter sido corrigido por outros), que espero que seja compreensível durante o trabalho a enorme carga de trabalho que está mantendo este projeto.

Todos 6 comentários

Acho que você está certo em consertar isso.

Em 26 de abril de 2014 19:37, hxu [email protected] escreveu:

Recebo este erro quando tento usar LabelBinarizer e LabelEncoder em um
Pipeline:

sklearn / pipeline.pyc em fit_transform (self, X, y, * _fit_params)
141 Xt, fit_params = self._pre_transform (X, y, * _fit_params)
142 if hasattr (self.steps [-1] [- 1], 'fit_transform'): -> 143 return self.steps [-1] [- 1] .fit_transform (Xt, y, * _fit_params)
144 mais:
145 return self.steps [-1] [- 1] .fit (Xt, y, * _fit_params) .transform (Xt)
TypeError: fit_transform () recebe exatamente 2 argumentos (3 dados)

Parece que isso ocorre porque as classes de ajuste e transformação de ureshttps: //github.com/scikit-learn/scikit-learn/blob/master/sklearn/preprocessing/label.py#L85são diferentes da maioria dos outros estimadores e só aceitam um único argumento.

Acho que é uma solução muito fácil (basta alterar a assinatura para def (self,
X, y = Nenhum)) que ficaria feliz em enviar uma solicitação de pull, mas eu queria
verifique se há outros motivos pelos quais as assinaturas são como
são que eu não pensei.

-
Responda a este e-mail diretamente ou visualize-o em Gi tHubhttps: //github.com/scikit-learn/scikit-learn/issues/3112
.

Em # 3113, decidimos que isso não deve ser corrigido porque a codificação de rótulo não pertence realmente a Pipeline .

@jnothman , só para saber: o que devo fazer se precisar vetorizar um recurso categórico em um pipeline?

Talvez seja melhor escrever seu próprio código Pipeline-like (talvez herdado do existente) para lidar com seu caso específico.

Em vez de usar LabelBinarizer em um pipeline, apenas implementei meu próprio transformador:

class CustomBinarizer(BaseEstimator, TransformerMixin):
    def fit(self, X, y=None,**fit_params):
        return self
    def transform(self, X):
        return LabelBinarizer().fit(X).transform(X)

Parece funcionar!

editar:

esta é a melhor solução:
https://github.com/scikit-learn/scikit-learn/pull/7375/files#diff -1e175ddb0d84aad0a578d34553f6f9c6

Vejo que houve muitas reações negativas nesta página. Eu acho que há um longo mal-entendido sobre o propósito do LabelBinarizer e do LabelEncoder. Estes são para alvos, não recursos. Embora reconhecidamente eles foram projetados (e mal nomeados) antes do meu tempo.

Embora eu ache que os usuários poderiam estar usando CountVectorizer (ou DictVectorizer com dataframe.to_dict(orient='records') se você estiver vindo de um dataframe) para essa finalidade por um longo tempo, recentemente mesclamos um CategoricalEncoder (# 9151 ) no mestre, embora isso possa ser transferido para OneHotEncoer e um novo OrdinalEncoder antes do lançamento (# 10521).

Espero que isso satisfaça as necessidades de uma população claramente insatisfeita.

Devo dizer que, como alguém que tem oferecido enormes quantidades de tempo livre para o desenvolvimento deste projeto há quase cinco anos (e recentemente foi contratado para trabalhar nele também), vendo a magnitude das reações negativas, ao invés de contribuições construtivas para a biblioteca é bastante triste. Embora reconheço que minha resposta acima de que você deve escrever uma nova coisa do tipo Pipeline, em vez de um novo transformador para entradas categóricas, foi um mal-entendido de minha parte (e deveria / poderia ter sido corrigido por outros), que espero que seja compreensível durante o trabalho a enorme carga de trabalho que está mantendo este projeto.

Esta página foi útil?
0 / 5 - 0 avaliações