0

谜题

我无法解释树叶中的值CatBoostRegressor。拟合模型正确地捕获了数据集的逻辑,但是当我绘制树时值的比例与实际数据集的比例不匹配。

在这个例子中,我们预测size,它的值在 15-30 左右,具体取决于观察的colorage

import random
import pandas as pd
import numpy as np
from catboost import Pool, CatBoostRegressor

# Create a fake dataset.
n = 1000
random.seed(1)
df = pd.DataFrame([[random.choice(['red', 'blue', 'green', 'yellow']),
                    random.random() * 100]
                   for i in range(n)],
                  columns=['color', 'age'])
df['size'] = np.select([np.logical_and(np.logical_or(df.color == 'red',
                                                     df.color == 'blue'),
                                       df.age < 50),
                        np.logical_or(df.color == 'red',
                                      df.color == 'blue'),
                        df.age < 50,
                        True],
                       [np.random.normal(loc=15, size=n),
                        np.random.normal(loc=20, size=n),
                        np.random.normal(loc=25, size=n),
                        np.random.normal(loc=30, size=n)])

# Fit a CatBoost regressor to the dataset.
pool = Pool(df[['color', 'age']], df['size'],
            feature_names=['color', 'age'], cat_features=[0])
m = CatBoostRegressor(n_estimators=10, max_depth=3, one_hot_max_size=4,
                      random_seed=1)
m.fit(pool)

# Visualize the first regression tree (saves to a pdf).  Values in leaf nodes
# are not on the scale of the original dataset.
m.plot_tree(tree_idx=0, pool=pool).render('regression_tree')

在此处输入图像描述

该模型在正确的值(大约 50)处分裂age,并且它正确地了解到红色和蓝色的观察结果与绿色和黄色的观察结果不同。叶子中的值排序正确(例如,50 以下的红色/蓝色观测值是最小的),但比例完全不同。

predict()函数返回原始数据集规模的值。

>>> df['predicted'] = m.predict(df)
>>> df.sample(n=10)
      color        age       size  predicted
676  yellow  66.305095  30.113389  30.065519
918  yellow  55.209821  29.944622  29.464825
705  yellow   1.742565  24.209283  24.913988
268    blue  76.749979  20.513211  20.019020
416    blue  59.807800  18.807197  19.949336
326     red   4.621795  14.748898  14.937314
609  yellow  99.165027  28.942243  29.823422
421   green  40.731038  26.078450  24.846742
363  yellow   2.461971  25.506517  24.913988
664     red   5.206448  16.579706  14.937314

我试过的

我想知道是否有某种简单的标准化正在进行,但显然不是这样。例如,年龄 < 50 的红色观察值在树中被指定为 -3.418,这与真实值的 z 分数(约 15)相去甚远。

>>> (15 - np.mean(df['size'])) / np.std(df['size'])
-1.3476124913754326

这篇文章提出了一个关于 XGBoost 的类似问题。接受的答案解释说这些值都应该添加到base_score参数中;但是,如果 中有类似的参数CatBoost,我找不到它。(如果参数在 中使用不同的名称CatBoost,我不知道它叫什么。)此外,CatBoost树中的值不只是与原始数据集相差某个常数;最大和最小叶节点之间的差异约为 7,而size原始数据集中的最大值和最小值之间的差异约为 15。

我浏览了CatBoost文档但没有成功。“模型值”部分表示回归的值是“应用模型产生的数字”,这表明它们应该在原始数据集的范围内。(对于 的输出也是如此predict(),所以我不清楚本节是否适用于绘制的决策树。)

4

0 回答 0