关于在Sklearn Pipeline中正确使用LGBM处理类别特征的问询
你的Pipeline构建是否正确?
首先给你吃个定心丸:你的Pipeline构建是能正常运行的,而且从你完成的测试来看,categorical_feature=(0,)并没有被忽略——这列特征确实被当作类别特征处理了。那为啥会弹出警告呢?咱们来拆解下背后的原因。
警告的由来
你收到的这条警告:
c:\programdata\miniconda3\lib\site-packages\lightgbm\basic.py:842: UserWarning: categorical_feature keyword has been found in
paramsan Please use categorical_feature argument of the Dataset constructor to pass this parameter.
是LightGBM版本迭代后的规范提醒:现在官方更推荐在构建Dataset对象时指定categorical_feature,而不是通过模型的初始化参数传递。但Sklearn Pipeline的运行逻辑是直接把参数传给模型的构造函数,没有单独构建Dataset的环节,所以就触发了这个警告。不过好在当前版本的LightGBM做了兼容处理,你传入的参数依然会生效,这也是你测试能得到预期结果的核心原因。
消除警告的规范解法(适配Sklearn Pipeline)
如果你看着警告不舒服,想完全遵循官方推荐的方式,同时保持Sklearn Pipeline的标准格式(输入为np.array),可以试试自定义一个轻量的模型子类,重写fit方法来传递类别特征参数:
from lightgbm import LGBMRegressor class CustomLGBMRegressor(LGBMRegressor): def fit(self, X, y, **fit_params): # 在这里指定类别特征的索引,和你之前的设置一致 fit_params['categorical_feature'] = (0,) return super().fit(X, y, **fit_params)
然后在Pipeline里替换成这个自定义模型即可:
from sklearn.pipeline import Pipeline pipeline = Pipeline([ ('regressor', CustomLGBMRegressor(n_estimators=100, max_depth=1)) ])
这样既符合Sklearn Pipeline的输入要求,又能按LightGBM的推荐方式指定类别特征,还能彻底消除那个警告。
另外补充一句:你已经把类别特征转成int类型是完全没问题的,LightGBM可以很好地识别这种类型的类别特征,不用额外做其他编码处理。
总结
- 你的Pipeline是正确的,
categorical_feature=(0,)没有被忽略,测试结果已经验证了这一点; - 警告只是版本迭代后的规范提醒,不会影响当前模型的功能;
- 想消除警告的话,用自定义模型子类的方式就能完美解决,同时保持Pipeline的标准格式。
内容的提问来源于stack exchange,提问作者user40780

