编程语言
首页 > 编程语言> > XGBoost -  算法理论以及实例

XGBoost -  算法理论以及实例

作者:互联网

XGBoost是一种基于Boost算法的机器学习方法,全称EXtreme Gradient Boosting
XGBoost在GBDT的基础上,引入了:

  1. CART回归树
  2. 正则项
  3. 泰勒公式二阶导数
  4. Blocks数据结构(用于加速运算)
    从而实现了比GBDT更好的实现效果。

一. 理论

关于XGBoost的理论在官网上介绍地很清楚,可以参考: https://xgboost.readthedocs.io/en/stable/tutorials/model.html

函数模型

XGBoost 的目标模型可以表示为:
image
其中L(θ)为损失项,Ω(θ)为正则项。正则项反映了模型的复杂程度。
一般L(θ)可以用方差来进行统计:
image
用于逻辑回归中:
image
下图可以解释两者和模型匹配程度之间的关系:
image

回归树

XGBoost树集成模型由一组分类和回归树 (CART) 组成。下面是一个 CART 的简单示例,用于对某人是否会喜欢假设的电脑游戏 X 进行分类。
image
我们将一个家族的成员分类为不同的叶子,并给他们分配相应叶子上的分数。CART 与决策树略有不同,在决策树中,叶仅包含决策值。在CART中,每片叶子都有一个真实的分数,这给了我们更丰富的解释,超越了分类。这也允许采用有原则的统一优化方法,我们将在本教程的后面部分中看到。
通常,一棵树不够坚固,无法在实践中使用。实际使用的是集成模型,它将多个树的预测相加。
image
在数学上,我们可以将模型写成
image
其中K是树的数量,f(x)是函数空间中的函数,并且是所有可能的 CART 的集合。要优化的目标函数由下式给出
image

XGBoost

下面给出用XGBoost求解的步骤,这部分参考:
https://zhuanlan.zhihu.com/p/162001079

一:重新定义一棵树

image

二:定义这棵树的复杂度

image

三:分组节点

image
合并一次项系数、二次项系数。
image

四:求解目标值

image
image
优化目标即让Obj的值尽可能的小

分裂点选择

训练树时,分裂点的选择有如下几种算法:

二. 实例

用XGBoost做回归:

用TPS2022 Mar的题目做示例,用过时间预测道路拥堵程度:

原始数据
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.metrics import mean_absolute_error, mean_squared_error

train_orig = pd.read_csv('train.csv', index_col='row_id', parse_dates=['time'])
train_orig.head()

image

特征工程
%%time
#用道路和方向进行OneHot编码

# Feature engineering
# Combine x, y and direction into a single categorical feature with 65 unique values
# which can be one-hot encoded
def place_dir(df):
    return df.apply(lambda row: f"{row.x}-{row.y}-{row.direction}", axis=1).values.reshape([-1, 1])

for df in [train_orig]:
    df['place_dir'] = place_dir(df)
    
ohe = OneHotEncoder(drop='first', sparse=False)
ohe.fit(train_orig[['place_dir']])

def engineer(df):
    """Return a new dataframe with the engineered features"""
    
    new_df = pd.DataFrame(ohe.transform(df[['place_dir']]),
                          columns=ohe.categories_[0][1:],
                          index=df.index)
    new_df['saturday'] = df.time.dt.weekday == 5
    new_df['sunday'] = df.time.dt.weekday == 6
    new_df['daytime'] = df.time.dt.hour * 60 + df.time.dt.minute
    new_df['dayofyear'] = df.time.dt.dayofyear # to model the trend
    return new_df


train = engineer(train_orig)

train['congestion'] = train_orig.congestion

features = list(train.columns)
print(list(features))

处理后的数据:
image

数据分割
# Split into train and test
# Use all Monday-Wednesday afternoons in August and September for validation
val_idx = ((train_orig.time.dt.month >= 8) & 
           (train_orig.time.dt.weekday <= 3) &
           (train_orig.time.dt.hour >= 12)).values
train_idx = ~val_idx

X_tr, X_va = train.loc[train_idx, features], train.loc[val_idx, features]
y_tr, y_va = train.loc[train_idx, 'congestion'], train.loc[val_idx, 'congestion']
AdaBoost
%%time

from sklearn.ensemble import AdaBoostRegressor

regr = AdaBoostRegressor(random_state=0, n_estimators=100)
regr.fit(X_tr, y_tr)
y_pred = regr.predict(X_va)
mean_absolute_error(y_pred, y_va)
GDBT
%%time

from sklearn.ensemble import GradientBoostingRegressor

regr = GradientBoostingRegressor(random_state=0, n_estimators=100)
regr.fit(X_tr, y_tr)
y_pred = regr.predict(X_va)
mean_absolute_error(y_pred, y_va)
XGBoost
%%time

import xgboost as xgb

model = xgb.XGBRegressor(n_estimators=200)
model.fit(X_tr, y_tr)
y_pred = model.predict(X_va)
score_xgb = mean_absolute_error(y_pred, y_va)
结果:
算法 结果
AdaBoost 13.654161859220649
GBDT 7.55620711428925
XGBoost 5.880979271309312

XGBoost参数:

详见官网,也可以参考这篇博客:https://www.cnblogs.com/TimVerion/p/11436001.html
image

XGBoost做特征挖掘

XGBoost还有一个常用功能是做特征挖掘,挖掘房价预测的相关性示例:
清洗后的数据:
image

在挖掘特征相关性之前,需要提前做一次预测:

%%time

xgbr = xgb.XGBRegressor(verbosity=0, n_estimators=100)
xgbr.fit(X_train, y_train)
y_pred = xgbr.predict(X_test)

之后用XGBoost自带的方法就可以plot模型中各个特征相关情况

xgb.plot_importance(xgbr) 

image

标签:实例,df,XGBoost,tr,算法,train,time,import
来源: https://www.cnblogs.com/Asp1rant/p/15997535.html