LightGBM 如何计算回归中第一棵树的叶值?
How does LightGBM calculate the leaf values for the first tree in regression?
当使用 create_tree_digraph
从回归中绘制第一棵树时,叶值使
对我来说没有意义。例如:
from sklearn.datasets import load_boston
X, y = load_boston(return_X_y=True)
import lightgbm as lgb
data = lgb.Dataset(X, label=y)
bst = lgb.train({}, data, num_boost_round=1)
lgb.create_tree_digraph(bst)
给出以下树:
例如,关注叶 3,这些似乎是拟合值:
bst.predict(X, num_iteration=0)[X[:,5]>7.437]
array([24.78919238, 24.78919238, 24.78919238, 24.78919238, 24.78919238,
24.78919238, 24.78919238, 24.78919238, 24.78919238, 24.78919238,
24.78919238, 24.78919238, 24.78919238, 24.78919238, 24.78919238,
24.78919238, 24.78919238, 24.78919238, 24.78919238, 24.78919238,
24.78919238, 24.78919238, 24.78919238, 24.78919238, 24.78919238,
24.78919238, 24.78919238, 24.78919238, 24.78919238, 24.78919238])
但与明显而微不足道的取均值方法相比,这些预测似乎很糟糕:
y[X[:,5]>7.437]
array([38.7, 43.8, 50. , 50. , 50. , 50. , 39.8, 50. , 50. , 42.3, 48.5,
50. , 44.8, 50. , 37.6, 46.7, 41.7, 48.3, 42.8, 44. , 50. , 43.1,
48.8, 50. , 43.5, 35.2, 45.4, 46. , 50. , 21.9])
y[X[:,5]>7.437].mean()
45.09666666666667
我在这里错过了什么?
LightGBM 的叶节点输出值显示该叶节点的预测,包括乘以学习率。
默认学习率为0.1
(https://lightgbm.readthedocs.io/en/latest/Parameters.html#learning_rate)。如果将其更改为 1.0
,您应该看到叶 3 的输出值为 45.097
(对于落入该叶节点的所有观察值,正好是 y
的平均值)。
from sklearn.datasets import load_boston
X, y = load_boston(return_X_y=True)
import lightgbm as lgb
data = lgb.Dataset(X, label=y)
bst = lgb.train({"learning_rate": 1.0}, data, num_boost_round=1)
lgb.create_tree_digraph(bst)
类似地,如果将 learning_rate
设置为非常非常小的值,您应该会看到第一棵树的大部分叶节点的值与 [=15= 的全局平均值非常相似].示例数据中 y
(y.mean()
) 的全局平均值为 22.532
.
bst = lgb.train({"learning_rate": 0.0000000000001}, data, num_boost_round=1)
lgb.create_tree_digraph(bst)
我不建议在实践中设置 learning_rate=1.0
,因为它会导致更差的准确性。对于像 LightGBM 这样的梯度提升库,最好使用学习率 < 1.0
和更高的 num_boost_round
(尝试 100
),这样每棵单独的树对最终预测的影响有限。
如果这样做,您会发现添加到模型中的每一棵后续树都应该在准确性上增加小的增量改进。这就是您的原始示例中发生的情况。示例数据中 y
(y.mean()
) 的全局平均值为 22.532
。对于一组具有局部均值 45.097
且学习率设置为 0.1
的记录,第一棵树预测 24.789
。本身并不是一个很好的预测,但对该组的预测比全球平均值更好。
当使用 create_tree_digraph
从回归中绘制第一棵树时,叶值使
对我来说没有意义。例如:
from sklearn.datasets import load_boston
X, y = load_boston(return_X_y=True)
import lightgbm as lgb
data = lgb.Dataset(X, label=y)
bst = lgb.train({}, data, num_boost_round=1)
lgb.create_tree_digraph(bst)
给出以下树:
例如,关注叶 3,这些似乎是拟合值:
bst.predict(X, num_iteration=0)[X[:,5]>7.437]
array([24.78919238, 24.78919238, 24.78919238, 24.78919238, 24.78919238,
24.78919238, 24.78919238, 24.78919238, 24.78919238, 24.78919238,
24.78919238, 24.78919238, 24.78919238, 24.78919238, 24.78919238,
24.78919238, 24.78919238, 24.78919238, 24.78919238, 24.78919238,
24.78919238, 24.78919238, 24.78919238, 24.78919238, 24.78919238,
24.78919238, 24.78919238, 24.78919238, 24.78919238, 24.78919238])
但与明显而微不足道的取均值方法相比,这些预测似乎很糟糕:
y[X[:,5]>7.437]
array([38.7, 43.8, 50. , 50. , 50. , 50. , 39.8, 50. , 50. , 42.3, 48.5,
50. , 44.8, 50. , 37.6, 46.7, 41.7, 48.3, 42.8, 44. , 50. , 43.1,
48.8, 50. , 43.5, 35.2, 45.4, 46. , 50. , 21.9])
y[X[:,5]>7.437].mean()
45.09666666666667
我在这里错过了什么?
LightGBM 的叶节点输出值显示该叶节点的预测,包括乘以学习率。
默认学习率为0.1
(https://lightgbm.readthedocs.io/en/latest/Parameters.html#learning_rate)。如果将其更改为 1.0
,您应该看到叶 3 的输出值为 45.097
(对于落入该叶节点的所有观察值,正好是 y
的平均值)。
from sklearn.datasets import load_boston
X, y = load_boston(return_X_y=True)
import lightgbm as lgb
data = lgb.Dataset(X, label=y)
bst = lgb.train({"learning_rate": 1.0}, data, num_boost_round=1)
lgb.create_tree_digraph(bst)
类似地,如果将 learning_rate
设置为非常非常小的值,您应该会看到第一棵树的大部分叶节点的值与 [=15= 的全局平均值非常相似].示例数据中 y
(y.mean()
) 的全局平均值为 22.532
.
bst = lgb.train({"learning_rate": 0.0000000000001}, data, num_boost_round=1)
lgb.create_tree_digraph(bst)
我不建议在实践中设置 learning_rate=1.0
,因为它会导致更差的准确性。对于像 LightGBM 这样的梯度提升库,最好使用学习率 < 1.0
和更高的 num_boost_round
(尝试 100
),这样每棵单独的树对最终预测的影响有限。
如果这样做,您会发现添加到模型中的每一棵后续树都应该在准确性上增加小的增量改进。这就是您的原始示例中发生的情况。示例数据中 y
(y.mean()
) 的全局平均值为 22.532
。对于一组具有局部均值 45.097
且学习率设置为 0.1
的记录,第一棵树预测 24.789
。本身并不是一个很好的预测,但对该组的预测比全球平均值更好。