其他分享
首页 > 其他分享> > 我的XGBoost学习经历及动手实践

我的XGBoost学习经历及动手实践

作者:互联网

图片

知乎地址:http://www.zhihu.com/people/meng-di-76-92

我今天主要介绍机器学习集成学习方法中三巨头之一的XGBoost,这个算法在早些时候机器学习比赛内曾经大放异彩,是非常好用的一个机器学习集成算法。

XGBoost是一个优化的分布式梯度增强库,旨在实现高效,灵活和便携。它在Gradient Boosting框架下实现机器学习算法。XGBoost提供了并行树提升(也称为GBDT,GBM),可以快速准确地解决许多数据科学问题。

相同的代码在主要的分布式环境(Hadoop,SGE,MPI)上运行,并且可以解决超过数十亿个样例的问题。XGBoost利用了核外计算并且能够使数据科学家在一个主机上处理数亿的样本数据。最终,将这些技术进行结合来做一个端到端的系统以最少的集群系统来扩展到更大的数据集上。

XGBoost原理介绍

从0开始学习,经历过推导公式的波澜曲折,下面展示下我自己的推公式的手稿吧,希望能激励到大家能够对机器学习数据挖掘更加热爱!

图片XGBoost公式1图片

XGBoost公式2

现在我们对手稿的内容进行详细的讲解:

1. 优化目标: image.png


由于前t-1棵树已知,那么

 image.png


我们找到了目标函数就需要对目标函数进行优化:


image.png


3. 生成树的策略:我们刚刚的假设前提是已知前t-1棵树,因此我们现在来探讨怎么生成树。根据决策树的生成策略,再每次分裂节点的时候我们需要考虑能使得损失函数减小最快的节点,也就是分裂后损失函数减去分裂前损失函数我们称之为Gain:

图片

Gain越大越能说明分裂后目标函数值减小越多。(因为从式子来看: image.png 越大,反而OBj越小)


4. 寻找最优节点

在决策树(CART)里面,我们使用的是精确贪心算法(Basic Exact Greedy Algorithm),也就是将所有特征的所有取值排序(耗时耗内存巨大),然后比较每一个点的Gini,找出变化最大的节点。当特征是连续特征时,我们对连续值离散化,取两点的平均值为分割节点。可以看到,这里的排序算法需要花费大量的时间,因为要遍历整个样本所有特征,而且还要排序!!

图片论文的精确贪心算法的伪代码

因此在XGBoost里面我们使用的是近似算法(Approximate Algorithm):该算法首先根据特征分布的百分位数(percentiles)提出候选分裂点,将连续特征映射到由这些候选点分割的桶中,汇总统计信息并根据汇总的信息在提案中找到最佳解决方案。对于某个特征k,算法首先根据特征分布的分位数找到特征切割点的候选集合 image.png ,然后将特征k的值根据集合 image.png 划分到桶(bucket)中,接着对每个桶内的样本统计值G、H进行累加,最后在这些累计的统计量上寻找最佳分裂点。


图片论文的近似算法的伪代码

XGBoost动手实践:

1. 引入基本工具库:

# 引入基本工具库import numpy as npimport pandas as pdimport xgboost as xgbimport matplotlib.pyplot as pltplt.style.use("ggplot")%matplotlib inline


2. XGBoost原生工具库的上手:

import xgboost as xgb  # 引入工具库# read in datadtrain = xgb.DMatrix('demo/data/agaricus.txt.train')   # XGBoost的专属数据格式,但是也可以用dataframe或者ndarraydtest = xgb.DMatrix('demo/data/agaricus.txt.test')  # # XGBoost的专属数据格式,但是也可以用dataframe或者ndarray# specify parameters via mapparam = {'max_depth':2, 'eta':1, 'objective':'binary:logistic' }    # 设置XGB的参数,使用字典形式传入num_round = 2     # 使用线程数bst = xgb.train(param, dtrain, num_round)   # 训练# make predictionpreds = bst.predict(dtest)   # 预测

3. XGBoost的参数设置(括号内的名称为sklearn接口对应的参数名字)

XGBoost的参数分为三种:

1. 通用参数 

通用参数有两种类型的booster,因为tree的性能比线性回归好得多,因此我们很少用线性回归。

2. 任务参数

这个参数用来控制理想的优化目标和每一步结果的度量方法。

3. 命令行参数 

这里不说了,因为很少用命令行控制台版本


4. XGBoost的调参说明:

参数调优的一般步骤:

5. XGBoost详细攻略:

