【机器学习】Xgboost的使用及参数详解
Xgboost的原生库#mermaid-svg-2QkQMijIkIAMOWxw .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-2QkQMijIkIAMOWxw .label text{fill:#3
目录
Xgboost的安装
由于Xgboost底层是C++实现的,所以需要先安装Microsoft Visual C++,安装 2015-2019任意一个版本就行;安装完毕后可以在控制面板查看安装结果:
然后命令行执行pip install xgboost即可
Xgboost的使用
Xgboost的原生库
使用Xgboost的原生库进行学习的流程大致如下:
下面按照图示流程讲解每一步的参数
读取数据
原生库的数据必须封装在DMatrix中才能进行训练;Dmatrix是Xgboost自定义的一个数据矩阵类,用于封装数据,这种定义方式可以优化存储和运算速度,其参数如下:
data:训练数据(注意Dmatrix要求数据类型只能是int、float、bool之一,所以数据中如果有字符串类型需提前进行编码)label:训练数据的标签(注意Dmatrix要求数据类型只能是int、float、bool之一,所以数据中如果有字符串类型需提前进行编码)weight:样本的权重base_margin:样本偏置,是一个N*1的数组,N为样本数missing:float型,输入数据中如果有缺失值则以该值替代,默认为np.nansilent:在计算过程中是否要输出信息,True表示不输出,默认为Falsefeature_names:特征名称feature_types:特征类型nthread:加载数据时的线程数,-1代表使用所有可用线程
类方法有以下几个(还有一些不常用的参考文末官方文档):
feature_names():获取特征名feature_types():获取特征类型get_base_margin():获取样本的偏置get_label():获取标签get_weight():获取权重num_col():获取特征数num_row():获取样本数save_binary(fname, silent=True):储存Dmatrix,fname为存储路径,silent控制是否输出信息;储存的数据可以通过xbgoost.Dmatrix(fname)取出
设置参数
一般参数
booster:弱评估器,可以是gbtree,gblinear,dart,默认是gbtreedisable_default_eval_metric:是否禁用默认的(验证集的)评估指标,注意如果你要用自定义的评估指标,需要将这一项设为Truenthread:训练模型时用的并行线程数verbosity:控制训练过程中输出信息的多少,取值为0, 1, 2, 3,默认为1validate_parameters:是否检查参数
弱评估器参数
基于树的弱评估器(gbtree, dart)的参数主要有以下几个:
eta:学习率,默认为0.3gamma:叶节点继续分裂所需的最小损失函数下降值,默认为0,即不断增加树的深度直到损失函数不再下降max_depth:树的最大深度,默认为6min_child_weight:叶节点继续分裂所需的最小样本权重, 默认为1subsample:训练样本的采样率,默认为1,即每次都用所有样本做提升sampling_method:样本采样方法,默认为均匀采样colsample_bytree,colsample_bylevel,colsample_bynode:特征采样率,colsample_bytree决定构建每一棵树的时候的采样率,colsample_bylevel决定树的深度每增加一层时的采样率,colsample_bynode决定每次叶节点分裂时的采样率,这三个参数默认都为1;在训练模型时三个参数的作用是累积的,例如数据共128个特征,colsample_bytree=colsample_bylevel=colsample_bynode=0.5,那么每个叶节点分裂时用到的特征数就是16lambda:L2正则化系数,默认为1alpha:L1正则化系数,默认为0tree_method:构建树采用的算法,可选值有:auto,exact,approx,hist,gpu_hist,默认为auto
如果你选的弱评估器为dart,注意它在训练时会采用dropout方法,即随机丢掉一部分树以防止过拟合,因而此时会有如下额外的参数:
sample_type:树模型的采样算法,默认均匀采样normalize_type:树的权重的归一化算法,具体公式见文末官方文档rate_drop:删除率,默认是0one_drop:开启这个功能将保证每次dropout至少会删除一棵树,默认为0(关闭)skip_drop:在一次迭代中不做dropout的概率,该参数优先于rate_drop和one_drop,默认为0
线性弱评估器(gblinear)的参数如下:
lambda:L2正则化系数,默认为0alpha:L1正则化系数,默认为0updater:拟合线性模型的算法,默认为shotgun算法feature_selector:特征选择方法,默认依次选择特征(cyclic)
任务参数
objective:学习目标,默认为reg:squarederror,即以平方损失为损失函数的回归模型;除此之外还有:参数 对应的学习目标 reg:squaredlogerror以均方对数损失为损失函数的回归模型 reg:logistic逻辑回归模型 binary:logistic二分类逻辑回归模型(输出为概率,即Sigmoid函数值) binary:logitraw二分类逻辑回归模型(输出为 w T x w^Tx wTx,即Sigmoid函数的参数) binary:hinge使用合页损失函数(hinge loss)的二分类模型(输出为0或1) multi:softmax使用softmax作为目标函数的多分类模型 base_score:所有样本的初始偏置值,默认0.5eval_metric:验证数据集的评估指标,分类问题默认为对数损失函数,回归问题默认为均方根损失函数seed:随机数种子
训练模型
原生Xgboost库既可以用来处理分类问题,也可以用来处理回归问题,实现方法都是调用train()函数;该函数参数如下:
params:上一步定义的参数列表dtrain:第一步读取的训练数据num_boost_round:迭代次数evals:验证数据集,该参数必须是由(Dmatrix, string)构成的列表,第二个string参数是用于输出的,可以任意设置obj:自定义目标函数feval:自定义评估函数;该参数起作用需要evals非空,并且将一般参数中的disable_default_eval_metric设为Truemaximize:是否要最大化fevalearly_stopping_rounds:控制训练速度;如果在验证数据集上迭代early_stopping_rounds次后损失函数没有下降就停止训练;要求evals参数不能为空verbose_eval:控制评估模型过程中的输出数量,bool类型或int类型,默认为True,即每个提升阶段都输出相应信息;要求evals参数非空xgb_model:加载模型(传入文件路径)callbacks:回调函数(列表),在每轮迭代结束后调用
预测结果
上一步train()函数返回的是一个Booster类,我们可以调用这个类的predict()方法进行预测,该函数常用的两个参数如下:
data:测试集数据ntree_limit:预测时使用的树的数量,默认为0(使用所有树)
示例代码
示例1
from sklearn.datasets import load_boston, load_iris
from sklearn.metrics import mean_squared_error, accuracy_score
from sklearn.model_selection import train_test_split
import xgboost as xgb
## 使用原生xgboost解决回归问题
# 读取数据
boston_data = load_boston()
X = boston_data.data
y = boston_data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=23)
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)
# 设置参数
params = {
'eta': 0.1,
'reg_alpha': 0.01,
'reg_lambda': 0.01,
'max_depth': 10
}
# 训练模型
bst = xgb.train(
params=params,
dtrain=dtrain,
num_boost_round=20
)
# 预测结果
ypred = bst.predict(dtest)
print('MSE of prediction on boston dataset:', mean_squared_error(y_test, ypred))
print('\n')
## 使用原生xgboost解决分类问题
# 读取数据
iris_data = load_iris()
X = iris_data.data
y = iris_data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=23)
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)
# 设置参数
params = {
'objective': 'multi:softmax',
'num_class': 3,
'eta': 0.1,
'reg_alpha': 0.01,
'reg_lambda': 0.01,
'max_depth': 8
}
# 训练模型
bst = xgb.train(
params=params,
dtrain=dtrain,
num_boost_round=20,
evals=[(dtrain, 'train'), (dtest, 'test')] # 将训练数据和测试数据都作为验证集,可以实时监督训练情况,是否过拟合
)
# 预测结果
result = bst.predict(
dtest,
ntree_limit=10
)
print('Accuracy of prediction on iris dataset:', accuracy_score(y_test, result))
输出:
注意objective参数如果不设置的话其实不会影响学习效果,因为该模型会根据数据判断当前问题是分类问题还是回归问题,如下所示:
iris_data = load_iris()
X = iris_data.data
y = iris_data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=23)
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)
# 设置参数
params = {
# 'objective': 'multi:softmax',
'num_class': 3,
'eta': 0.1,
'reg_alpha': 0.01,
'reg_lambda': 0.01,
'max_depth': 8
}
# 训练模型
bst = xgb.train(
params=params,
dtrain=dtrain,
num_boost_round=20,
evals=[(dtrain, 'train'), (dtest, 'test')]
)
# 预测结果
result = bst.predict(
dtest,
ntree_limit=10
)
print('Accuracy of prediction on iris dataset(objective unspecified):', accuracy_score(y_test, result))
输出:
与第一段代码运行结果对比可以发现是一样的
示例2
from sklearn.datasets import load_wine
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
import xgboost as xgb
import matplotlib.pyplot as plt
# 读取数据
wine_data = load_wine()
X = wine_data.data
y = wine_data.target
features = wine_data.feature_names
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=23)
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)
# 设置参数
params = {
'num_class': 3,
'eta': 0.1,
'reg_alpha': 0.01,
'reg_lambda': 0.01,
'max_depth': 8
}
# 训练模型
bst = xgb.train(
params=params,
dtrain=dtrain,
num_boost_round=10,
evals=[(dtrain, 'train'), (dtest, 'dtest')]
)
feature_score = bst.get_score(importance_type='gain') # 特征得分(特征重要性)
print(feature_score)
feature_importance = {}
for tag, score in feature_score.items():
feature_importance[features[int(tag[1:])]] = score
plt.figure(figsize=(12, 8))
plt.bar(range(len(feature_importance)), feature_importance.values())
plt.xticks(range(len(feature_importance)), feature_importance.keys(), rotation=45)
plt.ylabel('Importance')
plt.show()
# 预测结果
result = bst.predict(
dtest,
ntree_limit=10
)
print('Accuracy of prediction on wine dataset:', accuracy_score(y_test, result))
输出:


