XGBoost

    最近使用XGBoost做一个二分类的任务。记录XGBoost的主要参数和调参过程。

1. XGBoost

    XGBoost是一种十分精致的算法,可以处理各种不规则的数据。
构造一个使用XGBoost的模型十分简单。但是,提高这个模型的表现就有些困难,因为涉及到很多参数。所以为了提高模型的表现,参数的调整十分必要。

1.1. XGBoost的优势

  • 正则化
    正则化防止过拟合,实际上,XGBoost以“正则化提升(regularized boosting)”技术而闻名。
  • 缺失值处理
    XGBoost内置处理缺失值的规则。XGBoost在不同节点遇到缺失值时采用不同的处理方法,并且会学习未来遇到缺失值的处理方法

1.2. 参数

    XGBoost实际上是很多CART树堆叠起来。传入的特征可以含有None值。XGBoost有很多参数,使用GridSearchCV进行网格搜索时比较耗时。

使用pip install xgboost安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
XGBClassifier(
base_score=0.5,
booster='gbtree',
colsample_bylevel=1,
colsample_bytree=1,
gamma=0,
learning_rate=1,
max_delta_step=0,
max_depth=2,
min_child_weight=1,
missing=None,
n_estimators=2,
n_jobs=1,
nthread=None, objective='binary:logistic', random_state=0,
reg_alpha=0,
reg_lambda=1,
scale_pos_weight=1,
seed=None,
silent=True,
subsample=1)

XGBoost参数有3类:
https://www.cnblogs.com/wanglei5205/p/8579244.html
(1)通用类别:不需要调整,默认就好:

  • booster:[默认gbtree]
    选择每次迭代的模型,有两种选择:
    gbtree:基于树的模型
    gbliner:线性模型
  • silent[默认0]
    当这个参数值为1时,静默模式开启,不会输出任何信息。
    一般这个参数就保持默认的0,因为这样能帮我们更好地理解模型。
  • nthread[默认值为最大可能的线程数]
    这个参数用来进行多线程控制,应当输入系统的核数。
    如果你希望使用CPU全部的核,那就不要输入这个参数,算法会自动检测它。

(2)学习目标参数:与任务有关

  • objective:损失函数,支持分类/回归
    [默认reg:linear],这个参数定义需要被最小化的损失函数。最常用的值有:
    binary:logistic 二分类的逻辑回归,返回预测的概率(不是类别)。
    multi:softmax 使用softmax的多分类器,返回预测的类别(不是概率)。
    在这种情况下,你还需要多设一个参数:num_class(类别数目)。
    multi:softprob 和multi:softmax参数一样,但是返回的是每个数据属于各个类别的概率。
  • eval_metric:评价函数,对于回归问题,默认值是rmse,对于分类问题,默认值是error。
    典型值有:
    rmse 均方根误差
    logloss 负对数似然函数值
    error 二分类错误率(阈值为0.5)
    merror 多分类错误率
    mlogloss 多分类logloss损失函数
    auc 曲线下面积

  • seed:随机数的种子,默认为0
    设置它可以复现随机数据的结果,也可以用于调整参数

(3)booster参数:弱学习器参数,需要仔细调整,会影响模型性能
学习率和n_estimators具有相反的关系,建议学习率设小,通过交叉验证确定n_estimators

  • eta[默认0.3],和GBM中的 learning rate 参数类似。 通过减少每一步的权重,可以提高模型的鲁棒性。 典型值为0.01-0.2。

和树有关的参数

  • min_child_weight[默认1],最小样本权重的和,用于避免过拟合。但是如果这个值过高,会导致欠拟合。这个参数需要使用CV来调整。
  • max_depth[默认6],树的最大深度。 用来避免过拟合的。max_depth越大,模型越复杂,学到更具体更局部的样本。 需要使用CV函数来进行调优。 典型值:3-10
  • gamma[默认0],Gamma指定了节点分裂所需的最小损失函数下降值。这个参数的值越大,算法越保守。这个参数的值和损失函数息息相关,所以是需要调整的。
  • subsample[默认1]
    和GBM中的subsample参数一模一样。这个参数控制对于每棵树,随机采样的比例。减小这个参数的值,算法会更加保守,避免过拟合。但是,如果这个值设置得过小,它可能会导致欠拟合。
    典型值:0.5-1
  • colsample_bytree[默认1]
    和GBM里面的max_features参数类似。用来控制每棵随机采样的列数的占比(每一列是一个特征)。
    典型值:0.5-1

