【问题标题】:dtype error when fitting Sklearn Pipeline with a TargetEncoder followed by an XGBoost classifier使用 TargetEncoder 和 XGBoost 分类器拟合 Sklearn Pipeline 时出现 dtype 错误
【发布时间】:2020-10-25 14:21:24
【问题描述】:

在尝试拟合使用 XGBoost 分类器作为其最后步骤的管道时出现以下错误:

数据的DataFrame.dtypes 必须是int、float 或bool。 没想到字段[Categorical Columns here]中的数据类型。

我正在使用以下管道,使用 TargetEncoder 对分类列进行编码:

numerical_transformer = MinMaxScaler()
categorical_transformer = TargetEncoder()

numerical_cols = X.select_dtypes(include=['float', 'int']).columns
categorical_cols = X.select_dtypes(include='object').columns

preprocessor = make_column_transformer(
    (categorical_transformer, categorical_cols),
    (numerical_transformer, numerical_cols),
    remainder='passthrough')

clf = XGBClassifier(objective= 'binary:logistic')

pipe = make_pipeline(preprocessor, clf)

pipe.fit(X_train,y_train)

问题在于,显然,TargetEncoder 将 object 设置为编码分类列的数据类型。因此,XGBoost 抛出错误。

那么,如何在 XGBClassifier 对象使用数据类型之前将其设置为,例如 float

【问题讨论】:

  • 你可以在分类转换器之后插入一个[函数转换器][1],例如? [1]:scikit-learn.org/stable/modules/generated/…
  • @ItamarMushkin 感谢您的评论。使用函数转换器,我可以验证 TargetEncoder 是否有效地将 float64 设置为所有编码的分类列。但是,ColumnTransformer 输出的是 ndarray,而不是 DataFrame。不知何故,XGBoost 分类器不会将这些列解释为浮点数!
  • 1.不能期望 SKLearn 实体(转换器)输出 DataFrame,也不应该(XGBoost 不期望 DataFrame)
  • 2.也许您对 XGBoost 的输入中没有任何内容?那些讨厌的小 None 不会“破坏” float dtype,但它们对 XGBoost 来说是个问题。
  • 我已经使用列转换器来检查是否可以找到一些无,但事实并非如此。管道仅在我使用 FunctionTransformer(f) 而 f 使用 return x.astype('float64) 时才起作用。我仍然不知道问题出在哪里。

标签: python pandas scikit-learn xgboost


【解决方案1】:

我没有找到问题所在的解释,但我会解释我为解决问题所做的工作。

首先,我检查了在丢弃最后一步时是否可以在管道的输出中找到一些 NaN 或 None 值:

pipe = Pipeline(my_pipeline.steps[:-1])
X_trans = pipe.fit_transform(X,y)
print(f'nb of nan: {np.isnan(X_trans).sum()}')
print(f'nb of none: {(r == None).sum()}')  
>>> nb of nan: 0
>>> nb of none: 0 

因此,由于数据似乎没有问题,我选择使用 Itamar 推荐的 FunctionTransformer 来强制 dtype 浮动。管道现在看起来像这样:

pipe = make_pipeline(preprocessor, 
                     FunctionTransformer(lambda x: x.astype('float64')), 
                     clf)

这样,问题就消失了。

【讨论】:

    猜你喜欢
    • 2018-02-21
    • 2022-07-12
    • 1970-01-01
    • 1970-01-01
    • 2020-09-01
    • 2021-03-23
    • 2016-12-13
    • 2018-08-05
    • 2015-08-23
    相关资源
    最近更新 更多