python平台下实现xgboost算法及输出的解释

1. 问题描述

​ 近来, 在python环境下使用xgboost算法作若干的机器学习任务, 在这个过程中也使用了其内置的函数来可视化树的结果, 但对leaf value的值一知半解; 同时, 也遇到过使用xgboost 内置的predict 对测试集进行打分预测, 发现若干样本集的输出分值是一样的. 这个问题该怎么解释呢? 通过翻阅Stack Overflow 上的相关问题, 以及搜索到的github上的issue回答, 应该算初步对这个问题有了一定的理解, 特来分享!

2. 数据集

​ 在这里, 使用经典的鸢尾花的数据来说明. 使用二分类的问题来说明, 故在这里只取前100行的数据.

from sklearn import datasets

iris = datasets.load_iris()
data = iris.data[:100]
print data.shape
#(100L, 4L)
#一共有100个样本数据, 维度为4维 label = iris.target[:100]
print label
#正好选取label为0和1的数据
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]

3. 训练集与测试集

from sklearn.cross_validation import train_test_split

train_x, test_x, train_y, test_y = train_test_split(data, label, random_state=0)

4. Xgboost建模

4.1 模型初始化设置

import xgboost as xgb
dtrain=xgb.DMatrix(train_x,label=train_y)
dtest=xgb.DMatrix(test_x) params={'booster':'gbtree',
'objective': 'binary:logistic',
'eval_metric': 'auc',
'max_depth':4,
'lambda':10,
'subsample':0.75,
'colsample_bytree':0.75,
'min_child_weight':2,
'eta': 0.025,
'seed':0,
'nthread':8,
'silent':1} watchlist = [(dtrain,'train')]

4.2 建模与预测

bst=xgb.train(params,dtrain,num_boost_round=100,evals=watchlist)

ypred=bst.predict(dtest)

# 设置阈值, 输出一些评价指标
y_pred = (ypred >= 0.5)*1 from sklearn import metrics
print 'AUC: %.4f' % metrics.roc_auc_score(test_y,ypred)
print 'ACC: %.4f' % metrics.accuracy_score(test_y,y_pred)
print 'Recall: %.4f' % metrics.recall_score(test_y,y_pred)
print 'F1-score: %.4f' %metrics.f1_score(test_y,y_pred)
print 'Precesion: %.4f' %metrics.precision_score(test_y,y_pred)
metrics.confusion_matrix(test_y,y_pred)

Out[23]:

AUC: 1.0000
ACC: 1.0000
Recall: 1.0000
F1-score: 1.0000
Precesion: 1.0000
array([[13, 0],
[ 0, 12]], dtype=int64)

Yeah, 完美的模型, 完美的预测!

4.3 可视化输出

#对于预测的输出有三种方式
?bst.predict
Signature: bst.predict(data, output_margin=False, ntree_limit=0, pred_leaf=False, pred_contribs=False, approx_contribs=False) pred_leaf : bool
When this option is on, the output will be a matrix of (nsample, ntrees)
with each record indicating the predicted leaf index of each sample in each tree.
Note that the leaf index of a tree is unique per tree, so you may find leaf 1
in both tree 1 and tree 0. pred_contribs : bool
When this option is on, the output will be a matrix of (nsample, nfeats+1)
with each record indicating the feature contributions (SHAP values) for that
prediction. The sum of all feature contributions is equal to the prediction.
Note that the bias is added as the final column, on top of the regular features.

4.3.1 得分

默认的输出就是得分, 这没什么好说的, 直接上code.

ypred = bst.predict(dtest)
ypred

Out[32]:

array([ 0.20081411,  0.80391562,  0.20081411,  0.80391562,  0.80391562,
0.80391562, 0.20081411, 0.80391562, 0.80391562, 0.80391562,
0.80391562, 0.80391562, 0.80391562, 0.20081411, 0.20081411,
0.20081411, 0.20081411, 0.20081411, 0.20081411, 0.20081411,
0.20081411, 0.80391562, 0.20081411, 0.80391562, 0.20081411], dtype=float32)

在这里, 就可以观察到文章最开始遇到的问题: 为什么得分几乎都是一样的值? 先不急, 看看另外两种输出.

4.3.2 所属的叶子节点

当设置pred_leaf=True的时候, 这时就会输出每个样本在所有树中的叶子节点

ypred_leaf = bst.predict(dtest, pred_leaf=True)
ypred_leaf

Out[33]:

array([[1, 1, 1, ..., 1, 1, 1],
[2, 2, 2, ..., 2, 2, 2],
[1, 1, 1, ..., 1, 1, 1],
...,
[1, 1, 1, ..., 1, 1, 1],
[2, 2, 2, ..., 2, 2, 2],
[1, 1, 1, ..., 1, 1, 1]])

输出的维度为[样本数, 树的数量], 树的数量默认是100, 所以ypred_leaf的维度为[100*100].

对于第一行数据的解释就是, 在xgboost所有的100棵树里, 预测的叶子节点都是1(相对于每颗树).

