2017-10-04 4 views
1

EDIT:passer un argument supplémentaire pour GenericUnivariateSelect sans tours de portée

ici est le retraçage complet si je demande la make_scorer solution proposée dans les réponses ...

`File "________python/anaconda-2.7.11-64/lib/python2.7/site-packages/spyder/utils/site/sitecustomize.py", line 880, in runfile 
    execfile(filename, namespace) 

    File ""________python/anaconda-2.7.11-64/lib/python2.7/site-packages/spyder/utils/site/sitecustomize.py", line 94, in execfile 
    builtins.execfile(filename, *where) 

    File ""________/main_"________.py", line 43, in <module> 
    "_________index.fit(X,Y ,g=g,L=L) 

    File ""________/Core.py", line 95, in fit 
    X_preprocessed=self.preprocessing.fit_transform(X,y) 

    File ""________python/anaconda-2.7.11-64/lib/python2.7/site-packages/sklearn/pipeline.py", line 303, in fit_transform 
    return last_step.fit_transform(Xt, y, **fit_params) 

    File ""________/python/anaconda-2.7.11-64/lib/python2.7/site-packages/sklearn/base.py", line 497, in fit_transform 
    return self.fit(X, y, **fit_params).transform(X) 

    File "Base/Base.py", "________ 
    score_func_ret = self.score_func(X, y) 

TypeError: __call__() takes at least 4 arguments (3 given)` 

Je travaille sur un pipeline de sklearn.

custom_filter=GenericUnivariateSelect(Custom_Score,mode='MinScore',param=0.9) 
custom_filter._selection_modes.update({'MinScore': SelectMinScore}) 
MyProcessingPipeline=Pipeline(steps=[... 
          ('filter_step', None), 
          ....]) 
ProcessingParams.update({'filter_step':custom_filter}) 
MyProcessingPipeline.set_params(**ProcessingParams) 

SelectMinScore est une coutume BaseFilter.

-je effectuer la sélection des fonctionnalités univariée basée sur une Custom_Score qui doit recevoir un argument supplémentaire, appelé XX ici

def Custom_Score(X,Y,XX=_XX): 
     # do stuff 
     return my_score 

Malheureusement, AFAIK l'API sklearn ne permet pas d'arguments supplémentaires à passer un paramètre d'un paramètre d'une étape d'un pipeline.

J'ai essayé

MyProcessingPipeline({'filter_step':custom_filter(XX=_XX)})

mais que les sauts en cascade passant argument (je crois). Jusqu'ici, j'ai résolu ceci en écrivant un wrapper, où _XX est les données dont j'ai besoin qui malheureusement doivent être dans la portée de la fonction au moment de la définition. J'ai donc fini par définir la fonction dans ma fonction main afin que _XX existe et puisse être transmis.

def Custom_Score_Wrapped(X,Y): 
      return Custom_Score(X,Y,XX=_XX) 

Je pense que c'est une solution de contournement vraiment sale.

Quelle est la bonne façon de procéder?

Répondre

0

Vous pouvez simplement passer l'argument supplémentaire en appelant la fonction make_scorer(). Par exemple, vous check this link. Dans l'exemple, il utilise fbeta_score. Maintenant fbeta nécessite un paramètre supplémentaire, beta qui est réglée en appelant la fonction comme celui-ci make_scorer():

ftwo_scorer = make_scorer(fbeta_score, beta=2) 

Donc, dans votre cas, cela devrait fonctionner:

def Custom_Score(X,Y,XX): 
    # do stuff 
    return my_score 

my_scorer = make_scorer(Custom_Score,XX=_XX) 
+0

J'ai essayé, il ne ne fonctionne pas. Je reçois l'erreur suivante dans la classe basefilter: Fichier "Base/base_dataframe.py", ligne 333, en forme score_func_ret = self.score_func (X, y) TypeError: __call __() prend au moins 4 arguments (3 donné) – ErroriSalvo

+0

donc il semble que la classe de filtre doit encore accéder à tous les arguments de la partition_func afin de travailler – ErroriSalvo

+1

@Sabor pouvez-vous s'il vous plaît poster la trace complète de la pile –