1). 安装XGBoost

方式1:pip3 install xgboost方式2:pip install xgboost

2). 数据接口(XGBoost可处理的数据格式DMatrix)

# 1.LibSVM文本格式文件dtrain = xgb.DMatrix('train.svm.txt')dtest = xgb.DMatrix('test.svm.buffer')# 2.CSV文件(不能含类别文本变量,如果存在文本变量请做特征处理如one-hot)dtrain = xgb.DMatrix('train.csv?format=csv&label_column=0')dtest = xgb.DMatrix('test.csv?format=csv&label_column=0')# 3.NumPy数组data = np.random.rand(5, 10)  # 5 entities, each contains 10 featureslabel = np.random.randint(2, size=5)  # binary targetdtrain = xgb.DMatrix(data, label=label)# 4.scipy.sparse数组csr = scipy.sparse.csr_matrix((dat, (row, col)))dtrain = xgb.DMatrix(csr)# pandas数据框dataframedata = pandas.DataFrame(np.arange(12).reshape((4,3)), columns=['a', 'b', 'c'])label = pandas.DataFrame(np.random.randint(2, size=4))dtrain = xgb.DMatrix(data, label=label)

笔者推荐:先保存到XGBoost二进制文件中将使加载速度更快,然后再加载进来

# 1.保存DMatrix到XGBoost二进制文件中dtrain = xgb.DMatrix('train.svm.txt')dtrain.save_binary('train.buffer')# 2. 缺少的值可以用DMatrix构造函数中的默认值替换:dtrain = xgb.DMatrix(data, label=label, missing=-999.0)# 3.可以在需要时设置权重:w = np.random.rand(5, 1)dtrain = xgb.DMatrix(data, label=label, missing=-999.0, weight=w)

3). 参数的设置方式:

# 加载并处理数据df_wine = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data',header=None)df_wine.columns = ['Class label', 'Alcohol','Malic acid', 'Ash','Alcalinity of ash','Magnesium', 'Total phenols',                   'Flavanoids', 'Nonflavanoid phenols','Proanthocyanins','Color intensity', 'Hue','OD280/OD315 of diluted wines','Proline']df_wine = df_wine[df_wine['Class label'] != 1]  # drop 1 classy = df_wine['Class label'].valuesX = df_wine[['Alcohol','OD280/OD315 of diluted wines']].valuesfrom sklearn.model_selection import train_test_split  # 切分训练集与测试集from sklearn.preprocessing import LabelEncoder   # 标签化分类变量le = LabelEncoder()y = le.fit_transform(y)X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=1,stratify=y)dtrain = xgb.DMatrix(X_train, label=y_train)dtest = xgb.DMatrix(X_test)# 1.Booster 参数params = {    'booster': 'gbtree',    'objective': 'multi:softmax',  # 多分类的问题    'num_class': 10,               # 类别数,与 multisoftmax 并用    'gamma': 0.1,                  # 用于控制是否后剪枝的参数,越大越保守,一般0.1、0.2这样子。    'max_depth': 12,               # 构建树的深度,越大越容易过拟合    'lambda': 2,                   # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。    'subsample': 0.7,              # 随机采样训练样本    'colsample_bytree': 0.7,       # 生成树时进行的列采样    'min_child_weight': 3,    'silent': 1,                   # 设置成1则没有运行信息输出,最好是设置为0.    'eta': 0.007,                  # 如同学习率    'seed': 1000,    'nthread': 4,                  # cpu 线程数    'eval_metric':'auc'}plst = params.items()# evallist = [(dtest, 'eval'), (dtrain, 'train')]   # 指定验证集

4). 训练

# 2.训练num_round = 10bst = xgb.train( plst, dtrain, num_round)#bst = xgb.train( plst, dtrain, num_round, evallist )

5). 保存模型

# 3.保存模型bst.save_model('0001.model')# dump modelbst.dump_model('dump.raw.txt')# dump model with feature map#bst.dump_model('dump.raw.txt', 'featmap.txt')

6) . 加载保存的模型

# 4.加载保存的模型:bst = xgb.Booster({'nthread': 4})  # init modelbst.load_model('0001.model')  # load data

7). 设置早停机制

# 5.也可以设置早停机制(需要设置验证集)train(..., evals=evals, early_stopping_rounds=10)

8). 预测

# 6.预测ypred = bst.predict(dtest)

9). 绘图