那怎么看每颗树以及相应的叶子节点的分值呢?这里有两种方法, 可视化树或者直接输出模型.

xgb.to_graphviz(bst, num_trees=0)
#可视化第一棵树的生成情况

#直接输出模型的迭代工程
bst.dump_model("model.txt")
booster[0]:
0:[f3<0.75] yes=1,no=2,missing=1
1:leaf=-0.019697
2:leaf=0.0214286
booster[1]:
0:[f2<2.35] yes=1,no=2,missing=1
1:leaf=-0.0212184
2:leaf=0.0212
booster[2]:
0:[f2<2.35] yes=1,no=2,missing=1
1:leaf=-0.0197404
2:leaf=0.0197235
booster[3]: ……

通过上述命令就可以输出模型的迭代过程, 可以看到每颗树都有两个叶子节点(树比较简单). 然后我们对每颗树中的叶子节点1的value进行累加求和, 同时进行相应的函数转换, 就是第一个样本的预测值.

在这里, 以第一个样本为例, 可以看到, 该样本在所有树中都属于第一个叶子, 所以累加值, 得到以下值.

同样, 以第二个样本为例, 可以看到, 该样本在所有树中都属于第二个叶子, 所以累加值, 得到以下值.

leaf1   -1.381214
leaf2 1.410950

在使用xgboost模型最开始, 模型初始化的时候, 我们就设置了'objective': 'binary:logistic', 因此使用函数将累加的值转换为实际的打分:

$$f(x) = 1/(1+exp(-x))$$

1/float(1+np.exp(1.38121416))
Out[24]: 0.20081407112186503
1/float(1+np.exp(-1.410950))
Out[25]: 0.8039157403338895

这就与ypred = bst.predict(dtest) 的分值相对应上了.

4.3.2 特征重要性

接着, 我们看另一种输出方式, 输出的是特征相对于得分的重要性.

ypred_contribs = bst.predict(dtest, pred_contribs=True)
ypred_contribs

Out[37]:

array([[ 0.        ,  0.        , -1.01448286, -0.41277751,  0.04604663],
[ 0. , 0. , 0.96967536, 0.39522746, 0.04604663],
[ 0. , 0. , -1.01448286, -0.41277751, 0.04604663],
[ 0. , 0. , 0.96967536, 0.39522746, 0.04604663],
[ 0. , 0. , 0.96967536, 0.39522746, 0.04604663],
[ 0. , 0. , 0.96967536, 0.39522746, 0.04604663],
[ 0. , 0. , -1.01448286, -0.41277751, 0.04604663],
[ 0. , 0. , 0.96967536, 0.39522746, 0.04604663],
[ 0. , 0. , 0.96967536, 0.39522746, 0.04604663],
[ 0. , 0. , 0.96967536, 0.39522746, 0.04604663],
[ 0. , 0. , 0.96967536, 0.39522746, 0.04604663],
[ 0. , 0. , 0.96967536, 0.39522746, 0.04604663],
[ 0. , 0. , 0.96967536, 0.39522746, 0.04604663],
[ 0. , 0. , -1.01448286, -0.41277751, 0.04604663],
[ 0. , 0. , -1.01448286, -0.41277751, 0.04604663],
[ 0. , 0. , -1.01448286, -0.41277751, 0.04604663],
[ 0. , 0. , -1.01448286, -0.41277751, 0.04604663],
[ 0. , 0. , -1.01448286, -0.41277751, 0.04604663],
[ 0. , 0. , -1.01448286, -0.41277751, 0.04604663],
[ 0. , 0. , -1.01448286, -0.41277751, 0.04604663],
[ 0. , 0. , -1.01448286, -0.41277751, 0.04604663],
[ 0. , 0. , 0.96967536, 0.39522746, 0.04604663],
[ 0. , 0. , -1.01448286, -0.41277751, 0.04604663],
[ 0. , 0. , 0.96967536, 0.39522746, 0.04604663],
[ 0. , 0. , -1.01448286, -0.41277751, 0.04604663]], dtype=float32)

输出的ypred_contribs的维度为[100,5], 通过阅读前面的文档注释就可以知道, 最后一列是bias, 前面的四列分别是每个特征对最后打分的影响因子, 可以看出, 前面两个特征是不起作用的.

通过这个输出, 怎么和最后的打分进行关联呢? 原理也是一样的, 还是以前两列为例.

score_a = sum(ypred_contribs[0])
print score_a
# -1.38121373579
score_b = sum(ypred_contribs[1])
print score_b
# 1.41094945744

相同的分值, 相同的处理情况.

到此, 这期关于在python上关于xgboost算法的简单实现, 以及在实现的过程中: 得分的输出、样本对应到树的节点、每个样本中单独特征对得分的影响, 以及上述三者之间的联系, 均已介绍完毕, 知识积累完毕:happy:!

