由于Xgboost底层是C++实现的,所以需要先安装Microsoft Visual C++,安装 2015-2019任意一个版本就行;安装完毕后可以在控制面板查看安装结果:
然后命令行执行pip install xgboost
即可
使用Xgboost的原生库进行学习的流程大致如下:
下面按照图示流程讲解每一步的参数
原生库的数据必须封装在DMatrix中才能进行训练;Dmatrix是Xgboost自定义的一个数据矩阵类,用于封装数据,这种定义方式可以优化存储和运算速度,其参数如下:
data
:训练数据(注意Dmatrix要求数据类型只能是int、float、bool之一,所以数据中如果有字符串类型需提前进行编码)label
:训练数据的标签(注意Dmatrix要求数据类型只能是int、float、bool之一,所以数据中如果有字符串类型需提前进行编码)weight
:样本的权重base_margin
:样本偏置,是一个N*1的数组,N为样本数missing
:float型,输入数据中如果有缺失值则以该值替代,默认为np.nan
silent
:在计算过程中是否要输出信息,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
:是否要最大化feval
early_stopping_rounds
:控制训练速度;如果在验证数据集上迭代early_stopping_rounds
次后损失函数没有下降就停止训练;要求evals
参数不能为空verbose_eval
:控制评估模型过程中的输出数量,bool类型或int类型,默认为True,即每个提升阶段都输出相应信息;要求evals
参数非空xgb_model
:加载模型(传入文件路径)callbacks
:回调函数(列表),在每轮迭代结束后调用上一步train()
函数返回的是一个Booster类,我们可以调用这个类的predict()
方法进行预测,该函数常用的两个参数如下:
data
:测试集数据ntree_limit
:预测时使用的树的数量,默认为0(使用所有树)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))
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))
xgboost包已经封装了XGBRegressor,XGBClassifier,XGBRFRegressor,XGBRFClassifier等学习器,他们的调用方法和sklearn封装的学习器调用方法一样,下面分别介绍他们的参数
这个类用于解决回归问题
n_estimators
:提升树的数量,即训练轮数,等价于原生库的num_boost_round
max_depth
:树的最大深度learning_rate
:学习率,等价于原生库的eta
verbosity
:控制学习过程中输出信息的多少,取值为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.nan
importance_type
:计算特征重要性的依据,可选项有“gain”, “weight”, “cover”, “total_gain”, “total_cover”,默认为“gain”tree_method
:构建树采用的算法,可选值有:auto, exact, approx, hist, gpu_hist,默认为autoapply(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.XGBRegressor多了一个use_label_encoder
参数,表示是否用sklearn的LabelEncoder对类别做编码,默认为True,但官方文档建议将其设为False;另外这个类的objective
默认为binary:logistic
,除此之外其他参数、属性和方法与xgboost.XGBRegressor相同
这个类也是用于解决回归问题,不过在xgboost的基础上用随机森林算法做了集成,该类的学习率默认为1,subsample
默认为0.8,colsample_bynode
默认为0.8,reg_lambda
默认为0.00001,除此之外其他参数、属性和方法与xgboost.XGBRegressor相同
和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))
xgboost包除了以上功能强大的学习器外还封装了几个非常好用的绘图函数
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
:是否在图中显示具体数值,默认为Truebooster
:弱评估器或xgboost模型实例fmap
:特征图的文件路径num_trees
:指定要画第几棵树,默认为0(第一棵)ax
:matplotlib的Axes对象,默认为None,此时将创建一个新的图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))
输出:
参考:官方文档