我正在使用带有Pipeline的XGBRegressor。Pipeline包含预处理步骤和模型(XGBRegressor)。
以下是完整的预处理步骤。(我已经定义了numeric_cols和cat_cols)
numerical_transfer = SimpleImputer()cat_transfer = Pipeline(steps = [ ('imputer', SimpleImputer(strategy = 'most_frequent')), ('onehot', OneHotEncoder(handle_unknown = 'ignore')) ])preprocessor = ColumnTransformer( transformers = [ ('num', numerical_transfer, numeric_cols), ('cat', cat_transfer, cat_cols) ])
最终的Pipeline是
my_model = Pipeline(steps = [('preprocessor', preprocessor), ('model', model)])
当我尝试在不使用early_stopping_rounds的情况下进行拟合时,代码运行正常。
(my_model.fit(X_train, y_train))
但是当我使用early_stopping_rounds如下所示时,我得到了错误。
my_model.fit(X_train, y_train, model__early_stopping_rounds=5, model__eval_metric = "mae", model__eval_set=[(X_valid, y_valid)])
我在以下位置得到了错误:
model__eval_set=[(X_valid, y_valid)]) 错误是ValueError: DataFrame.dtypes for data must be int, float or bool.Did not expect the data types in fields MSZoning, Street, Alley, LotShape, LandContour, Utilities, LotConfig, LandSlope, Condition1, Condition2, BldgType, HouseStyle, RoofStyle, RoofMatl, MasVnrType, ExterQual, ExterCond, Foundation, BsmtQual, BsmtCond, BsmtExposure, BsmtFinType1, BsmtFinType2, Heating, HeatingQC, CentralAir, Electrical, KitchenQual, Functional, FireplaceQu, GarageType, GarageFinish, GarageQual, GarageCond, PavedDrive, PoolQC, Fence, MiscFeature, SaleType, SaleCondition
这是否意味着我在应用my_model.fit()之前应该预处理X_valid,或者我做错了什么?
如果问题是我们需要在应用fit()之前预处理X_valid,如何使用我上面定义的预处理器来做到这一点?
编辑:我尝试在不使用Pipeline的情况下预处理X_valid,但我得到了特征不匹配的错误。
回答:
问题在于Pipeline不适合eval_set。所以,正如你所说,你需要预处理X_valid。最简单的方法是使用不带’model’步骤的Pipeline。在拟合你的Pipeline之前使用以下代码:
# 制作一个副本以避免更改原始数据X_valid_eval=X_valid.copy()# 从Pipeline中移除模型eval_set_pipe = Pipeline(steps = [('preprocessor', preprocessor)])# 拟合并转换X_valid.copy()X_valid_eval = eval_set_pipe.fit(X_train, y_train).transform (X_valid_eval)
然后在更改model__eval_set后拟合你的Pipeline如下:
my_model.fit(X_train, y_train, model__early_stopping_rounds=5, model__eval_metric = "mae", model__eval_set=[(X_valid_eval, y_valid)])