理解GB、GBDT、xgboost、lightGBM

GBDT和xgboost在竞赛和工业界使用都非常频繁,能有效的应用到分类、回归、排序问题,虽然使用起来不难,但是要能完整的理解还是有一点麻烦的。本文尝试一步一步梳理GB、GBDT、xgboost,它们之间有非常紧密的联系,GBDT是以决策树(CART)为基学习器的GB算法,xgboost扩展和改进了GDBT,xgboost算法更快,准确率也相对高一些。    

1. Gradient boosting(GB)

      机器学习中的学习算法的目标是为了优化或者说最小化loss Function, Gradient boosting的思想是迭代生多个(M个)弱的模型,然后将每个弱模型的预测结果相加,后面的模型Fm+1(x)基于前面学习模型的Fm(x)的效果生成的,关系如下:

1 \le m \le M     F_{m+1}(x) = F_m(x) + h(x)

      GB算法的思想很简单,关键是怎么生成h(x)?

      如果目标函数是回归问题的均方误差,很容易想到最理想的h(x)应该是能够完全拟合y - F_m(x) ,这就是常说基于残差的学习。残差学习在回归问题中可以很好的使用,但是为了一般性(分类,排序问题),实际中往往是基于loss Function 在函数空间的的负梯度学习,对于回归问题\frac{1}{2}(y - F(x))^2残差和负梯度也是相同的。L(y, f)中的f,不要理解为传统意义上的函数,而是一个函数向量\! f(x_1), \ldots, f(x_n),向量中元素的个数与训练样本的个数相同,因此基于Loss Function函数空间的负梯度的学习也称为“伪残差”。

GB算法的步骤:

  1.初始化模型为常数值:

    F_0(x) = \underset{\gamma}{\arg\min} \sum_{i=1}^n L(y_i, \gamma).

  2.迭代生成M个基学习器

    1.计算伪残差

      r_{im} = -\left[\frac{\partial L(y_i, F(x_i))}{\partial F(x_i)}\right]_{F(x)=F_{m-1}(x)} \quad \mbox{for } i=1,\ldots,n.

    2.基于\{(x_i, r_{im})\}_{i=1}^n生成基学习器\! h_m(x)

    3.计算最优的\! \gamma_m

      \gamma_m = \underset{\gamma}{\operatorname{arg\,min}} \sum_{i=1}^n L\left(y_i, F_{m-1}(x_i) + \gamma h_m(x_i)\right).

        4.更新模型

      F_m(x) = F_{m-1}(x) + \gamma_m h_m(x).

 2. Gradient boosting Decision Tree(GBDT)

     GB算法中最典型的基学习器是决策树,尤其是CART,正如名字的含义,GBDT是GB和DT的结合。要注意的是这里的决策树是回归树,GBDT中的决策树是个弱模型,深度较小一般不会超过5,叶子节点的数量也不会超过10,对于生成的每棵决策树乘上比较小的缩减系数(学习率<0.1),有些GBDT的实现加入了随机抽样(subsample 0.5<=f <=0.8)提高模型的泛化能力。通过交叉验证的方法选择最优的参数。因此GBDT实际的核心问题变成怎么基于\{(x_i, r_{im})\}_{i=1}^n使用CART回归树生成\! h_m(x)

CART分类树在很多书籍和资料中介绍比较多,但是再次强调GDBT中使用的是回归树。作为对比,先说分类树,我们知道CART是二叉树,CART分类树在每次分枝时,是穷举每一个feature的每一个阈值,根据GINI系数找到使不纯性降低最大的的feature以及其阀值,然后按照feature<=阈值,和feature>阈值分成的两个分枝,每个分支包含符合分支条件的样本。用同样方法继续分枝直到该分支下的所有样本都属于统一类别,或达到预设的终止条件,若最终叶子节点中的类别不唯一,则以多数人的类别作为该叶子节点的性别。回归树总体流程也是类似,不过在每个节点(不一定是叶子节点)都会得一个预测值,以年龄为例,该预测值等于属于这个节点的所有人年龄的平均值。分枝时穷举每一个feature的每个阈值找最好的分割点,但衡量最好的标准不再是GINI系数,而是最小化均方差--即(每个人的年龄-预测年龄)^2 的总和 / N,或者说是每个人的预测误差平方和 除以 N。这很好理解,被预测出错的人数越多,错的越离谱,均方差就越大,通过最小化均方差能够找到最靠谱的分枝依据。分枝直到每个叶子节点上人的年龄都唯一(这太难了)或者达到预设的终止条件(如叶子个数上限),若最终叶子节点上人的年龄不唯一,则以该节点上所有人的平均年龄做为该叶子节点的预测年龄。

3. Xgboost