基于sklearnAPI的Xgboost
xgboost包已经封装了XGBRegressor,XGBClassifier,XGBRFRegressor,XGBRFClassifier等学习器,他们的调用方法和sklearn封装的学习器调用方法一样,下面分别介绍他们的参数
xgboost.XGBRegressor
这个类用于解决回归问题
参数
n_estimators:提升树的数量,即训练轮数,等价于原生库的num_boost_roundmax_depth:树的最大深度learning_rate:学习率,等价于原生库的etaverbosity:控制学习过程中输出信息的多少,取值为0, 1, 2, 3objective:学习目标及其损失函数,默认为reg:squarederror,即以平方损失为损失函数的回归模型booster:弱评估器,可以是gbtree,gblinear或dartn_jobs:训练时并行的线程数gamma:叶节点继续分裂所需的最小损失函数下降值min_child_weight:一个叶子节点上所需要的最小样本权重max_delta_step:树的权重估计中允许的单次最大增量subsample:对训练样本的采样比例colsample_bytree,colsample_bylevel,colsample_bynode:参考上文原生库的弱评估器参数reg_alpha:L1正则化系数reg_lambda:L2正则化系数base_score:所有样本的偏置random_state:随机数种子missing:缺失值的表达形式,默认为np.nanimportance_type:计算特征重要性的依据,可选项有“gain”, “weight”, “cover”, “total_gain”, “total_cover”,默认为“gain”tree_method:构建树采用的算法,可选值有:auto, exact, approx, hist, gpu_hist,默认为auto
属性和方法
apply(X, ntree_limit=0):X为测试数据,维度为[n_samples, n_features];ntree_limit预测时使用的树的数量,默认为0(使用所有树);返回维度为[n_samples, n_trees]的数组,第i行第j列表示第i个数据在第j个树中的叶节点的下标evals_result():返回验证集上的评估结果feature_importances_:返回特征重要性fit():用给定数据训练模型,其参数如下:参数 含义 X训练数据集x值 y训练数据集y值 sample_weight样本权重 base_margin样本偏置 eval_set验证数据集(以 ( X , y ) (X, y) (X,y)组成的列表) eval_metric评估指标 early_stopping_rounds见上文原生库参数 verbose控制训练过程中输出信息的多少 xgb_model要预加载的模型(字符串类型,即文件路径) sample_weight_eval_set验证集样本权重 callbacks回调函数 get_booster():返回模型的弱评估器(只能在fit()之后调用)get_params():返回模型参数predict():预测,参数如下:参数 含义 data测试集 ntree_limit预测时使用的树的数量 validate_features默认为True,将会检查测试数据和弱评估器的特征是否一致 output_margin是否返回原始分数(对分类问题原始分数就是 w T x w^Tx wTx,对回归问题原始分数与预测结果一样),默认为False save_model(fname):保存模型,fname为字符串类型,表示文件路径load_model(fname):加载模型,fname为字符串类型,表示文件路径
xgboost.XGBClassifier
这个类用于解决分类问题,相比xgboost.XGBRegressor多了一个use_label_encoder参数,表示是否用sklearn的LabelEncoder对类别做编码,默认为True,但官方文档建议将其设为False;另外这个类的objective默认为binary:logistic,除此之外其他参数、属性和方法与xgboost.XGBRegressor相同
xgboost.XGBRFRegressor
这个类也是用于解决回归问题,不过在xgboost的基础上用随机森林算法做了集成,该类的学习率默认为1,subsample默认为0.8,colsample_bynode默认为0.8,reg_lambda默认为0.00001,除此之外其他参数、属性和方法与xgboost.XGBRegressor相同
xgboost.XGBRFClassifier
和xgboost.XGBRFRegressor类似,该模型在xgboost的基础上用随机森林算法做了集成,它也有use_label_encoder参数,默认为True,官方文档建议将其设为False;该类的学习率默认为1,subsample默认为0.8,colsample_bynode默认为0.8,reg_lambda默认为0.00001,除此之外其他参数、属性和方法与xgboost.XGBRegressor相同
示例代码
from sklearn.datasets import load_boston, load_iris
from sklearn.metrics import mean_squared_error, accuracy_score
from sklearn.model_selection import train_test_split
from xgboost import XGBRegressor, XGBClassifier
# 使用skleanAPI xgboost解决回归问题
boston_data = load_boston()
X = boston_data.data
y = boston_data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=23)
reg = XGBRegressor(
n_estimators=20,
learning_rate=0.1,
max_depth=5)
reg.fit(X_train, y_train)
ypred = reg.predict(X_test)
print('MSE of prediction on boston dataset:', mean_squared_error(y_test, ypred))
print('\n')
# 使用sklearnAPI xgboost解决分类问题
iris_data = load_iris()
X = iris_data.data
y = iris_data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=23)
xgbc = XGBClassifier(
learning_rate=0.1,
n_estimators=20,
seed=27,
verbosity=1
)
xgbc.fit(X_train, y_train)
result = xgbc.predict(X_test)
print('Accuracy of prediction on iris dataset:', accuracy_score(y_test, result))
输出:
Plotting API
xgboost包除了以上功能强大的学习器外还封装了几个非常好用的绘图函数
xgboost.plot_importance
参数
booster:弱评估器或xgboost模型实例ax:matplotlib的Axes对象,默认为None,此时将创建一个新的图grid:是否加上网格,默认为Trueimportance_type:特征重要性的计算方法,默认为"weight",即特征在树中出现的次数;其余可选项为“gain”和“cover”max_num_features:图中显示的最大特征数,如果是None则显示所有特征(默认)height:条形图的高度,默认0.2xlim:元组类型,表示x的取值范围,默认为Noneylim:元组类型,表示x的取值范围,默认为Nonetitle:图的名称,默认为"Feature importance"xlabel:x轴名称,默认为"F score"ylabel:y轴名称,默认为"Features"show_values:是否在图中显示具体数值,默认为True
xgboost.plot_tree
参数
booster:弱评估器或xgboost模型实例fmap:特征图的文件路径num_trees:指定要画第几棵树,默认为0(第一棵)ax:matplotlib的Axes对象,默认为None,此时将创建一个新的图
xgboost.to_graphviz
参数
booster:弱评估器或xgboost模型实例fmap:特征图的文件路径num_trees:指定要画第几棵树,默认为0(第一棵)yes_color:满足节点条件的边的颜色,默认为’#0000FF’no_color:不满足节点条件的边的颜色,默认为’#FF0000’condition_node_params:非叶节点的参数,字典类型leaf_node_params:叶节点的参数,字典类型
示例代码
from sklearn.datasets import load_breast_cancer
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
import xgboost as xgb
import matplotlib.pyplot as plt
cancer_data = load_breast_cancer()
X = cancer_data.data
y = cancer_data.target
features = cancer_data.feature_names
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=23)
xgbc = xgb.XGBRegressor(
learning_rate=0.1,
n_estimators=20,
seed=27,
verbosity=1
)
xgbc.fit(
X_train,
y_train,
eval_set=[(X_train, y_train), (X_test, y_test)]
)
fea_imp = xgbc.feature_importances_
print(fea_imp)
输出:
接上文代码
# 由于并不是所有特征都能用上,所以这里统计一下用到的特征
used_features = []
for ind in range(len(features)):
if fea_imp[ind]:
used_features.append(features[ind])
fig = plt.figure(figsize=(10, 8))
ax = fig.add_axes([0,0,1,1])
xgb.plot_importance(xgbc, ax)
ax.set_yticklabels(used_features)
输出:
接上文代码
node_params = {
'shape': 'box',
'style': 'filled,rounded',
'fillcolor': '#78bceb'
}
xgb.to_graphviz(xgbc, condition_node_params = node_params)
输出:
接上文代码
result = xgbc.predict(
X_test,
ntree_limit=10
)
# 预测结果是概率值,为了用accuracy_score计算准确率需要转换为类别
result = list(map(lambda x: 1 if x>0.5 else 0, result))
print('Accuracy of prediction on cancer dataset:', accuracy_score(y_test, result))
输出:
参考:官方文档
更多推荐



所有评论(0)