param-grid将参数传递给底层函数。丢失在kw_args

时间:2018-06-02 16:42:24

标签: python python-3.x scikit-learn kwargs

我迷失在这里。希望有人能说清楚。

我已经建立了一个管道(sklearn管道,实际上确切地说是一个不平衡的学习pipeline

管道的第一步是FunctionSampler(仅在Git-hub上可用的不平衡 - 学习0.4.0dev),它是下面在步骤3中定义的自定义函数的API包装器。我希望能够将一系列参数传递给底层函数 - 这是我的问题。

然后我构建了一个范围为max_samples的网格搜索,但是当我适合时,我得到了错误。

我是python的新手 - 如果我有一个明显的答案,我没有看到道歉。

非常感谢!

1定义自定义函数

In [90]: def outlier_rejection(X, y, max_samples):
        ...:     model = IsolationForest(max_samples=max_samples, contamination=0.4, random_state=rng)
        ...:     model.fit(X)
        ...:     y_pred = model.predict(X)
        ...:     return X[y_pred ==1], y[y_pred == 1]
        ...:

2构建管道

  pipe = make_pipeline(FunctionSampler(func=outlier_rejection, kw_args={'max_samples':1}), LogisticRegression(random_state=rng))

3显示了我需要在kw_args

中传递max_samples的管道
Pipeline(memory=None,
             steps=[('functionsampler', FunctionSampler(accept_sparse=True,
                func=<function outlier_rejection at 0x000001173B3E9EA0>,
                kw_args={'max_samples': 1})), ('logisticregression', LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
                  intercept_scaling=1, max...ect at 0x0000011737DCA1B0>,
                  solver='liblinear', tol=0.0001, verbose=0, warm_start=False))])

4构建网格搜索

cv = GridSearchCV(pipe, param_grid={'logisticregression__C': [1., 10.], 'functionsampler__max_samples': [1, 10, 100]})

5适合cv并获得以下错误

ValueError: Invalid parameter max_samples for estimator FunctionSampler(accept_sparse=True,
        func=<function outlier_rejection at 0x000001173B3E9EA0>,
        kw_args={'max_samples': 1}). Check the list of available parameters with `estimator.get_params().keys()`.

2 个答案:

答案 0 :(得分:1)

这里的第一个问题是您尝试将max_samples参数传递给FunctionSampler(),但FunctionSampler()没有max_samples作为命名参数。

相反,max_samples属于kw_args的{​​{1}}参数中的条目。

这表明您应该传递类似

的内容
FunctionSampler()

'functionsampler__kw_args': {'max_samples': [1, 10, 100]} GridSearchCV参数(注意:我不确定为什么它在你的代码中被称为param_grid,这个参数在位置上是名为paramsdocs)。

但是......你不能将dict作为param_grid参数中的值传递。这样做会引发错误:

  

ValueError:参数(functionsampler__kw_args)的参数值必须是序列(但不是字符串)或np.ndarray。

我能想到的最佳解决方案是将param_grid包含在一个接受来自FunctionSampler()的单独keyvalues参数的类中(例如param_grid) ,然后将它们放在一起作为functionsamplerwrapper__key期望的kw_args字典。像这样:

FunctionSampler()

注意 - 我只检查过它是否运行没有错误(确实如此),但我实际上没有对数据进行测试以确保功能正常。
希望这会有所帮助。

答案 1 :(得分:0)

@andrew_reece的FunctionSamplerWrapper解决方案不适用于我。相反,@ luide的注释中的解决方法可以完成此工作。只能代替

'functionsampler__kw_args': [{'max_samples':x} for x in [10,100]]

我宁愿做

'functionsampler__kw_args': [{'max_samples': 10}, {'max_samples': 100}]

因为我认为它更容易理解。

请注意,我没有将值放在列表中(例如{'max_samples': [10]}),因为这样做会产生关于值长度不匹配的错误。

这里有关于Scikit-learn FunctionTransformer的相关讨论:

How can I make the FunctionTransformer along with GridSearchCV into a pipeline?

总而言之,这就是我要做的:

'functionsampler__kw_args': [{'max_samples': 10}, {'max_samples': 100}]