XGBoost(eXtreme Gradient Boosting)是一种机器学习算法,是梯度提升决策树(Gradient Boosting Decision Trees)的一种优化实现。它是由陈天奇在2014年开发并推出的。XGBoost是一种强大而高效的算法,被广泛用于解决各种机器学习问题,包括分类、回归、排序、推荐和异常检测等。它结合了梯度提升算法的优点,通过并行处理和优化技术,达到了高性能和高准确性的平衡。
先来举个例子,我们要预测一家人对电子游戏的喜好程度,考虑到年轻和年老相比,年轻更可能喜欢电子游戏,以及男性和女性相比,男性更喜欢电子游戏,故先根据年龄大小区分小孩和大人,然后再通过性别区分开是男是女,逐一给各人在电子游戏喜好程度上打分,得到tree1。同时对电子游戏的喜好程序一定程度上可以从每天用电脑的时间分析,得到tree2。两棵树的结论累加起来便是最终的结论,所以小孩的预测分数就是两棵树中小孩所落到的结点的分数相加:2 + 0.9 = 2.9。爷爷的预测分数同理:-1 + (-0.9)= -1.9
1.不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数ft(x),去拟合上次预测的残差,新添加的ft(x)使得我们的目标函数尽量最大地降低。
2.当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数。
3.最后只需要将每棵树对应的分数加起来就是该样本的预测值。
如何选择每一轮加入什么树呢?答案是非常直接的,选取一个 f 来使得我们的目标函数尽量最大地降低。这里 f 可以使用泰勒展开公式近似。
Xgboost的目标函数(损失函数+正则项表达):
一般的目标函数都包含这两项,其中,误差/损失函数鼓励我们的模型尽量去拟合训练数据,使得最后的模型会有比较少的 bias。而正则化项则鼓励更加简单的模型。因为当模型简单之后,有限数据拟合出来结果的随机性比较小,不容易过拟合,使得最后模型的预测更加稳定。
如下图所示,xgboost对树的复杂度包含了两个部分:
在这种新的定义下,我们可以把之前的目标函数进行如下变形:
最终公式可以化简为:
通过对wj求导等于0,可以得到:
从树深度0开始,每一节点都遍历所有的特征,比如年龄、性别等等,然后对于某个特征,先按照该特征里的值进行排序,然后线性扫描该特征进而确定最好的分割点,最后对所有特征进行分割后,我们选择所谓的增益Gain最高的那个特征。
主要针对数据太大,不能直接进行计算。
设置阈值,只有增益大于该阈值时才进行分裂。
Objective [default = reg:linear],这定义了要最小化的损失函数。最常用的值是:
eval_metric [默认根据objective参数的取值],用于验证数据的度量标准。回归的默认值为rmse,分类的误差为error。典型值为:
import os
import pandas as pd
import numpy as np
import sklearn
import xgboost as xgb
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
from tqdm import tqdm
from MyModel.utils.features import *
import warnings
warnings.filterwarnings("ignore")
def huber_approx_obj(y_pred, y_test):
d = y_pred - y_test
h = 5 # h is delta in the graphic
scale = 1 + (d / h) ** 2
scale_sqrt = np.sqrt(scale)
grad = d / scale_sqrt
hess = 1 / scale / scale_sqrt
return grad, hess
def load_datasets():
pd.set_option('display.max_columns', 1000)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)
df = pd.read_pickle('****.pickle')
features = ["key1","key2","key3","key4","key5","key6","key7"]
print(df.head(10))
df_train, df_test = sklearn.model_selection.train_test_split(df, test_size=0.2)
X_train, X_test = df_train[features], df_test[features]
print(X_test)
y_train, y_test = df_train["value"], df_test["value"]
print(y_test)
return X_train, X_test, y_train, y_test
def model_train(X_train, X_test, y_train, y_test):
regressor = xgb.XGBRegressor(obj=huber_approx_obj, n_estimators=12, max_depth=64, colsample_bytree=0.8)
print(len(X_train))
regressor.fit(X_train, y_train, eval_metric=huber_approx_obj)
y_pred_test = regressor.predict(X_test)
print(y_test)
print(y_pred_test)
error = np.median(10 ** np.abs(y_test - y_pred_test))
print(error)
def main():
X_train, X_test, y_train, y_test = load_datasets()
model_train(X_train, X_test, y_train, y_test)
if __name__ == "__main__":
main()