首页 > 解决方案 > Scikit:自定义估算器:无法克隆

问题描述

我已经编写了自己的估算器,用于自动清理特定数据集。我想我正确地遵循了 scikit 规则:

from sklearn.base import BaseEstimator, TransformerMixin
import pandas as pd
from pathlib import Path

class cleaning(BaseEstimator, TransformerMixin):

    def __init__(self, to_drop = [], ins_threshold=0.6, 
                 corr_threshold=0.7, attribute_filepath='attribute.xlsx'): # no *args or **kargs, provides methods get_params() and set_params()
        """
        Parameters:
        -----------
        to_drop (list) : columns to be dropped
        ins_thresholrd (float) : [0.0 - 1.0] insignificant threshold above which columns containing that proportion of NaN get dropped
        corr_threshold (float) : [0.0 - 1.0] correlation threshold above which correlated columns get dropped (first one is kept)
        attribute_filepath (str of pathlib.Path) : path to the Excel file containing attributes information

        """

        self.attribute_filepath = Path(attribute_filepath)
        self.ins_threshold = ins_threshold
        self.corr_threshold = corr_threshold

        self.to_drop = to_drop
        self.ins_col = None
        self.correlated_col = None

但我仍然收到错误

RuntimeError: Cannot clone object cleaning(attribute_filepath=PosixPath('MyFile.xlsx')), as the constructor either does not set or modifies parameter attribute_filepath

我不明白为什么因为self.attribute_filepath 在我的__init__?

标签: pythonscikit-learn

解决方案


虽然很晚,但我会在遇到类似问题时尝试给出答案。对我来说,您在这里设置self.attribute_filepath的东西与默认参数不同,因此您有点违反了 scikit-learn API 约定。确实,谈到__init__'s 方法并引用文档

不应该有逻辑,甚至没有输入验证,也不应该改变参数。相应的逻辑应该放在使用参数的地方,通常是合适的。以下是错误的:

def __init__(self, param1=1, param2=2, param3=3):
    # WRONG: parameters should not be modified
    if param1 > 1:
        param2 += 1
    self.param1 = param1
    # WRONG: the object's attributes should have exactly the name of
    # the argument in the constructor
    self.param3 = param2

将您的自定义转换器传递给其他情况时会发生什么GridSearchCV()- 我猜您正在将您的转换器传递给 a Pipeline,而这反过来又GridSearchCV()或者您正在做类似的事情 - 因此调用fit()获得的实例,将如下所示:

  1. 在达到这一点之前,您的设置可能不会出现任何问题。然后:
  2. 您的转换器将被克隆(并__init__调用方法);
  3. 将调用 setter;
  4. 外部克隆将在此处失败,因为the constructor [...] modifies parameter attribute_filepath.

再次引用文档,

由于 model_selection.GridSearchCV 使用 set_params 将参数设置应用于估计器,因此调用 set_params 与使用init方法设置参数具有相同的效果是必不可少的。

当然,答案的某些部分依赖于一些有根据的猜测。

这篇文章很好地解释了这一点。最后,我还会建议类似问题的这两个答案:herehere


推荐阅读