# 1.绘制重要性xgb.plot_importance(bst)# 2.绘制输出树#xgb.plot_tree(bst, num_trees=2)# 3.使用xgboost.to_graphviz()将目标树转换为graphviz#xgb.to_graphviz(bst, num_trees=2)

6. 实战案例:

1). 分类案例

from sklearn.datasets import load_irisimport xgboost as xgbfrom xgboost import plot_importancefrom matplotlib import pyplot as pltfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_score   # 准确率# 加载样本数据集iris = load_iris()X,y = iris.data,iris.targetX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234565) # 数据集分割
# 算法参数params = {    'booster': 'gbtree',    'objective': 'multi:softmax',    'num_class': 3,    'gamma': 0.1,    'max_depth': 6,    'lambda': 2,    'subsample': 0.7,    'colsample_bytree': 0.75,    'min_child_weight': 3,    'silent': 0,    'eta': 0.1,    'seed': 1,    'nthread': 4,}
plst = params.items()
dtrain = xgb.DMatrix(X_train, y_train) # 生成数据集格式num_rounds = 500model = xgb.train(plst, dtrain, num_rounds) # xgboost模型训练
# 对测试集进行预测dtest = xgb.DMatrix(X_test)y_pred = model.predict(dtest)
# 计算准确率accuracy = accuracy_score(y_test,y_pred)print("accuarcy: %.2f%%" % (accuracy*100.0))
# 显示重要特征plot_importance(model)plt.show()

2). 回归案例

import xgboost as xgbfrom xgboost import plot_importancefrom matplotlib import pyplot as pltfrom sklearn.model_selection import train_test_splitfrom sklearn.datasets import load_bostonfrom sklearn.metrics import mean_squared_error
# 加载数据集boston = load_boston()X,y = boston.data,boston.target
# XGBoost训练过程X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
params = {    'booster': 'gbtree',    'objective': 'reg:squarederror',    'gamma': 0.1,    'max_depth': 5,    'lambda': 3,    'subsample': 0.7,    'colsample_bytree': 0.7,    'min_child_weight': 3,    'silent': 1,    'eta': 0.1,    'seed': 1000,    'nthread': 4,}
dtrain = xgb.DMatrix(X_train, y_train)num_rounds = 300plst = params.items()model = xgb.train(plst, dtrain, num_rounds)
# 对测试集进行预测dtest = xgb.DMatrix(X_test)ans = model.predict(dtest)
# 显示重要特征plot_importance(model)plt.show()


7. XGBoost调参(结合sklearn网格搜索)

import xgboost as xgbimport pandas as pdfrom sklearn.model_selection import train_test_splitfrom sklearn.model_selection import GridSearchCVfrom sklearn.metrics import roc_auc_score
iris = load_iris()X,y = iris.data,iris.targetcol = iris.target_namestrain_x, valid_x, train_y, valid_y = train_test_split(X, y, test_size=0.3, random_state=1)   # 分训练集和验证集parameters = {              'max_depth': [5, 10, 15, 20, 25],              'learning_rate': [0.01, 0.02, 0.05, 0.1, 0.15],              'n_estimators': [500, 1000, 2000, 3000, 5000],              'min_child_weight': [0, 2, 5, 10, 20],              'max_delta_step': [0, 0.2, 0.6, 1, 2],              'subsample': [0.6, 0.7, 0.8, 0.85, 0.95],              'colsample_bytree': [0.5, 0.6, 0.7, 0.8, 0.9],              'reg_alpha': [0, 0.25, 0.5, 0.75, 1],              'reg_lambda': [0.2, 0.4, 0.6, 0.8, 1],              'scale_pos_weight': [0.2, 0.4, 0.6, 0.8, 1]
}
xlf = xgb.XGBClassifier(max_depth=10,            learning_rate=0.01,            n_estimators=2000,            silent=True,            objective='multi:softmax',            num_class=3 ,            nthread=-1,            gamma=0,            min_child_weight=1,            max_delta_step=0,            subsample=0.85,            colsample_bytree=0.7,            colsample_bylevel=1,            reg_alpha=0,            reg_lambda=1,            scale_pos_weight=1,            seed=0,            missing=None)
gs = GridSearchCV(xlf, param_grid=parameters, scoring='accuracy', cv=3)gs.fit(train_x, train_y)
print("Best score: %0.3f" % gs.best_score_)print("Best parameters set: %s" % gs.best_params_ )
本文电子版 后台回复 XGBoost 获取

图片


标签:XGBoost,xgb,实践,DMatrix,动手,train,test,import
来源: https://blog.51cto.com/15127527/2688437