写点什么

总结自快速机器学习算法基准测试的重要经验

2017 年 9 月 06 日

根据 KDNuggets 网站的介绍,增强决策树正支撑着 Kaggle 机器学习挑战赛中超过半数的胜出解决方案。除了卓越的性能表现之外,这些算法亦拥有现实层面的吸引力——即最大程度降低调整需求。在今天的文章中,我们将评估两款高人气升级包:XGBoost 与 LightGBM,亦包括其 GPU 实现方案。如果您觉得文章太长而不想通读,那么我们会将对六套数据集进行测试所得出的结论总结如下:

  1. XGBoost 与 LightGBM 拥有相似的准确度水平。
  2. LightGBM 对于全部测试数据集,无论是在 CPU 抑或 GPU 之上,LightGBM 的训练时长都要短于 XGBoost 及其基于直方图方法的 XGBoost hist。两套库之间的训练时间差异主要取决于实际数据集,且时耗差别可高达 25 倍。
  3. XGBoost GPU 实现方案无法有效扩展至大型数据集当中,并曾在测试过程当中发生内存不足问题。
  4. 当特征维度较高时,XGBoost hist 的执行速度往往明显低于原始 XGBoost。

我们的全部代码皆属于开源成果,且可从此 repo 当中获取。我们将解释这些库当中所使用的具体算法,同时立足不同数据集对其加以评估。您是否希望自己的机器学习方案拥有更快的运行速度?如果是,请跟着我们的脚步继续推进。

增强决策树基础知识

梯度增强属于一种机器学习技术,其能够以弱分类器集合的形式生成预测模型,同时对可微损失函数进行优化。目前最具人气的梯度增强类型之一正是增强决策树,其内部由一组弱决策树集合组成。目前有两种不同策略可进行树计算:逐级与逐叶。其中逐级策略以逐级方式进行树状结构创建。通过这种策略,各个节点通过分割数据对靠近树根处的节点进行优先级排序。逐叶策略则立足损失变化最大的节点处进行数据分割。对于规模较小的数据集而言,逐级增长往往效果更好(逐叶增长在这类场景下往往存在过度拟合问题); 而逐叶增长则比较合适应用于大规模数据集——这是因为其速度表现要明显优于逐级增长。

(点击放大图像)

逐级增长策略对逐叶增长策略。其中逐级增长策略会随着树状层级数量的增加而带来较高复杂性。相比之下,逐叶策略则通过优化损失函数的方式生成分支。

训练强化决策树过程中的一大挑战,在于为各个“叶”找到最佳分割计算成本。对于常规技术而言,要找到各叶的精确分割方式,需要对每一次迭代当中的全部数据进行扫描。而另一种可行方法则通过构建特征直方图找出粗略分割方式。如此一来,算法本身将不必评估特征中的每个单一值,而只需计算直方图边界即可完成分割计算。这样的处理方式对于大型数据集而言效率更高,且不致对准确度产生不利影响。

XGBoost 项目始于 2014 年,且目前已经在多轮 Kaggle 挑战赛中取得优胜并积累起可观人气。最初的 XGBoost 基于一套逐级增长算法,但近期其亦添加了新的逐叶增长选项,旨在利用直方图实现近似分割。我们将这套版本称为 XGBoost hist。LightGBM 的面世时间则更晚,始于 2016 年 3 月,并于同年 8 月转为开源项目。其基于逐叶算法与直方近似值,且凭借着出色的速度表现而得到高度关注(免责声明:本篇文章的联合作者之一 Guolin Ke 为 LightGBM 项目的核心贡献者之一)。除了多线程 CPU 之外,目前 XGBoost 与 LightGBM 亦皆可利用 GPU 实现加速。

评估 XGBoost 与 LightGBM

我们面向六组不同数据集进行了机器学习测试。这些实验皆被保存在我们 GitHub repo 当中的 Python notebook 当中,感兴趣的朋友可以点击此处查看。我们还展示了实验中使用的 XGBoost 与 LightGBM 具体编译版本,同时提供实验的安装与设置步骤说明。另外,我们还尝试利用CPU 与GPU 处理分类与回归问题。全部实验皆运行在一套Azure NV24 虚拟机当中,其拥有24 个计算核心、224 GB 内存以及英伟达M60 GPU。操作系统选择了Utuntu 16.04。在全部实验当中,我们发现XGBoost 与LightGBM 的准确度表现基本相当(可参见F1 评分),因此本文将专注于讨论其训练时间差异。下表所示为这两套库在CPU 与GPU 场景下的训练时长与训练时间比。

(点击放大图像)

CPU 与 GPU 场景下 XGBoost 与 LightGBM 训练时间与训练时间比测试结果比较。其中 XGBoost GPU 训练时间并未显示(-),因为我们在过程中遭遇内存不足问题。而在 CPU 场景下利用 XGBoost 处理 Airline 数据集时(-*),我们在 5 小时后停止了计算。各组数据集的最佳训练时间以黑体显示。

来自测试的启示

虽然基准测试不能代表一切,但其中部分结论确实有其价值。通过实验,我们发现逐叶方法一般而言较逐级方法速度更快。然而,CPU 场景下的 BCI 与 Planet Kaglle 数据集处理结果,以及 GPU 场景下的 GCI 处理结果显示,XGBoost hist 的处理时长要远长于标准 XGBoost。这主要是由于数据集本身拥有庞大的体积与特征数量,导致 XGBoost 需要耗费极为可观的内存资源。

