XGBoost是GBDT,梯度下降树的一种。
一、XGBoost是如何进行计算的
如果判断一个人是否喜欢玩电脑,可以用年龄、性别、职业等信息得到下面的回归树。
对每个节点赋予权重,然后可以计算每个人的得分,比如小男孩= 2,但是一个树用来拟合或者计算并不合理,因此增加树的数量。最终小男孩的得分为2.9
增加树的数量,利用集成学习进行预测的模型包含随机森林和提升树。利用下图来对一个树进行数学化表达。
然后下面表示XGBoost逐次进行训练的过程
为了保证加入添加函数之后的预测效果变好,还会引入正则化惩罚。(略)
二、代码实现
(1)格式转换
本文使用UCI的agaricus数据,UCI中的数据转换为libSVM格式代码如下:
def loadfmap( fname ): fmap = {} nmap = {} for l in open( fname ): arr = l.split() if arr[0].find('.') != -1: idx = int( arr[0].strip('.') ) assert idx not in fmap fmap[ idx ] = {} ftype = arr[1].strip(':') content = arr[2] else: content = arr[0] for it in content.split(','): if it.strip() == '': continue k , v = it.split('=') fmap[ idx ][ v ] = len(nmap) nmap[ len(nmap) ] = ftype+'='+k return fmap, nmap def write_nmap( fo, nmap ): for i in range( len(nmap) ): fo.write('%d\t%s\ti\n' % (i, nmap[i]) ) fmap, nmap = loadfmap( 'agaricus-lepiota.fmap' ) fo = open( 'featmap.txt', 'w' ) write_nmap( fo, nmap ) fo.close() fo = open( 'agaricus.txt', 'w' ) for l in open( 'agaricus-lepiota.data' ): arr = l.split(',') if arr[0] == 'p': fo.write('1') else: assert arr[0] == 'e' fo.write('0') for i in range( 1,len(arr) ): fo.write( ' %d:1' % fmap[i][arr[i].strip()] ) fo.write('\n') fo.close()
UCI中数据共23列,第一列为是否可以食用,后22列为蘑菇的属性。
p,x,s,n,t,p,f,c,n,k,e,e,s,s,w,w,p,w,o,p,k,s,u e,x,s,y,t,a,f,c,b,k,e,c,s,s,w,w,p,w,o,p,n,n,g e,b,s,w,t,l,f,c,b,n,e,c,s,s,w,w,p,w,o,p,n,n,m p,x,y,w,t,p,f,c,n,n,e,e,s,s,w,w,p,w,o,p,k,s,u
后22列映射关系为
1. cap-shape: bell=b,conical=c,convex=x,flat=f, knobbed=k,sunken=s 2. cap-surface: fibrous=f,grooves=g,scaly=y,smooth=s 3. cap-color: brown=n,buff=b,cinnamon=c,gray=g,green=r, pink=p,purple=u,red=e,white=w,yellow=y 4. bruises?: bruises=t,no=f 5. odor: almond=a,anise=l,creosote=c,fishy=y,foul=f, musty=m,none=n,pungent=p,spicy=s 6. gill-attachment: attached=a,descending=d,free=f,notched=n 7. gill-spacing: close=c,crowded=w,distant=d 8. gill-size: broad=b,narrow=n 9. gill-color: black=k,brown=n,buff=b,chocolate=h,gray=g, green=r,orange=o,pink=p,purple=u,red=e, white=w,yellow=y 10. stalk-shape: enlarging=e,tapering=t 11. stalk-root: bulbous=b,club=c,cup=u,equal=e, rhizomorphs=z,rooted=r,missing=? 12. stalk-surface-above-ring: fibrous=f,scaly=y,silky=k,smooth=s 13. stalk-surface-below-ring: fibrous=f,scaly=y,silky=k,smooth=s 14. stalk-color-above-ring: brown=n,buff=b,cinnamon=c,gray=g,orange=o, pink=p,red=e,white=w,yellow=y 15. stalk-color-below-ring: brown=n,buff=b,cinnamon=c,gray=g,orange=o, pink=p,red=e,white=w,yellow=y 16. veil-type: partial=p,universal=u 17. veil-color: brown=n,orange=o,white=w,yellow=y 18. ring-number: none=n,one=o,two=t 19. ring-type: cobwebby=c,evanescent=e,flaring=f,large=l, none=n,pendant=p,sheathing=s,zone=z 20. spore-print-color: black=k,brown=n,buff=b,chocolate=h,green=r, orange=o,purple=u,white=w,yellow=y 21. population: abundant=a,clustered=c,numerous=n, scattered=s,several=v,solitary=y 22. habitat: grasses=g,leaves=l,meadows=m,paths=p, urban=u,waste=w,woods=d
转化后的数据为
1 3:1 10:1 11:1 21:1 30:1 34:1 36:1 40:1 41:1 53:1 58:1 65:1 69:1 77:1 86:1 88:1 92:1 95:1 102:1 105:1 117:1 124:1 0 3:1 10:1 20:1 21:1 23:1 34:1 36:1 39:1 41:1 53:1 56:1 65:1 69:1 77:1 86:1 88:1 92:1 95:1 102:1 106:1 116:1 120:1 0 1:1 10:1 19:1 21:1 24:1 34:1 36:1 39:1 42:1 53:1 56:1 65:1 69:1 77:1 86:1 88:1 92:1 95:1 102:1 106:1 116:1 122:1 1 3:1 9:1 19:1 21:1 30:1 34:1 36:1 40:1 42:1 53:1 58:1 65:1 69:1 77:1 86:1 88:1 92:1 95:1 102:1 105:1 117:1 124:1
第一行第二列元素2表示cap-shape为convex,1表示“是”。第三行第3列的19表示cap-color为white。
然后分割为训练集、测试集
import random k = 1 nfold = 5 argv = 'agaricus.txt' fi = open( argv, 'r' ) ftr = open( argv+'.train', 'w' ) fte = open( argv+'.test', 'w' ) for l in fi: if random.randint( 1 , nfold ) == k: fte.write( l ) else: ftr.write( l ) fi.close() ftr.close() fte.close()
再然后进行模型的训练
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import xgboost as xgb import numpy as np # 1、xgBoost的基本使用 # 2、自定义损失函数的梯度和二阶导 train_data = 'agaricus.txt.train' test_data = 'agaricus.txt.test' # 定义一个损失函数 def log_reg(y_hat, y): p = 1.0 / (1.0 + np.exp(-y_hat)) g = p - y.get_label() h = p * (1.0 - p) return g, h # 错误率,本例子当中,估计值<0.5代表没有毒 def error_rate(y_hat, y): return 'error', float(sum(y.get_label() != (y_hat > 0.5))) / len(y_hat) if __name__ == "__main__": # 读取数据 data_train = xgb.DMatrix(train_data) data_test = xgb.DMatrix(test_data) # 设置参数 param = {'max_depth': 3, 'eta': 1, 'silent': 1, 'objective': 'binary:logistic'} # logitraw watchlist = [(data_test, 'eval'), (data_train, 'train')] n_round = 7 bst = xgb.train(param, data_train, num_boost_round=n_round, evals=watchlist, obj=log_reg, feval=error_rate) # 计算错误率 y_hat = bst.predict(data_test) y = data_test.get_label() print('y_hat',y_hat) print('y', y) error = sum(y != (y_hat > 0.5)) error_rate = float(error) / len(y_hat) print('样本总数:\t', len(y_hat)) print('错误数目:\t%4d' % error) print('错误率:\t%.5f%%' % (100 * error_rate))
本文引用文章:
XGboost_阿巴乾的博客-CSDN博客
机器学习的相关代码汇总_johnny_love_1968的博客-CSDN博客_机器学习代码