Xgboost是GB算法的高效实现,xgboost中的基学习器除了可以是CART(gbtree)也可以是线性分类器(gblinear)。下面所有的内容来自原始paper,包括公式。

(1). xgboost在目标函数中显示的加上了正则化项,基学习为CART时,正则化项与树的叶子节点的数量T和叶子节点的值有关。

(2). GB中使用Loss Function对f(x)的一阶导数计算出伪残差用于学习生成fm(x),xgboost不仅使用到了一阶导数,还使用二阶导数。

    第t次的loss:

    对上式做二阶泰勒展开:g为一阶导数,h为二阶导数

(3). 上面提到CART回归树中寻找最佳分割点的衡量标准是最小化均方差,xgboost寻找分割点的标准是最大化,lamda,gama与正则化项相关


G、H:与数据点在误差函数上的一阶、二阶导数有关,T:叶子的个数

xgboost算法的步骤和GB基本相同,都是首先初始化为一个常数,gb是根据一阶导数ri,xgboost是根据一阶导数gi和二阶导数hi,迭代生成基学习器,相加更新学习器。

xgboost与gdbt除了上述三点的不同,xgboost在实现时还做了许多优化

  • 在寻找最佳分割点时,考虑传统的枚举每个特征的所有可能分割点的贪心法效率太低,xgboost实现了一种近似的算法。大致的思想是根据百分位法列举几个可能成为分割点的候选者,然后从候选者中根据上面求分割点的公式计算找出最佳的分割点。
  • xgboost考虑了训练数据为稀疏值的情况,可以为缺失值或者指定的值指定分支的默认方向,这能大大提升算法的效率,paper提到50倍。
  • 特征列排序后以块的形式存储在内存中,在迭代中可以重复使用;虽然boosting算法迭代必须串行,但是在处理每个特征列时可以做到并行。
  • 按照特征列方式存储能优化寻找最佳的分割点,但是当以行计算梯度数据时会导致内存的不连续访问,严重时会导致cache miss,降低算法效率。paper中提到,可先将数据收集到线程内部的buffer,然后再计算,提高算法的效率。
  • xgboost 还考虑了当数据量比较大,内存不够时怎么有效的使用磁盘,主要是结合多线程、数据压缩、分片的方法,尽可能的提高算法的效率。


