# 实验
## 对比实验
详细的实验脚本和输出日志部分请参考 [repo](https://github.com/guolinke/boosting_tree_benchmarks).
### 数据集
我们使用4个数据集进行对比实验,有关数据的细节在下表列出:
| **数据集** | **任务** | **链接** | **训练集** | **特征** | **注释** |
| --- | --- | --- | --- | --- | --- |
| Higgs | 二分类 | [link](https://archive.ics.uci.edu/ml/datasets/HIGGS) | 10,500,000 | 28 | 使用余下50万个样本作为测试集 |
| Yahoo LTR | 机器学习排序 | [link](https://webscope.sandbox.yahoo.com/catalog.php?datatype=c) | 473,134 | 700 | set1.train为训练集,set1.test为测试集 |
| MS LTR | 机器学习排序 | [link](http://research.microsoft.com/en-us/projects/mslr/) | 2,270,296 | 137 | {S1,S2,S3}为训练集,{S5} 为测试集 |
| Expo | 二分类 | [link](http://stat-computing.org/dataexpo/2009/) | 11,000,000 | 700 | 使用余下100W个样本作为测试集 |
| Allstate | 二分类 | [link](https://www.kaggle.com/c/ClaimPredictionChallenge) | 13,184,290 | 4228 | 使用余下100W个样本作为测试集 |
### 硬件环境
我们使用一台Linux服务器作为实验平台,具体配置如下:
| **OS** | **CPU** | **Memory** |
| --- | --- | --- |
| Ubuntu 14.04 LTS | 2 * E5-2670 v3 | DDR4 2133Mhz, 256GB |
### 底层
我们使用 [xgboost](https://github.com/dmlc/xgboost) 作为底层算法。
并且 xgboost 和 LightGBM 都基于 OpenMP 构建。
### 设置
我们为该实验建立了3个设置 , 这些设置的参数如下:
1. xgboost:
```
eta = 0.1
max_depth = 8
num_round = 500
nthread = 16
tree_method = exact
min_child_weight = 100
```
2. xgboost_hist (使用直方图算法):
```
eta = 0.1
num_round = 500
nthread = 16
tree_method = approx
min_child_weight = 100
tree_method = hist
grow_policy = lossguide
max_depth = 0
max_leaves = 255
```
3. LightGBM:
```
learning_rate = 0.1
num_leaves = 255
num_trees = 500
num_threads = 16
min_data_in_leaf = 0
min_sum_hessian_in_leaf = 100
```
xgboost 通过 `max_depth` 对建树进行深度限制与模型复杂度控制 。
LightGBM 通过 `num_leaves` 执行带深度限制的 leaf-wise 叶子生长策略与模型复杂度控制。
因此我们无法设置完全相同的模型进行比较。为了相对权衡, 我们在xgboost中设置 `max_depth=8` 以使叶子数量达到最大数量 255 与 LightGBM 中设置 `num_leves=255` 进行比较。
其他参数皆为默认值
### 结论
#### 效率
为了比较效率, 我们只运行没有任何测试或者度量输出的训练进程,并且我们不计算 IO 的时间。
如下是耗时的对比表格:
| **Data** | **xgboost** | **xgboost_hist** | **LightGBM** |
| --- | --- | --- | --- |
| Higgs | 3794.34 s | 551.898 s | **238.505513 s** |
| Yahoo LTR | 674.322 s | 265.302 s | **150.18644 s** |
| MS LTR | 1251.27 s | 385.201 s | **215.320316 s** |
| Expo | 1607.35 s | 588.253 s | **138.504179 s** |
| Allstate | 2867.22 s | 1355.71 s | **348.084475 s** |
我们发现在所有数据集上 LightGBM 都比 xgboost 快。
#### 准确率
为了比较准确率, 我们使用数据集测试集部分的准确率进行公平比较。
| **Data** | **Metric** | **xgboost** | **xgboost_hist** | **LightGBM** |
| --- | --- | --- | --- | --- |
| Higgs | AUC | 0.839593 | 0.845605 | 0.845154 |
| Yahoo LTR | NDCG<sub>1</sub> | 0.719748 | 0.720223 | 0.732466 |
| NDCG<sub>3</sub> | 0.717813 | 0.721519 | 0.738048 |
| NDCG<sub>5</sub> | 0.737849 | 0.739904 | 0.756548 |
| NDCG<sub>10</sub> | 0.78089 | 0.783013 | 0.796818 |
| MS LTR | NDCG<sub>1</sub> | 0.483956 | 0.488649 | 0.524255 |
| NDCG<sub>3</sub> | 0.467951 | 0.473184 | 0.505327 |
| NDCG<sub>5</sub> | 0.472476 | 0.477438 | 0.510007 |
| NDCG<sub>10</sub> | 0.492429 | 0.496967 | 0.527371 |
| Expo | AUC | 0.756713 | 0.777777 | 0.777543 |
| Allstate | AUC | 0.607201 | 0.609042 | 0.609167 |
#### 内存消耗
我们在运行训练任务时监视 RES,并在 LightGBM 中设置 `two_round=true` (将增加数据载入时间,但会减少峰值内存使用量,不影响训练速度和准确性)以减少峰值内存使用量。
| **Data** | **xgboost** | **xgboost_hist** | **LightGBM** |
| --- | --- | --- | --- |
| Higgs | 4.853GB | 3.784GB | **0.868GB** |
| Yahoo LTR | 1.907GB | 1.468GB | **0.831GB** |
| MS LTR | 5.469GB | 3.654GB | **0.886GB** |
| Expo | 1.553GB | 1.393GB | **0.543GB** |
| Allstate | 6.237GB | 4.990GB | **1.027GB** |
## 并行测试
### 数据集
我们使用 `terabyte click log` 数据集进行并行测试,详细信息如下表:
| **数据** | **任务** | **链接** | **数据集** | **特征** |
| --- | --- | --- | --- | --- |
| Criteo | 二分类 | [link](http://labs.criteo.com/2013/12/download-terabyte-click-logs/) | 1,700,000,000 | 67 |
该数据集包含了 24 天点击记录,其中有 13 个整数特征与 26 个类别特征。
我们统计了该数据集 26 个类别前十天的点击率和计数,使用接下来十天的数据作为训练集并且该训练集中类别已与点击率和计数相对应。
处理后的训练集共有 17 亿条数据和 67 个特征。
### 环境
我们使用了 16 台 Windows 服务器作为实验平台,详细信息如下表:
| **OS** | **CPU** | **Memory** | **Network Adapter** |
| --- | --- | --- | --- |
| Windows Server 2012 | 2 * E5-2670 v2 | DDR3 1600Mhz, 256GB | Mellanox ConnectX-3, 54Gbps, RDMA support |
### 设置:
```
learning_rate = 0.1
num_leaves = 255
num_trees = 100
num_thread = 16
tree_learner = data
```
我们在此使用并行数据,因为该数据集数据量大但是特征少。
其他参数皆为默认值
### 结论
| **#Machine** | **Time per Tree** | **Memory Usage(per Machine)** |
| --- | --- | --- |
| 1 | 627.8 s | 176GB |
| 2 | 311 s | 87GB |
| 4 | 156 s | 43GB |
| 8 | 80 s | 22GB |
| 16 | 42 s | 11GB |
从结果看,我们发现 LightGBM 在分布式学习中可以做到线性加速。
## GPU 实验
参考 [GPU 性能](./GPU-Performance.rst).