我们同时发现,XGBoost 的 GPU 实现方案在扩展性方面表现较差——其在 3 套规模较大的数据集处理过程中皆引发了内存错误。此外,我们不得不在 5 个小时之后人为中止了 XGBoost 在 Airline 数据集上的训练。

最后,在 LightGBM 与 XGBoost 之间,我们发现 LightGBM 在全部测试中皆带来优于 XGBoost 与 XGBoost hist 的速度表现,且实际速度最高可达 XGBoost 的 25 倍与 XGBoost hist 的 15 倍。

我们希望调查不同数据集规模及轮数对于 CPU 及 GPU 性能的影响。在下表当中,我们展示了使用 Airline 数据集内某一子集时的处理结果。在对 CPU 及 GPU 的训练时间进行比较时,我们发现 LightGBM 的 GPU 版本在数据集较大且轮数越多时,拥有超越 CPU 版本的表现。而正如预期那样,在使用小型数据集时,RAM 与 GPU 内存之间的数据复制 IO 开销被 GPU 自身的计算速度优势所抵消。而值得一提的是,我们在使用 XGBoost hist GPU 版本时并没有发现任何性能提升效果。顺带解释一句,根据近期的其它研究文章,与多核心 CPU 相比,XGBoost 的标准版本(即采用精确分割而非直方图方法)同样无法在 GPU 场景下得到提升。

(点击放大图像)

.XGBoost、XGBoost hist 以及 LightGBM 训练时间基准测试与不同数据规模及轮数情况下的 AUC 结果。与之前一样,XGBoost 在 GPU 场景下的 1 亿行实验同样因内存不足而未能得出结果(-)。XGBoost 的 1 亿行 500 轮训练则在运行 5 小时后被我们人为中止(-*)。各示例的最佳训练时间与最高 AUC 结果以黑体显示。

总体而言,我们发现 LightGBM 在 CPU 与 GPU 场景下的速度表现皆优于 XGBoost。另外,如果大家决定使用 XGBoost,我们建议您密切关注特征维度与内存消耗情况。LightGBM 显著的速度优势将可转化为对更多迭代进行搜索的能力及 / 或更快的超参数搜索速度。因此,如果您可用于模型优化的时间较为有限,或者希望尝试更多不同的特征工程思路,那么 LightGBM 无疑将成为更理想的选择。

祝各位工作愉快!

查看原文链接

2017 年 9 月 06 日 16:301000

评论

发布
暂无评论
发现更多内容

Serverless: 2020年函数计算的冷启动怎么样了

刘宇

Java并发之AQS源码分析

指尖流逝

Java

敏捷团队成员的工作量指标真的那么重要吗?

金生水起

敏捷开发 Scrum精髓 敏捷精髓 Agile

搜商:高效的使用搜索引擎

石云升

高效搜索 搜索技巧 搜商

数据与广告系列一:初识在线计算广告

黄崇远@数据虫巢

互联网 数据 广告

现在的我和未来的我之间的差距原来是态度,而它拉开我们彼此命运的距离。

叶小鍵

【大咖说问大咖】关于开源的那些事 —— PingCAP CTO 黄东旭 Q&A 交流帖

InfoQ写作平台官方

开源 写作平台 大咖说 技术交流 活动专区

提升编程效率:重构

Page

高效工作 敏捷开发 重构 高效

为什么我喜欢的大V拉黑我?

lmymirror

经历 后真相时代 日常思考

记一次线上事故

编号94530

Java MySQL 故障分析 事故

低代码 .VS. 无代码

Jeff Kit

低代码 零代码

从ClickHouse的名字由来讲起

nauu

数据库 大数据 分布式 OLAP Clickhouse

个人技术成长与发展

颇风

后端 技术人

看完这篇操作系统,和面试官扯皮就没问题了

cxuan

操作系统 计算机基础

Spring Cloud Kubernetes之实战网关Gateway

Damon

Kubernetes 容器 Spring Cloud 微服务冶理

游戏夜读 | 预测问题的硬核是?

game1night

练习英语口语的误区

七镜花园-董一凡

学习

如何认识更多的朋友扩展社交朋友圈的质量

吃素的左撇子

人生 人脉

Web3 极客日报#138

谢锐 | Frozen

区块链 独立开发者 技术社区 Rebase Web3 Daily

Java 中的 Mysql 时区问题

张晓辉

Kafka零数据丢失的配置方案

奈学教育

kafka kafka配置 kafka数据

MySQL索引知识介绍

Simon

MySQL 索引结构

Web3极客日报 #139

谢锐 | Frozen

区块链 独立开发者 技术社区 Rebase Web3 Daily

JVM源码分析之深入分析Object类finalize()方法的实现原理

猿灯塔

JVM

基于环信sdk在uni-app中快速开发多平台社交Demo

DT极客

一杯茶的时间,上手 Node.js

图雀社区

node.js

ClickHouse为何如此之快?

nauu

数据库 大数据 OLAP Clickhouse

Android | Tangram动态页面之路(一)需求背景

哈利迪

android

Linux 容器化技术的前世今生(虚拟化、容器化、Docker)

Meandni

Docker 云计算 Linux 容器 虚拟机

严选合伙人(一)

Neco.W

创业 合伙人 初创公司

如何优雅的实现分布式锁

张坚

redis zookeeper 分布式锁

InfoQ 极客传媒开发者生态共创计划线上发布会

InfoQ 极客传媒开发者生态共创计划线上发布会

总结自快速机器学习算法基准测试的重要经验-InfoQ