<think>嗯,用户想用KNN、SVM、RandomForest、AdaBoost、XGBoost和GradientBoosting这些机器学习模型来训练PM2.5的预测模型,还需要示例代码和参数调优。首先,我得回忆一下这些模型的基本流程。通常机器学习项目的步骤包括数据预处理、特征工程、模型训练、调参和评估。用户可能需要具体的代码示例,尤其是每个模型的训练部分。 首先,数据预处理方面,PM2.5的数据可能来自大气监测,可能包含时间序列或者气象数据。需要处理缺失值,可能用填充或者删除。特征工程可能包括构造时序特征,比如前几天的PM2.5值作为特征,或者天气因素如温度、湿度等。标准化或归一化对KNN和SVM比较重要,因为这两个模型对特征的尺度敏感。分训练集和测试集是必须的,可能还需要时间序列的分割,比如按时间划分而不是随机划分,因为PM2.5数据可能有时间相关性。 然后,针对每个模型,需要给出代码示例。比如,KNN需要设置n_neighbors,SVM可能需要选择核函数,RandomForest需要n_estimators等参数。参数调优部分,通常用网格搜索或随机搜索,比如GridSearchCV。用户可能需要知道每个模型的关键参数以及如何调整它们。 接下来,考虑到用户提供的引用链接,里面提到了不同的项目,比如引用1是关于PM2.5预测的算法对比,可能里面有相关的特征处理或模型应用的经验。引用3提到集成学习中的Adaboost、GBDTXGBoost等,可能调参部分可以参考这些内容。引用5中的工业产量预测可能涉及类似的数据预处理步骤,比如特征构造和模型选择。 需要注意的是,用户可能需要代码示例,所以每个模型的训练和调优部分需要分开写,比如先给出基础训练代码,再说明调参方法。同时,参数调优部分需要指出每个模型的重要参数,比如XGBoost的n_estimators、learning_rate、max_depth等。 可能用户还会关心模型评估指标,比如MAE、RMSE、R²,这些应该在代码中体现出来。另外,特征重要性分析对于树模型可能有用,比如RandomForest和XGBoost可以输出特征重要性,帮助理解哪些因素影响PM2.5。 另外,需要注意数据泄露问题,尤其是在时间序列数据中,划分数据集时要确保测试集的数据在训练集之后,避免用未来数据预测过去。这可能需要在train_test_split时设置shuffle=False,或者使用TimeSeriesSplit。 对于每个模型的具体实现,比如KNN的K值选择,可能需要通过交叉验证来确定。SVM的参数C和gamma也需要调整,特别是当数据量较大时,SVM可能训练速度较慢,需要考虑使用线性核或者其他方法加速。 在代码示例中,可能需要使用Scikit-learn的API,比如KNeighborsRegressor、SVR、RandomForestRegressor、AdaBoostRegressor,以及XGBoost和GradientBoosting的对应类。需要确保用户安装了这些库,比如xgboostlightgbm可能需要单独安装。 参数调优部分,比如对RandomForest,调整n_estimators、max_depth、min_samples_split等;AdaBoost调整n_estimators和learning_rate;XGBoost的参数较多,包括学习率、树的深度、子样本比例等。 最后,可能需要给出一些建议,比如对于高维数据,SVM可能不太适合,或者树模型对缺失值不敏感,可以不需要处理缺失值等。另外,集成模型通常需要更多的计算资源,调参空间更大,可能需要更细致的调整。 可能还需要考虑特征选择,比如使用RFECV或者基于模型的特征重要性来选择重要特征,减少过拟合风险。此外,可视化部分,比如绘制真实值与预测值的对比图,或者残差图,可能对用户有帮助,但用户没有特别提到,所以可能不需要包含在回答中,除非示例代码中简单提及。 综上,回答的结构应该是先整体流程,再分模型给出代码示例和调参方法,最后总结注意事项。需要确保代码正确,参数合理,并引用提供的参考资料中的相关内容,比如引用1中的算法对比可能提到不同模型在PM2.5预测中的表现,可以引用作为调参重要性的依据。</think>### PM2.5预测模型构建步骤及代码示例 #### 一、数据预处理与特征工程 1. **数据清洗** - 处理缺失值:用均值/中位数填充或删除 - 异常值检测:使用$3\sigma$原则或IQR方法 2. **特征构造** - 时序特征:前$N$天的PM2.5均值、滑动窗口统计量 - 气象特征:温度、湿度、风速等交互项 3. **标准化处理** ```python from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_scaled = scaler.fit_transform(X) ``` 4. **数据集划分** ```python from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, shuffle=False) # 时间序列需禁用shuffle ``` --- #### 二、模型训练与示例代码 ##### 1. KNN回归 ```python from sklearn.neighbors import KNeighborsRegressor knn = KNeighborsRegressor(n_neighbors=5, weights='distance') knn.fit(X_train, y_train) ``` ##### 2. SVM回归 ```python from sklearn.svm import SVR svr = SVR(kernel='rbf', C=1.0, epsilon=0.1) svr.fit(X_train, y_train) ``` ##### 3. 随机森林回归 ```python from sklearn.ensemble import RandomForestRegressor rf = RandomForestRegressor(n_estimators=100, max_depth=10, random_state=42) rf.fit(X_train, y_train) ``` ##### 4. AdaBoost回归 ```python from sklearn.ensemble import AdaBoostRegressor ada = AdaBoostRegressor(n_estimators=50, learning_rate=0.1) ada.fit(X_train, y_train) ``` ##### 5. XGBoost回归 ```python import xgboost as xgb xgb_model = xgb.XGBRegressor( n_estimators=100, learning_rate=0.1, max_depth=5, subsample=0.8 ) xgb_model.fit(X_train, y_train) ``` ##### 6. GradientBoosting回归 ```python from sklearn.ensemble import GradientBoostingRegressor gb = GradientBoostingRegressor( n_estimators=100, learning_rate=0.1, max_depth=3 ) gb.fit(X_train, y_train) ``` --- #### 三、参数调优方法(以XGBoost为例) ```python from sklearn.model_selection import GridSearchCV param_grid = { 'max_depth': [3, 5, 7], 'learning_rate': [0.01, 0.1, 0.2], 'subsample': [0.6, 0.8, 1.0] } grid_search = GridSearchCV(xgb_model, param_grid, cv=5, scoring='neg_mean_squared_error') grid_search.fit(X_train, y_train) print("最优参数:", grid_search.best_params_) ``` --- #### 四、模型评估 ```python from sklearn.metrics import mean_absolute_error, r2_score y_pred = model.predict(X_test) print(f"MAE: {mean_absolute_error(y_test, y_pred):.2f}") print(f"R²: {r2_score(y_test, y_pred):.2f}") ``` --- #### 五、关键注意事项 1. **时序特征处理**:PM2.5预测需考虑时间依赖性,建议使用滞后特征或滑动窗口[^1] 2. **树模型优势**:随机森林/XGBoost对缺失值和特征交互更鲁棒[^3] 3. **计算效率**:SVM在大数据场景下需采用线性核或采样策略[^5] ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值