在没有范围技巧的情况下将额外参数传递给GenericUnivariateSelect

时间:2017-10-04 07:48:51

标签: python scikit-learn pipeline scoping

编辑:

如果我应用答案中建议的make_scorer解决方法,那么这是完整的追溯......

`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)`

我正在开发一个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是自定义BaseFilter

我需要根据Custom_Score执行单变量功能选择,必须接收额外参数,在此处称为XX

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

不幸的是,AFAIK sklearn API不允许额外的参数传递给管道步骤的参数参数。

我试过了

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

但这打破了通过级联的争论(我相信)。

到目前为止,我已经通过编写一个包装器解决了这个问题,其中_XX是我需要的数据,不幸的是,它必须在定义时才在函数的范围内。 所以我最终在main函数中定义了函数,以便_XX存在并且可以传递。

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

我认为这是一个非常脏的解决方法。

这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

您可以在调用make_scorer()函数时简单地传递额外的争论。 例如,您check this link。在示例中,它使用了fbeta_score。 现在fbeta需要一个额外的参数beta,它在调用make_scorer()函数时设置,如下所示:

ftwo_scorer = make_scorer(fbeta_score, beta=2)

所以在你的情况下,这应该有效:

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

my_scorer = make_scorer(Custom_Score,XX=_XX)