在 sklearn 中创建自定义转换器时出错 - 需要 2 个位置参数,但给出了 3 个

Posted

技术标签:

【中文标题】在 sklearn 中创建自定义转换器时出错 - 需要 2 个位置参数,但给出了 3 个【英文标题】:Error creating a custom transformer in sklearn - takes 2 positional arguments but 3 were given 【发布时间】:2020-07-22 04:43:54 【问题描述】:

我正在尝试使用自定义变压器为通用数据集创建管道。 这是我的第一个变压器。给定一个列名,它将该日期时间列分成更多列。

class DatePartTransformer:

    def __init__(self,fldname):
        self.fldname = fldname

    def fit(self):
        return self 

    def transform(self):
        return self

    def fit_transform(self,df, drop=True, time=False, errors='raise'):
        fld = df[self.fldname]
        fld_dtype = fld.dtype
        if isinstance(fld_dtype, pd.core.dtypes.dtypes.DatetimeTZDtype):
            fld_dtype = np.datetime64

        if not np.issubdtype(fld_dtype, np.datetime64):
            df[self.fldname] = fld = pd.to_datetime(fld, infer_datetime_format=True, errors=errors)
        targ_pre = re.sub('[Dd]ate$', '', self.fldname)
        attr = ['Year', 'Month', 'Week', 'Day', 'Dayofweek', 'Dayofyear',
            'Is_month_end', 'Is_month_start', 'Is_quarter_end', 'Is_quarter_start', 'Is_year_end', 'Is_year_start']
        if time: attr = attr + ['Hour', 'Minute', 'Second']
        for n in attr: df[targ_pre + n] = getattr(fld.dt, n.lower())
        df[targ_pre + 'Elapsed'] = fld.astype(np.int64) // 10 ** 9
        if drop: df.drop(self.fldname, axis=1, inplace=True)

        return df

这是我的第二个

from pandas.api.types import is_string_dtype

class TrainCats:

    def __init__(self):
        pass

    def fit(self):
        return self

    def transform(self):
        return self

    def fit_transform(self,df):

        for n,c in df.items():
            if is_string_dtype(c): 
                df[n] = c.astype('category').cat.as_ordered()
        return df

我打算写更多。

这是管道。

pipeline = Pipeline([
 ('imputer',DatePartTransformer('date')),
 ('cats',TrainCats())
])

df = pipeline.fit_transform(df_raw)

当我运行管道时,我得到了这个错误

TypeError                                 Traceback (most recent call last)
<ipython-input-36-36154d1b45b5> in <module>
      4 ])
      5 
----> 6 df = pipeline.fit_transform(df_raw)

c:\users\vishak~1\desktop\env\ml\lib\site-packages\sklearn\pipeline.py in fit_transform(self, X, y, **fit_params)
    391                 return Xt
    392             if hasattr(last_step, 'fit_transform'):
--> 393                 return last_step.fit_transform(Xt, y, **fit_params)
    394             else:
    395                 return last_step.fit(Xt, y, **fit_params).transform(Xt)

TypeError: fit_transform() takes 2 positional arguments but 3 were given

Aurélien Géron 的书中说管道就是这样工作的。我找不到我的错误。

【问题讨论】:

这能回答你的问题吗? fit_transform() takes 2 positional arguments but 3 were given with LabelBinarizer 不幸的是,这些解决方案都不适合我。 【参考方案1】:

如果您查看Pipeline 的源代码,您会发现在使用fit_transform 时,它要求每个转换器采用2 个位置参数,即Xy(除了self)方法。这正是这一行:

                 return last_step.fit_transform(Xt, y, **fit_params)

所以你的转换器fit_transform的方法声明必须有2个位置参数。要修复它,您需要做的就是为您的 TrainCats fit_transform 方法提供第二个虚拟参数,如下所示:

    def fit_transform(self,df, y=None):

        for n,c in df.items():
            if is_string_dtype(c): 
                df[n] = c.astype('category').cat.as_ordered()
        return df

这将减少您的错误,但还有一个漏洞。尽管DatePartTransformer 中的fit_transform 需要多个参数,但由于管道假设,您的drop 参数将被None 或来自其他转换器的实际y 覆盖。如果您希望只处理输入而不处理标签,则还需要将此虚拟参数添加到 DatePartTransformer

     def fit_transform(self,df, y=None, drop=True, time=False, errors='raise'):
        ...

【讨论】:

以上是关于在 sklearn 中创建自定义转换器时出错 - 需要 2 个位置参数,但给出了 3 个的主要内容,如果未能解决你的问题,请参考以下文章

在片段中创建自定义列表视图时出错。必需的活动,找到的片段

在片段中创建自定义列表视图时出错所需活动,找到片段

在 JavaScript 中创建自定义回调

在 Wordpress 中创建自定义 URL

如何在光滑的滑块中创建自定义箭头以在悬停时更改图像?

在 Java 中创建自定义 JButton