python平台下实现xgboost算法及输出的解释的更多相关文章

  1. 在Window平台下安装xgboost的Python版本

    原文:http://blog.csdn.net/pengyulong/article/details/50515916 原文修改了两个地方才安装成功,第3步可以不用,第2步重新生成所有的就行了. 第4 ...

  2. Python机器学习笔记:XgBoost算法

    前言 1,Xgboost简介 Xgboost是Boosting算法的其中一种,Boosting算法的思想是将许多弱分类器集成在一起,形成一个强分类器.因为Xgboost是一种提升树模型,所以它是将许多 ...

  3. Java平台调用Python平台已有算法(附源码及解析)

    1. 问题描述 Java平台要调用Pyhon平台已有的算法,为了减少耦合度,采用Pyhon平台提供Restful 接口,Java平台负责来调用,采用Http+Json格式交互. 2. 解决方案 2.1 ...

  4. (转载)Linux平台下安装 python 模块包

    https://blog.csdn.net/aiwangtingyun/article/details/79121145 一.安装Python Windows平台下: 进入Python官网下载页面下载 ...

  5. caffe学习(1):多平台下安装配置caffe

    如何在 centos 7.3 上安装 caffe 深度学习工具   有好多朋友在安装 caffe 时遇到不少问题.(看文章的朋友希望关心一下我的创业项目趣智思成) 今天测试并整理一下安装过程.我是在阿 ...

  6. .NET平台下开源框架

    一.AOP框架Encase 是C#编写开发的为.NET平台提供的AOP框架.Encase 独特的提供了把方面(aspects)部署到运行时代码,而其它AOP框架依赖配置文件的方式.这种部署方面(asp ...

  7. Python之路,Day21 - 常用算法学习

    Python之路,Day21 - 常用算法学习   本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的 ...

  8. 在windows64位Anaconda3环境下安装XGBoost

    安装步骤参考的是: "Installing XGBoost For Anaconda on Windows":https://www.ibm.com/developerworks/ ...

  9. 机器学习总结(一) Adaboost,GBDT和XGboost算法

    一: 提升方法概述 提升方法是一种常用的统计学习方法,其实就是将多个弱学习器提升(boost)为一个强学习器的算法.其工作机制是通过一个弱学习算法,从初始训练集中训练出一个弱学习器,再根据弱学习器的表 ...

随机推荐

  1. 组件注册-自定义TypeFilter指定过滤规则

    组件注册-自定义TypeFilter指定过滤规则 4.1 FilterType.ANNOTATION 按照注解方式 4.2 FilterType.ASSIGNABLE_TYPE 按照给定的类型 @Co ...

  2. 初识xls文件的读写

    # 开发人员 : llm#时间ccc:import xlrdimport xlwt def read_xls(): info = xlrd.open_workbook('pytest.xls') pr ...

  3. <Dynamic Programming> 120 279

    120. Triangle 从倒数第二行找,然后逐个遍历这个DP数组,对于每个数字,和它之后的元素比较选择较小的再加上面一行相邻位置的元素做为新的元素,然后一层一层的向上扫描 class Soluti ...

  4. Salesforce - 建立轮循机制的潜在客户分配规则

    客服中心经常会遇到由多个客服轮流分配接进来的订单,例如你有100个订单进入系统,你希望五个客服每人分配20个,也就是一种小组的轮换机制,常被称为“轮询” 这种循环分配规需要保证平均分配给客服新的订单记 ...

  5. loj 2135 「ZJOI2015」幻想乡战略游戏 - 动态点分治

    题目传送门 传送门 题目大意 给定一棵树,初始点权都为0,要求支持: 修改点权 询问带权重心 询问带权重心就在点分树上跑一下就行了.(枚举跳哪个子树更优) 剩下都是基础点分治. 学了一下11-dime ...

  6. Visual Studio 2019(VS2019)正式版注册码秘钥

    Visual Studio 2019 EnterpriseBF8Y8-GN2QH-T84XB-QVY3B-RC4DF Visual Studio 2019 ProfessionalNYWVH-HT4X ...

  7. BCompare注册文件+密钥被撤销解决方案

    注册码: rssAPVg2OpBjDVo3E0DhGWrjPIq0hsTSuNz13wTuzVHfb2mRgO9bZKn9Bl42D5YEyMSYPXsxzcb08dqbRlbzWNJzJXE6YVa ...

  8. What IS MPI

    一.MPI message passing interface A specification for the developers and users of message passing libr ...

  9. luogu P1533 可怜的狗狗 |莫队+二分

    题目背景 小卡由于公务需要出差,将新家中的狗狗们托付给朋友嘉嘉,但是嘉嘉是一个很懒的人,他才没那么多时间帮小卡喂狗狗. 题目描述 小卡家有N只狗,由于品种.年龄不同,每一只狗都有一个不同的漂亮值.漂亮 ...

  10. Dubbo简介与使用

    1:Dubbo是什么 阿里生产的一种rpc 实现框架  Dubbo 是一个分布式服务框架,是阿里巴巴开源项目 ,被国内电商及互联网项目中使用. Dubbo 致力于提供高性能和透明化的RPC远程服务调用 ...