YDF高级特征指南:时序、多维、预训练嵌入特征喂给决策树的简单方法
【免费下载链接】yggdrasil-decision-forestsA library to train, evaluate, interpret, and productionize decision forest models such as Random Forest and Gradient Boosted Decision Trees.项目地址: https://gitcode.com/gh_mirrors/yg/yggdrasil-decision-forests
YDF(Yggdrasil Decision Forests)是一个开源决策森林库,用于训练、评估、解释和部署随机森林(Random Forest)与梯度提升树(GBDT)模型。本文是一份面向新手的完整指南,讲清楚如何把三类"高级"特征——时序事件流、多维向量、预训练模型产出的嵌入向量——用简单的方式喂给决策树,而不必自己造轮子。
为什么决策树也能吃"高级特征"?
很多人觉得决策树只适合干净的表格数据。实际上,YDF 通过"特征语义(Feature Semantic)"机制来解决这个问题:训练时 YDF 会自动识别每个特征的类型(数值、类别、布尔、类别集合、离散化数值),并据此选择最优的分裂方式。
- NUMERICAL(数值):按阈值分裂,例如
age >= 30 - CATEGORICAL(类别):按值集合分裂,例如
country in {USA, DE},无需 one-hot - BOOLEAN(布尔):内存和速度优化过的特化语义
- CATEGORICAL_SET(类别集合):按集合交集分裂,适合标签组、分词后的文本
- DISCRETIZED_NUMERICAL(离散化数值):加速训练约 2 倍的数值语义
这意味着:只要你能把数据表示成"每个样本一行、每列一个特征",YDF 就能训练。下面三类高级特征正好都落在这张表里。
时序特征:别喂原始时间戳,要喂"统计特征"
📌 典型场景:银行交易流水、销售日志、网络日志、病人体征——每一条记录是一个带时间戳的事件,事件之间采样并不均匀。
关键原则来自官方 guide_feature_semantics.md:
- 时间戳 → 日历特征:直接转成 Unix 时间戳效果很差,应拆成"星期几、月份中的第几周、一天中的几点"这类日历特征。
- 事件流 → 滑动窗口统计:围绕客户/终端等 ID,计算过去 1 天/1 周/4 周内的交易次数、金额总和、欺诈次数等。
官方教程 time_sequences.ipynb 给出了完整演示:用信用卡交易数据集识别欺诈,把"过去 4 周内同一终端的欺诈次数"等窗口特征算好后喂给 YDF。模型解释时可以看到,per_terminal.moving_sum_frauds(终端级滑动欺诈求和)是最重要的特征,而"星期几"几乎不重要——这正是时序特征工程的正确打开方式。
对于复杂时序问题,官方建议使用 Time sequences 教程 中集成的 Temporian 时序预处理库,它能自动保证"只用过去的数据",避免未来数据泄漏。
多维特征:一个向量自动展开成多个特征 🚀
📌 典型场景:图像像素、传感器多通道读数、任何"定长向量"。
YDF 原生支持定长向量作为特征:把一个(N, D)的 NumPy 数组直接放进数据集字典即可。YDF 会把向量的每个维度"展开(unroll)"成一个独立特征,自动命名为feature.0_of_D、feature.1_of_D这样的格式(例如categorical_vector.0_of_2)。
两个注意点:
- 所有样本的向量长度必须一致(定长向量)。如果长度不定,请改用 CATEGORICAL_SET 语义。
- 类别型向量同样支持,展开后每个维度都是独立的 CATEGORICAL 特征。
更多细节见官方教程 multidimensional_feature.ipynb。
预训练嵌入向量:文本/图像编码器输出直接可用
📌 这是多维特征最经典的用法:先用预训练模型(如 Universal Sentence Encoder)把一段文本编码成 512 维数值向量,然后把这 512 维向量作为一列直接喂给 YDF。
流程非常简单:
- 离线推理:用预训练编码器给每条样本生成嵌入向量(这一步在 YDF 之外完成)。
- 直接训练:嵌入向量作为多维 NUMERICAL 特征进入随机森林/GBDT,512 维会被展开成
text.0_of_512…text.511_of_512。
决策森林在稀疏、噪声大的表格化数据上表现稳定,与预训练编码器结合后,既能继承深度模型的语义能力,又保留树模型的可解释性和低推理成本。官方 multidimensional_feature.ipynb 教程中就用嵌入类特征做了演示,并通过模型描述(describe())查看每棵树的分裂结构。
⚠️ 注意:原始图像像素这类"视觉原始输入"并不适合决策森林,官方建议这类场景优先用神经网络;但编码器产出的紧凑嵌入向量是决策森林的强项。
变长标签/分词文本:用 CATEGORICAL_SET 语义
📌 典型场景:网页标签{politics, elections}、商品 tag 集合、分词后的文本。
与定长向量相反,变长的类别值序列要用ydf.Semantic.CATEGORICAL_SET语义:YDF 按"集合交集"来分裂(例如"文本词集是否包含 {cat, dog}")。
使用建议:
- 别用 CATEGORICAL_SET 代替 CATEGORICAL:结果相同但训练更慢。
- 文本要先分词:按空格切分对英文尚可,中文请换更专业的分词器;可用双词(bi-gram)保留部分位置信息。
- 读取 CSV 时,CATEGORICAL_SET 列会自动按空格分词,详见 dataset_formats.md。
三个常见"坑",帮你少走弯路 ⚠️
| 常见做法 | 正确做法 |
|---|---|
| 对类别特征做 one-hot 编码 | 直接喂 CATEGORICAL,树模型天然支持集合分裂 |
| 把数值特征分桶(0-5, 5-10…) | 尽量直接喂原始数值,分桶会损失信息 |
| 保留 ID / unique_hash 列 | 训练前删除,会拖慢训练并增大模型 |
| 时间戳直接转 Unix 秒数 | 拆成日历特征 + 滑动窗口统计特征 |
另外,YDF 会自动把罕见类别值替换为 OOD(out-of-dictionary)以防过拟合,由超参数max_vocab_count和min_vocab_frequency控制;缺失值也会按语义自动插补(数值取均值、类别取众数),你不需要自己填充缺失值。
训练之后:评估与解释一步到位
训练完成后,model.evaluate()会自动生成 ROC、精确率-召回率、阈值-准确率、阈值-样本量四类曲线(如图所示),方便你挑业务阈值。
model.describe()则给出特征重要性、每棵树的分裂结构等解释信息——即使你的特征是嵌入向量或时序统计量,模型依然是可解释的树,这也是决策森林用于风控、信贷等场景的核心价值。
快速上手:三步喂入高级特征
- 安装:
pip install ydf - 准备数据:把时序统计特征、多维向量、嵌入向量组织成"字典 of NumPy 数组"(小数据)或 Avro 文件(大数据、分布式训练),格式说明见 dataset_formats.md。
- 训练并查看语义:调用
ydf.RandomForestLearner(label="label").train(ds),再用model.describe()检查"Dataspec"页确认每个特征的语义是否符合预期。
语义定义与完整类型转换规则请参考 guide_feature_semantics.md。按照上面的方法,时序、多维向量和预训练嵌入这些"高级特征"喂给决策树,其实只需要几行代码的距离 🌲
【免费下载链接】yggdrasil-decision-forestsA library to train, evaluate, interpret, and productionize decision forest models such as Random Forest and Gradient Boosted Decision Trees.项目地址: https://gitcode.com/gh_mirrors/yg/yggdrasil-decision-forests
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考