如何解决Lightgbm 在同一数据集上的拆分方式不同一种热编码与一对其他拆分算法
在lightgbm上做小测试的时候,发现了一个我看不懂的案例。
import pandas as pd
X = pd.DataFrame(
[
[0,1,1],[2,2,0],[3,3,2],[0,-3,[1,2.5,5,-1.5,],columns=["col1","col2","col3"],)
X["col1"] = X["col1"].astype("category")
X["col3"] = X["col3"].astype("category")
y = pd.Series([0,1])
及其相关的一个热编码版本:
from sklearn.preprocessing import OneHotEncoder
feats_to_encode = ["col1","col3"]
enc = OneHotEncoder()
enc.fit(X[feats_to_encode])
X_one_hot_encoded = pd.DataFrame(
enc.transform(X[feats_to_encode]).toarray(),columns=[
feats_to_encode[feat_id] + str(cat)
for feat_id in range(len(enc.categories_))
for cat in enc.categories_[feat_id]
],)
X_one_hot_encoded["col2"] = X["col2"]
然后我用之前的数据集训练了 2 个 lightgbm 模型。我知道 lightgbm 使用特殊算法管理分类列。 “当一个特征的类别数小于或等于 max_cat_to_onehot 时,将使用一对一分割算法”(见 max_cat_to_onehot)。然后我会天真地期望,因为我的分类列的类别(4 和 3)比参数 max_cat_to_onehot 少,所以我会用两个数据集得到相同的结果,除非“一对一分割算法”不等价到一个热编码分类列。由于参数名称“max_cat_to_onehot”和算法“one-vs-other split algorithm”,我假设了这种行为。
from lightgbm import LGBMRegressor
params = {
"n_estimators": 1,"max_depth": 2,"min_child_samples": 1,"importance_type": "gain","max_cat_to_onehot": 10,}
model = LGBMRegressor(**params)
model.fit(X,y)
print(model._Booster.dump_model()["tree_info"][0]["tree_structure"]["split_gain"]) # 0.30476200580596924
model = LGBMRegressor(**params)
model.fit(X_one_hot_encoded,y)
print(model._Booster.dump_model()["tree_info"][0]["tree_structure"]["split_gain"]) # 1.0666699409484863
两种型号的第一次拆分是不同的。第二个模型选择了可能的最佳分割,但第一个模型并非如此。
有人知道这是什么原因吗?我认为我对“一对一分割算法”行为的猜测是错误的。
解决方法
我更新了 lightgbm 版本,从 2.3.1 到 3.1.1。使用新版本,我得到了预期的结果。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。