和正则化有关的参数

  • lambda[默认1]
    权重的L2正则化项。(和Ridge regression类似)。
    这个参数是用来控制XGBoost的正则化部分的。虽然大部分数据科学家很少用到这个参数,但是这个参数在减少过拟合上还是可以挖掘出更多用处的。
  • alpha[默认1]
    权重的L1正则化项。(和Lasso regression类似)。
    可以应用在很高维度的情况下,使得算法的速度更快。
    样本不均衡

  • scale_pos_weight[默认1]
    正样本占的比重,为1时表示正负样例比重是一样的。当正样本较少时,正样本:负样本=1:9,将scale_pos_weight设置为9,scale_pos_weight=负样本个数/正样本个数。在各类别样本十分不平衡时,把这个参数设定为一个正值,可以使算法更快收敛。

1.3. 调参

  1. 先给定一个较高的学习率(learning rate),一般情况下,学习率为0.1,但是对于不同的问题,理想的学习率在0.05~0.3之间波动。先调节决策树的数量n_estimators
1
2
3
4
5
6
7
8
9
10
11
12
13
from IPython.display import display

cv_params = {'n_estimators': [20,40, 60, 80]}
other_params = {'learning_rate': 0.1, 'n_estimators': 500, 'max_depth': 5, 'min_child_weight': 1,
'seed': 0,'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0, 'reg_alpha': 0,
'reg_lambda': 1,'scale_pos_weight':1,'objective':'binary:logistic'}
model = XGBClassifier(**other_params)
optimized_GBM = GridSearchCV(estimator=model, param_grid=cv_params, scoring='accuracy', cv=5,verbose=1, n_jobs=4)
optimized_GBM.fit(X_train, y_train)

print('参数的最佳取值:{0}'.format(optimized_GBM.best_params_))
print('最佳模型得分:{0}'.format(optimized_GBM.best_score_))
display(pd.DataFrame(optimized_GBM.cv_results_).T)
  1. 在给定的learning rate和n_eatimators情况下,对决策树特定参数调优(max_depth,min_child_weight,gamma,subsample,colsample_bytree)
  2. max_depth和min_child_weight参数调优
1
2
3
4
cv_params = {'max_depth': list(range(3,10,2)), 'min_child_weight': list(range(1,7,1))}
other_params = {'learning_rate': 0.1, 'n_estimators': 60, 'max_depth': 5, 'min_child_weight': 1,
'seed': 0,'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0, 'reg_alpha': 0,
'reg_lambda': 1,'scale_pos_weight':1,'objective':'binary:logistic'}
  1. gamma参数调优
    Gamma参数取值范围可以很大,我这里把取值范围设置为5了。你其实也可以取更精确的gamma值

    1
    2
    3
    4
    cv_params = {'gamma': [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]}
    other_params = {'learning_rate': 0.1, 'n_estimators': 350, 'max_depth': 3, 'min_child_weight': 5,
    'seed': 0,'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0, 'reg_alpha': 0,
    'reg_lambda': 1,'objective':'binary:logistic'}
  2. subsamplehe colsample_bytree参数,相当于每个树的样本和特征个数。

    1
    2
    3
    4
     cv_params = {  
    'subsample': [i / 10.0 for i in range(6, 10)],
    'colsample_bytree': [i / 10.0 for i in range(6, 10)]
    }
  3. 正则化参数调优
    下一步应用正则化来降低过拟合。

    1
    cv_params = {'reg_alpha': [0.05, 0.1, 1, 2, 3], 'reg_lambda': [0.05, 0.1, 1, 2, 3]}
  4. 学习率调优
    最后使用较低的学习率

打赏
0%