【问题标题】:param-grid passing parameters to an underlying function. lost in kw_argsparam-grid 将参数传递给底层函数。迷失在 kw_args
【发布时间】:2018-11-12 12:26:33
【问题描述】:

我在这里迷路了。希望有人能解释一下。

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

管道的第一步是FunctionSampler(imbalanced-learn 0.4.0dev 仅在 Git-hub 上可用),它是下面第 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 fit 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()`.

【问题讨论】:

    标签: python python-3.x scikit-learn keyword-argument


    【解决方案1】:

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

    相反,max_samples 属于 FunctionSampler()kw_args 参数中的一个条目。

    这表明您应该传递类似

    的内容
    'functionsampler__kw_args': {'max_samples': [1, 10, 100]}
    

    GridSearchCV param_grid 参数(注意:我不确定为什么在您的代码中将其称为params,该参数在docs 中是定位的或命名为param_grid)。

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

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

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

    from imblearn import FunctionSampler
    from imblearn.pipeline import make_pipeline
    from sklearn.ensemble import IsolationForest
    from sklearn.model_selection import GridSearchCV
    from sklearn.linear_model import LogisticRegression
    
    
    class FunctionSamplerWrapper(object):    
        def unwrap(self, key, values):
            return FunctionSampler(func=outlier_rejection, kw_args={key[0]: values})
    
    pipe = make_pipeline(FunctionSamplerWrapper().unwrap(key = ['max_samples'], 
                                                         values = [1]), 
                         LogisticRegression(random_state=rng))
    
    cv = GridSearchCV(pipe, 
                      [{'logisticregression__C': [1., 10.], 
                       'functionsamplerwrapper__key': ['max_samples'],
                       'functionsamplerwrapper__values': [1, 10, 100]}])
    

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

    【讨论】:

    • 超级!非常感谢你。回复:“params”和“param_grid”是因为我正在试验一种称为 EvolutionaryAlgorithmSearchVC (sklearn-deap) 的 GridSearchCV 变体
    • 另外我只想提一下,在玩游戏时我设法让这段代码运行: cv = GridSearchCV(pipe, param_grid={'logisticregression__C': [1., 10.], 'functionsampler__kw_args': [{'max_samples':x} for x in [10,100]]}) 但我需要对其进行全面测试
    • 不客气!对于不同的变体,更新您的原始帖子以注意哪些函数和类是非标准的可能会有所帮助。我还发现您的make_pipeline 实际上来自imblearn,而不是sklearnsklearn 版本会使用此代码引发错误)。对于将来从您的帖子中学习的其他人来说,这可能会引起混淆。
    【解决方案2】:

    @andrew_reece 的 FunctionSamplerWrapper 解决方案对我不起作用。相反,@luide 在 cmets 中的解决方法可以完成这项工作。只是代替

    '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}]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-27
      • 2021-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多