问题
EDIT:
here is the complete traceback if I apply the make_scorer
workaround suggested in the answers...
`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)`
I am working on a sklearn pipeline.
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)
where SelectMinScore
is a custom BaseFilter
.
I need to perform univariate feature selection based on a Custom_Score
, which must receive an extra argument, called XX in here
def Custom_Score(X,Y,XX=_XX ):
# do stuff
return my_score
Unfortunately, AFAIK the sklearn API does not allow extra arguments to be passed a parameter of a parameter of a step of a pipeline.
I have tried
MyProcessingPipeline({'filter_step':custom_filter(XX=_XX)})
but that breaks argument passing cascade (I believe).
So far, I have solved this by writing a wrapper, where _XX is the data I need which unfortunately need to be in the scope of the function at definition time.
So I have ended up defining the function within my main
function so that _XX exists and it can be passed.
def Custom_Score_Wrapped(X,Y):
return Custom_Score(X,Y,XX=_XX )
I think this is a really dirty workaround.
What is the right way to do this?
回答1:
You can simply pass the extra arguement while calling the make_scorer() function.
For example, you check this link. In the example it makes use of fbeta_score.
Now fbeta requires an additional parameter, beta
which is set while calling the make_scorer() function like this :
ftwo_scorer = make_scorer(fbeta_score, beta=2)
So in your case, this should work:
def Custom_Score(X,Y,XX):
# do stuff
return my_score
my_scorer = make_scorer(Custom_Score,XX=_XX)
来源:https://stackoverflow.com/questions/46559634/passing-an-extra-argument-to-genericunivariateselect-without-scope-tricks