python - 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__
?
解决方案
虽然很晚,但我会在遇到类似问题时尝试给出答案。对我来说,您在这里设置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()
获得的实例,将如下所示:
- 在达到这一点之前,您的设置可能不会出现任何问题。然后:
- 您的转换器将被克隆(并
__init__
调用方法); - 将调用 setter;
- 外部克隆将在此处失败,因为
the constructor [...] modifies parameter attribute_filepath
.
再次引用文档,
由于 model_selection.GridSearchCV 使用 set_params 将参数设置应用于估计器,因此调用 set_params 与使用init方法设置参数具有相同的效果是必不可少的。
当然,答案的某些部分依赖于一些有根据的猜测。
推荐阅读
- google-cloud-firestore - 如何触发 onwrite 将数据复制到不同 Firestore 中的集合
- c# - 在时区获取当前时间没有考虑夏令时(我认为)
- actionscript-3 - FlashDevelop 将整个类路径放在新实例声明中
- c++ - How do I keep a running total of an input variable inside of a switch?
- shell - How do I get grep working in a function while assigned to a new variable?
- git - I Can not merge my work into develop branch using SourceTree?
- npm - 是否安装 NPM
还运行该 pkg 的 npm start 吗? - ruby-on-rails - Create index with new searchkick options in rails console
- split - How to download "Split" CSV files from H2O DAI?
- c# - program crashes when i add code to make a button turn off bluetooth