使用 Python XGBoost 进行梯度提升

我过去参加过很多 Kaggle 比赛,在过去的 3-4 年里,所有获奖作品都使用了某种形式的梯度提升。因此,我们今天就来仔细研究一下。

什么是梯度提升?

集成学习:为了获得比单独从任何组成学习算法中提取的预测效率更高的预测效率,集成方法使用多种学习算法。

个体模型存在偏差或方差是很常见的,这就是我们需要学习集成学习的原因。

Baggingboosting是两种最常见的集成技术。

  • Bagging:使用很多模型进行并行训练。每个模型都由数据的随机子集进行训练。
  • Boosting:依次教授许多附加模型。每个特定模型都会从先前模型所犯的错误中进行学习。

虽然您之前已经学习过bagging技术(例如随机森林),但让我们看看什么是 boosting。

一类机器学习算法,将多个弱学习模型合并在一起,产生一个称为梯度增强分类器的强预测模型。

在进行梯度提升时,通常使用决策树。由于梯度增强模型在复杂数据集分类方面的有效性,梯度增强模型变得越来越普遍,并且最近已被用来赢得Kaggle数据科学的多项竞赛!

Scikit-Learn是 Python 机器学习库,支持各种梯度提升分类器实现,包括 XGBoost、light Gradient Boosting、catBoosting 等。

什么是XGBoost?

XGBoost 是处理标准表格数据的领先模型(而不是更奇特的数据类型,如图像和视频,即存储在Pandas DataFrames中的数据类型)。许多 Kaggle 比赛都以 XGBoost 模型为主。

与随机森林等策略相比,XGBoost 模型需要更多的专业知识和模型调整才能实现最佳精度。

而且非常简单。

房价数据集上梯度提升的实现

我正在使用 Kaggle.com 上一个非常流行的数据集,称为房价预测 (HPP) 数据集

本次竞赛有 79 个解释变量(几乎)描述了爱荷华州艾姆斯住宅的各个方面,挑战您预测每套住宅的最终价格。

让我们开始吧!

1. 导入所需包

让我们导入重要的包:

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.impute import SimpleImputer
from xgboost import XGBRegressor

插补器用于使用平均值、众数或任何其他选择的方法“插补”(替换)数据集中的 NaN 值。

2. 设置数据

让我们导入我们的训练数据:

data_train = pd.read_csv('train.csv')
data_train.dropna(axis=0, subset=['SalePrice'], inplace=True)
data_train.head(1)

我们删除SalePrice中包含 NaN 的行,因为这是我们最重要的度量。

使用梯度提升的数据集房价预测

我们将分配 SalePrice 作为标签(即 AX = y 格式):

y = data_train.SalePrice
X = data_train.drop(['SalePrice'], axis=1).select_dtypes(exclude=['object'])

我们使用 sklearn 的 train_test_split 函数将数据以 3:1 的比例划分为训练数据和测试数据:

train_X, test_X, train_y, test_y = train_test_split(X.values, y.values, test_size=0.25)
火车数据房屋价格预测

让我们对数据集中的NaN 值进行插补:

my_imputer = SimpleImputer()
train_X = my_imputer.fit_transform(train_X)
test_X = my_imputer.transform(test_X)

现在我们已经完成了预处理。显然,我们可以调整数据集的每一列,查找异常值,正则化等,但这是你的作业!

3. 创建模型

让我们创建我们的模型:

my_model = XGBRegressor()
 
my_model.fit(train_X, train_y, verbose=True)

正如您在输出中看到的,这些是我们可以指定来调整模型的所有参数:

XGBRegressor(base_score=0.5, booster='gbtree', colsample_bylevel=1, colsample_bynode=1, colsample_bytree=1, gamma=0, importance_type='gain', learning_rate=0.1, max_delta_step=0, max_depth=3, min_child_weight=1, missing=None, n_estimators=100, n_jobs=1, nthread=None, objective='reg:linear', random_state=0, reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None, silent=None, subsample=1, verbosity=1)

我们现在可以做出预测:

predictions = my_model.predict(test_X)
predictions

这给了我们:

预测输出爱荷华州房价,Kaggle

我们还可以找到回归误差,结果约为 17000:

from sklearn.metrics import mean_absolute_error
print("Mean Absolute Error : " + str(mean_absolute_error(predictions, test_y)))

梯度提升的完整代码实现

如果您错过了任何步骤,您可以在此处找到完整的代码以及数据集:

https://github.com/arkaprabha-majumdar/house-price-prediction

其他形式 – 轻型 GBM 和 catBoost

用法与XGB完全相同:

from lightgbm import LGBMRegressor
my_model = LGBMRegressor()
my_model.fit(train_X, train_y, verbose=True)

from catboost import CatBoostRegressor
my_model = CatBoostRegressor()
my_model.fit(train_X, train_y, verbose=True)

过程是一样的。

LightGBM:Light GBM,基于决策树算法,是一种快速、分布式、高性能的梯度提升系统,用于机器学习中的排序、分类和许多其他任务。

它按叶子方式划分以获得最佳匹配,而其他增强算法则按深度或级别而不是按叶方式破坏树。

因此,当在 Light GBM 中的同一叶子上增加时,leaf-wise 算法可以比 level-wise 算法减少更多的损失,从而获得更高的精度,这是当前任何 boosting 算法都很难实现的。

它也令人惊讶地非常快。lightGBM的训练过程的执行时间存在显着差异,因此现在更倾向于将其作为“快速修复

CatBoost:作为一种更好的梯度提升算法,Catboost 实现了有序提升,但 catboost 最大的进步在于它如何处理分类信息。由于需要提供数字编码,分类数据引入了许多问题。

Catboost 使用目标编码变体来确定具有可用历史记录和随机排列的目标编码,以对我们的分类数据进行编码并处理。Catboost 不使用平均值,而是使用可用上下文,因为实时运行的模型不知道其目标的真实平均值。

人们对上述所有算法都做了一些基准测试。浏览它们:

https://www.kaggle.com/nholloway/catboost-v-xgboost-v-lightgbm

然而,总体来说,catBoost 速度慢而且效果不是很好。尝试进行您自己的基准测试,并在评论中告诉我们您更喜欢哪一个。

结论

梯度提升是一种强大的数据分类和回归机制,可以加快您学习新机器学习算法的速度。