赞
踩
Xgboost是Boosting算法的其中一种,Boosting算法的思想是将许多弱分类器集成在一起,形成一个强分类器。因为Xgboost是一种提升树模型,所以它是将许多树模型集成在一起,形成一个很强的分类器。而所用到的树模型则是CART回归树模型。
Xgboost是在GBDT的基础上进行改进,使之更强大,适用于更大范围。
Xgboost一般和sklearn一起使用,但是由于sklearn中没有集成Xgboost,所以才需要单独下载安装。
Xgboost算法可以给预测模型带来能力的提升。当我们对其表现有更多了解的时候,我们会发现他有如下优势:
2.1 正则化
实际上,Xgboost是以“正则化提升(regularized boosting)” 技术而闻名。Xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数,每个叶子节点上输出的score的L2模的平方和。从Bias-variance tradeoff角度来讲,正则项降低了模型的variance,使学习出来的模型更加简单,防止过拟合,这也是Xgboost优于传统GBDT的一个特征
2.2 并行处理
Xgboost工具支持并行。众所周知,Boosting算法是顺序处理的,也是说Boosting不是一种串行的结构吗?怎么并行的?注意Xgboost的并行不是tree粒度的并行。Xgboost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含)。Xgboost的并行式在特征粒度上的,也就是说每一颗树的构造都依赖于前一颗树。
我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),Xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分类时,需要计算每个特征的增益,大大减少计算量。这个block结构也使得并行成为了可能,在进行节点的分裂的时候,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。
2.3 灵活性
Xgboost支持用户自定义目标函数和评估函数,只要目标函数二阶可导就行。它对模型增加了一个全新的维度,所以我们的处理不会受到任何限制。
2.4 缺失值处理
对于特征的值有缺失的样本,Xgboost可以自动学习出他的分裂方向。Xgboost内置处理缺失值的规则。用户需要提供一个和其他样本不同的值,然后把它作为一个参数穿进去,以此来作为缺失值的取值。Xgboost在不同节点遇到缺失值时采用不同的处理方法,并且会学习未来遇到缺失值时的处理方法。
2.5 剪枝
Xgboost先从顶到底建立所有可以建立的子树,再从底到顶反向机芯剪枝,比起GBM,这样不容易陷入局部最优解
2.6 内置交叉验证
Xgboost允许在每一轮Boosting迭代中使用交叉验证。因此可以方便的获得最优Boosting迭代次数,而GBM使用网格搜索,只能检测有限个值。
# 常规参数
# 模型参数
max_delta_step
含义:这参数限制每棵树权重改变的最大步长。如果这个参数的值为0,那就意味着没有约束。如果它被赋予了某个正值,那么它会让这个算法更加保守。 通常,这个参数不需要设置。但是当各类别的样本十分不平衡时,它对逻辑回归是很有帮助的。 这个参数一般用不到,但是你可以挖掘出来它更多的用处。
colsample_bylevel
用来控制树的每一级的每一次分裂,对列数的采样的占比。 我个人一般不太用这个参数,因为subsample参数和colsample_bytree参数可以起到相同的作用。但是如果感兴趣,可以挖掘这个参数更多的用处。
colsample_bynode
是每个节点(拆分)的列的子采样率。每次评估新的拆分时,都会发生一次子采样。列是从为当前级别选择的列集中进行二次采样的。
# 学习任务参数
校验数据所需要的评价指标,不同的目标函数将会有缺省的评价指标(rmse for regression, and error for classification, mean average precision for ranking)-
用户可以添加多种评价指标,对于Python用户要以list传递参数对给程序,而不是map参数list参数不会覆盖’eval_metric’
可供的选择如下:
# 代码主要函数:
Xgboost有两大类接口:Xgboost原生接口 和sklearn接口,并且Xgboost能够实现分类回归两种任务。下面对这四种情况做以解析。
- from sklearn.datasets import load_iris
- import xgboost as xgb
- from xgboost import plot_importance
- import matplotlib.pyplot as plt
- from sklearn.model_selection import train_test_split
- from sklearn.metrics import accuracy_score # 准确率
-
- # 记载样本数据集
- iris = load_iris()
- X,y = iris.data,iris.target
- # 数据集分割
- X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=123457)
-
- # 算法参数
- params = {
- 'booster':'gbtree',
- 'objective':'multi:softmax',
- 'num_class':3,
- 'gamma':0.1,
- 'max_depth':6,
- 'lambda':2,
- 'subsample':0.7,
- 'colsample_bytree':0.7,
- 'min_child_weight':3,
- 'slient':1,
- 'eta':0.1,
- 'seed':1000,
- 'nthread':4,
- }
-
- plst = params.items()
-
- # 生成数据集格式
- dtrain = xgb.DMatrix(X_train,y_train)
- num_rounds = 500
- # xgboost模型训练
- model = xgb.train(plst,dtrain,num_rounds)
-
- # 对测试集进行预测
- dtest = xgb.DMatrix(X_test)
- y_pred = model.predict(dtest)
-
- # 计算准确率
- accuracy = accuracy_score(y_test,y_pred)
- print('accuarcy:%.2f%%'%(accuracy*100))
-
- # 显示重要特征
- plot_importance(model)
- plt.show()
2,基于Xgboost原生接口的回归
- import xgboost as xgb
- from xgboost import plot_importance
- from matplotlib import pyplot as plt
- from sklearn.model_selection import train_test_split
- from sklearn.datasets import load_boston
- from 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:gamma',
- 'gamma':0.1,
- 'max_depth':5,
- 'lambda':3,
- 'subsample':0.7,
- 'colsample_bytree':0.7,
- 'min_child_weight':3,
- 'slient':1,
- 'eta':0.1,
- 'seed':1000,
- 'nthread':4,
- }
-
- dtrain = xgb.DMatrix(X_train,y_train)
- num_rounds = 300
- plst = params.items()
- model = xgb.train(plst,dtrain,num_rounds)
-
- # 对测试集进行预测
- dtest = xgb.DMatrix(X_test)
- ans = model.predict(dtest)
-
- # 显示重要特征
- plot_importance(model)
- plt.show()
3,Xgboost使用sklearn接口的分类(推荐)(下面两个例子)
- from sklearn.datasets import load_iris
- import xgboost as xgb
- from xgboost import plot_importance
- from matplotlib import pyplot as plt
- from sklearn.model_selection import train_test_split
- from sklearn.metrics import accuracy_score
-
- # 加载样本数据集
- iris = load_iris()
- X,y = iris.data,iris.target
- X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=12343)
-
- # 训练模型
- model = xgb.XGBClassifier(max_depth=5,learning_rate=0.1,n_estimators=160,silent=True,objective='multi:softmax')
- model.fit(X_train,y_train)
-
- # 对测试集进行预测
- y_pred = model.predict(X_test)
-
- #计算准确率
- accuracy = accuracy_score(y_test,y_pred)
- print('accuracy:%2.f%%'%(accuracy*100))
-
- # 显示重要特征
- plot_importance(model)
- plt.show()
- # -*- coding: utf-8 -*-
- """
- ###############################################################################
- # 作者:wanglei5205
- # 邮箱:wanglei5205@126.com
- # 代码:http://github.com/wanglei5205
- # 博客:http://cnblogs.com/wanglei5205
- # 目的:学习xgboost的XGBClassifier函数
- # 官方API文档:http://xgboost.readthedocs.io/en/latest/python/python_api.html#module-xgboost.training
- ###############################################################################
- """
- ### load module
- import matplotlib.pyplot as plt
- from sklearn import datasets
- from sklearn.model_selection import train_test_split
- from sklearn.metrics import accuracy_score
- from xgboost import XGBClassifier
- from xgboost import plot_importance
-
- ### load datasets
- digits = datasets.load_digits()
-
- ### data analysis
- print(digits.data.shape)
- print(digits.target.shape)
-
- ### data split
- x_train,x_test,y_train,y_test = train_test_split(digits.data,
- digits.target,
- test_size = 0.3,
- random_state = 33)
- ### fit model for train data
- model = XGBClassifier(learning_rate=0.1,
- n_estimators=1000, # 树的个数--1000棵树建立xgboost
- max_depth=6, # 树的深度
- min_child_weight = 1, # 叶子节点最小权重
- gamma=0., # 惩罚项中叶子结点个数前的参数
- subsample=0.8, # 随机选择80%样本建立决策树
- colsample_btree=0.8, # 随机选择80%特征建立决策树
- objective='multi:softmax', # 指定损失函数
- scale_pos_weight=1, # 解决样本个数不平衡的问题
- random_state=27 # 随机数
- )
- model.fit(x_train,
- y_train,
- eval_set = [(x_test,y_test)],
- eval_metric = "mlogloss",
- early_stopping_rounds = 10,
- verbose = True)
-
- ### plot feature importance
- fig,ax = plt.subplots(figsize=(15,15))
- plot_importance(model,
- height=0.5,
- ax=ax,
- max_num_features=64)
- plt.show()
-
- ### make prediction for test data
- y_pred = model.predict(x_test)
-
- ### model evaluate
- accuracy = accuracy_score(y_test,y_pred)
- print("accuarcy: %.2f%%" % (accuracy*100.0))
- """
- 95.74%
- """
转自https://www.cnblogs.com/wanglei5205/p/8579244.html
- import xgboost as xgb
- from xgboost import plot_importance
- from matplotlib import pyplot as plt
- from sklearn.model_selection import train_test_split
- from sklearn.datasets import load_boston
-
- # 导入数据集
- 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)
-
- model = xgb.XGBRegressor(max_depth=5,learning_rate=0.1,n_estimators=160,silent=True,objective='reg:gamma')
- model.fit(X_train,y_train)
-
- # 对测试集进行预测
- ans = model.predict(X_test)
-
- # 显示重要特征
- plot_importance(model)
- plt.show()
1,选择较高的学习速率(learning rate)。一般情况下,学习速率的值为0.1.但是,对于不同的问题,理想的学习速率有时候会在0.05~0.3之间波动。选择对应于此学习速率的理想决策树数量。Xgboost有一个很有用的函数“cv”,这个函数可以在每一次迭代中使用交叉验证,并返回理想的决策树数量。
2,对于给定的学习速率和决策树数量,进行决策树特定参数调优(max_depth , min_child_weight , gamma , subsample,colsample_bytree)在确定一棵树的过程中,我们可以选择不同的参数。
3,Xgboost的正则化参数的调优。(lambda , alpha)。这些参数可以降低模型的复杂度,从而提高模型的表现。
4,降低学习速率,确定理想参数。
下面详细的进行这些操作。
为了确定Boosting参数,我们要先给其他参数一个初始值。咱们先按照如下方法取值:
注意,上面这些参数的值知识一个初始的估计值,后继需要调优。这里把学习速率就设成默认的0.1。然后用Xgboost中的cv函数来确定最佳的决策树数量。
- def modelfit(alg, dtrain, predictors,useTrainCV=True, cv_folds=5, early_stopping_rounds=50):
- if useTrainCV:
- xgb_param = alg.get_xgb_params()
- xgtrain = xgb.DMatrix(dtrain[predictors].values, label=dtrain[target].values)
- cvresult = xgb.cv(xgb_param, xgtrain, num_boost_round=alg.get_params()['n_estimators'], nfold=cv_folds,
- metrics='auc', early_stopping_rounds=early_stopping_rounds, show_progress=False)
- alg.set_params(n_estimators=cvresult.shape[0])
-
- #Fit the algorithm on the data
- alg.fit(dtrain[predictors], dtrain['Disbursed'],eval_metric='auc')
-
- #Predict training set:
- dtrain_predictions = alg.predict(dtrain[predictors])
- dtrain_predprob = alg.predict_proba(dtrain[predictors])[:,1]
-
- #Print model report:
- print "\nModel Report"
- print "Accuracy : %.4g" % metrics.accuracy_score(dtrain['Disbursed'].values, dtrain_predictions)
- print "AUC Score (Train): %f" % metrics.roc_auc_score(dtrain['Disbursed'], dtrain_predprob)
-
- feat_imp = pd.Series(alg.booster().get_fscore()).sort_values(ascending=False)
- feat_imp.plot(kind='bar', title='Feature Importances')
- plt.ylabel('Feature Importance Score')
- #Choose all predictors except target & IDcols
- predictors = [x for x in train.columns if x not in [target,IDcol]]
- xgb1 = XGBClassifier(
- learning_rate =0.1,
- n_estimators=1000,
- max_depth=5,
- min_child_weight=1,
- gamma=0,
- subsample=0.8,
- colsample_bytree=0.8,
- objective= 'binary:logistic',
- nthread=4,
- scale_pos_weight=1,
- seed=27)
- modelfit(xgb1, train, predictors)
我们先对这两个参数调优,是因为他们对最终结果有很大的影响。首先,我们先大范围地粗略参数,然后再小范围的微调。
注意:在这一节我会进行高负荷的栅格搜索(grid search),这个过程大约需要15-30分钟甚至更久,具体取决于你系统的性能,你也可以根据自己系统的性能选择不同的值。
- param_test1 = {
- 'max_depth':range(3,10,2),
- 'min_child_weight':range(1,6,2)
- }
- gsearch1 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=140, max_depth=5,
- min_child_weight=1, gamma=0, subsample=0.8, colsample_bytree=0.8,
- objective= 'binary:logistic', nthread=4, scale_pos_weight=1, seed=27),
- param_grid = param_test1, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
- gsearch1.fit(train[predictors],train[target])
- gsearch1.grid_scores_, gsearch1.best_params_, gsearch1.best_score_
至此,我们对于数值进行了较大跨度的12中不同的排列组合,可以看出理想的max_depth值为5,理想的min_child_weight值为5。在这个值附近我们可以再进一步调整,来找出理想值。我们把上下范围各拓展1,因为之前我们进行组合的时候,参数调整的步长是2。
- param_test2 = {
- 'max_depth':[4,5,6],
- 'min_child_weight':[4,5,6]
- }
- gsearch2 = GridSearchCV(estimator = XGBClassifier( learning_rate=0.1, n_estimators=140, max_depth=5,
- min_child_weight=2, gamma=0, subsample=0.8, colsample_bytree=0.8,
- objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27),
- param_grid = param_test2, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
- gsearch2.fit(train[predictors],train[target])
- gsearch2.grid_scores_, gsearch2.best_params_, gsearch2.best_score_
至此,我们得到max_depth的理想取值为4,min_child_weight的理想取值为6。同时,我们还能看到cv的得分有了小小一点提高。需要注意的一点是,随着模型表现的提升,进一步提升的难度是指数级上升的,尤其是你的表现已经接近完美的时候。当然啦,你会发现,虽然min_child_weight的理想取值是6,但是我们还没尝试过大于6的取值。像下面这样,就可以尝试其它值。
- param_test2b = {
- 'min_child_weight':[6,8,10,12]
- }
- gsearch2b = GridSearchCV(estimator = XGBClassifier( learning_rate=0.1, n_estimators=140, max_depth=4,
- min_child_weight=2, gamma=0, subsample=0.8, colsample_bytree=0.8, objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), param_grid = param_test2b, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
-
- gsearch2b.fit(train[predictors],train[target])
-
- modelfit(gsearch3.best_estimator_, train, predictors)
-
- gsearch2b.grid_scores_, gsearch2b.best_params_, gsearch2b.best_score_
我们可以看出,6确确实实是理想的取值了。
在已经调整好其他参数的基础上,我们可以进行gamma参数的调优了。Gamma参数取值范围很大,这里我们设置为5,其实你也可以取更精确的gamma值。
- param_test3 = {
- 'gamma':[i/10.0 for i in range(0,5)]
- }
-
- gsearch3 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1,
- n_estimators=140, max_depth=4,min_child_weight=6, gamma=0,
- subsample=0.8, colsample_bytree=0.8,objective= 'binary:logistic',
- nthread=4, scale_pos_weight=1,seed=27), param_grid = param_test3, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
-
- gsearch3.fit(train[predictors],train[target])
-
- gsearch3.grid_scores_, gsearch3.best_params_, gsearch3.best_score_
从这里可以看出来,我们在第一步调参时设置的初始gamma值就是比较合适的。也就是说,理想的gamma值为0。在这个过程开始之前,最好重新调整boosting回合,因为参数都有变化。
从这里,可以看出,得分提高了。所以,最终得到的参数是:
- xgb2 = XGBClassifier(
- learning_rate =0.1,
- n_estimators=1000,
- max_depth=4,
- min_child_weight=6,
- gamma=0,
- subsample=0.8,
- colsample_bytree=0.8,
- objective= 'binary:logistic',
- nthread=4,
- scale_pos_weight=1,
- seed=27)
- modelfit(xgb2, train, predictors)
尝试不同的subsample 和 colsample_bytree 参数。我们分两个阶段来进行这个步骤。这两个步骤都取0.6,0.7,0.8,0.9作为起始值。
- param_test4 = {
- 'subsample':[i/10.0 for i in range(6,10)],
- 'colsample_bytree':[i/10.0 for i in range(6,10)]
- }
-
- gsearch4 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=177, max_depth=3, min_child_weight=4, gamma=0.1, subsample=0.8, colsample_bytree=0.8, objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), param_grid = param_test4, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
-
- gsearch4.fit(train[predictors],train[target])
- gsearch4.grid_scores_, gsearch4.best_params_, gsearch4.best_score_
从这里可以看出来,subsample 和 colsample_bytree 参数的理想取值都是0.8。现在,我们以0.05为步长,在这个值附近尝试取值。
- param_test5 = {
- 'subsample':[i/100.0 for i in range(75,90,5)],
- 'colsample_bytree':[i/100.0 for i in range(75,90,5)]
- }
-
- gsearch5 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=177, max_depth=4, min_child_weight=6, gamma=0, subsample=0.8, colsample_bytree=0.8, objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), param_grid = param_test5, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
-
- gsearch5.fit(train[predictors],train[target])
我们得到的理想取值还是原来的值。因此,最终的理想取值是:
由于gamma函数提供了一种更加有效的降低过拟合的方法,大部分人很少会用到这个参数,但是我们可以尝试用一下这个参数。
- param_test6 = {
- 'reg_alpha':[1e-5, 1e-2, 0.1, 1, 100]
- }
- gsearch6 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=177, max_depth=4, min_child_weight=6, gamma=0.1, subsample=0.8, colsample_bytree=0.8, objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), param_grid = param_test6, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
-
- gsearch6.fit(train[predictors],train[target])
- gsearch6.grid_scores_, gsearch6.best_params_, gsearch6.best_score_
我们可以看到,相比之前的结果,CV的得分甚至还降低了。但是我们之前使用的取值是十分粗糙的,我们在这里选取一个比较靠近理想值(0.01)的取值,来看看是否有更好的表现。
- param_test7 = {
- 'reg_alpha':[0, 0.001, 0.005, 0.01, 0.05]
- }
- gsearch7 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=177, max_depth=4, min_child_weight=6, gamma=0.1, subsample=0.8, colsample_bytree=0.8, objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), param_grid = param_test7, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
-
- gsearch7.fit(train[predictors],train[target])
- gsearch7.grid_scores_, gsearch7.best_params_, gsearch7.best_score_
可以看到,CV的得分提高了。现在,我们在模型中来使用正则化参数,来看看这个参数的影响。
- xgb3 = XGBClassifier(
- learning_rate =0.1,
- n_estimators=1000,
- max_depth=4,
- min_child_weight=6,
- gamma=0,
- subsample=0.8,
- colsample_bytree=0.8,
- reg_alpha=0.005,
- objective= 'binary:logistic',
- nthread=4,
- scale_pos_weight=1,
- seed=27)
- modelfit(xgb3, train, predictors)
然后我们发现性能有了小幅度提高。
最后,我们使用较低的学习速率,以及使用更多的决策树,我们可以用Xgboost中CV函数来进行这一步工作。
- xgb4 = XGBClassifier(
- learning_rate =0.01,
- n_estimators=5000,
- max_depth=4,
- min_child_weight=6,
- gamma=0,
- subsample=0.8,
- colsample_bytree=0.8,
- reg_alpha=0.005,
- objective= 'binary:logistic',
- nthread=4,
- scale_pos_weight=1,
- seed=27)
- modelfit(xgb4, train, predictors)
总结一下,要想模型的表现有大幅的提升,调整每个参数带来的影响也必须清楚,仅仅靠着参数的调整和模型的小幅优化,想要让模型的表现有个大幅度提升是不可能的。要想模型的表现有质的飞跃,需要依靠其他的手段。诸如,特征工程(feature egineering) ,模型组合(ensemble of model),以及堆叠(stacking)等。
使用梯度提升算法的好处是在提升树被创建后,可以相对直接地得到每个属性的重要性得分。一般来说,重要性分数,衡量了特征在模型中的提升决策树构建中的价值。一个属性越多的被用来在模型中构建决策树,它的重要性就相对越高。
属性重要性是通过对数据集中的每个属性进行计算,并进行排序得到。在单个决策树中通过每个属性分裂点改进性能度量的量来计算属性重要性。由节点负责加权和记录次数,也就是说一个属性对分裂点改进性能度量越大(越靠近根节点),权值越大;被越多提升树所选择,属性越重要。性能度量可以是选择分裂节点的Gini纯度,也可以是其他度量函数。
最终将一个属性在所有提升树中的结果进行加权求和后然后平均,得到重要性得分。
一个已训练的Xgboost模型能够自动计算特征重要性,这些重要性得分可以通过成员变量feature_importances_得到。可以通过如下命令打印:
print(model.feature_importances_)
我们可以直接在条形图上绘制这些分数,以便获得数据集中每个特征的相对重要性的直观显示,例如:
- # plot
- pyplot.bar(range(len(model.feature_importances_)), model.feature_importances_)
- pyplot.show()
我们可以通过在the Pima Indians onset of diabetes 数据集上训练XGBoost模型来演示,并从计算的特征重要性中绘制条形图。
- # plot feature importance manually
- from numpy import loadtxt
- from xgboost import XGBClassifier
- from matplotlib import pyplot
- from sklearn.datasets import load_iris
- # load data
- dataset = load_iris()
- # split data into X and y
- X = dataset.data
- y = dataset.target
- # fit model no training data
- model = XGBClassifier()
- model.fit(X, y)
- # feature importance
- print(model.feature_importances_)
- # plot
- pyplot.bar(range(len(model.feature_importances_)), model.feature_importances_)
- pyplot.show()
运行这个实例,首先输出特征重要性分数:
[0.17941953 0.11345647 0.41556728 0.29155672]
相对重要性条形图:
这种绘制的缺点在于,只显示了特征重要性而没有排序,可以在绘制之前对特征重要性得分进行排序。
通过内建的绘制函数进行特征重要性得分排序后的绘制,这个函数就是plot_importance(),示例如下:
- # plot feature importance manually
- from numpy import loadtxt
- from xgboost import XGBClassifier
- from matplotlib import pyplot
- from sklearn.datasets import load_iris
- from xgboost import plot_importance
-
- # load data
- dataset = load_iris()
- # split data into X and y
- X = dataset.data
- y = dataset.target
- # fit model no training data
- model = XGBClassifier()
- model.fit(X, y)
- # feature importance
- print(model.feature_importances_)
- # plot feature importance
-
- plot_importance(model)
- pyplot.show()
示例得到条形图:
根据其在输入数组的索引,特征被自动命名为f0~f3,在问题描述中手动的将这些索引映射到名称,我们可以看到,f2具有最高的重要性,f1具有最低的重要性。
特征重要性得分,可以用于在scikit-learn中进行特征选择。通过SelectFromModel类实现,该类采用模型并将数据集转换为具有选定特征的子集。这个类可以采取预先训练的模型,例如在整个数据集上训练的模型。然后,它可以阈值来决定选择哪些特征。当在SelectFromModel实例上调用transform()方法时,该阈值被用于在训练集和测试集上一致性选择相同特征。
在下面的示例中,我们首先在训练集上训练xgboost模型,然后在测试上评估。使用从训练数据集计算的特征重要性,然后,将模型封装在一个SelectFromModel实例中。我们使用这个来选择训练集上的特征,用所选择的特征子集训练模型,然后在相同的特征方案下对测试集进行评估。
- # select features using threshold
- selection = SelectFromModel(model, threshold=thresh, prefit=True)
- select_X_train = selection.transform(X_train)
- # train model
- selection_model = XGBClassifier()
- selection_model.fit(select_X_train, y_train)
- # eval model
- select_X_test = selection.transform(X_test)
- y_pred = selection_model.predict(select_X_test)
我们可以通过测试多个阈值,来从特征重要性中选择特征。具体而言,每个输入变量的特征重要性,本质上允许我们通过重要性来测试每个特征子集。
完整代码如下:
- # plot feature importance manually
- import numpy as np
- from xgboost import XGBClassifier
- from matplotlib import pyplot
- from sklearn.datasets import load_iris
- from xgboost import plot_importance
- from sklearn.model_selection import train_test_split
- from sklearn.metrics import accuracy_score
- from sklearn.feature_selection import SelectFromModel
-
- # load data
- dataset = load_iris()
- # split data into X and y
- X = dataset.data
- y = dataset.target
-
- # split data into train and test sets
- X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.33,random_state=7)
-
- # fit model no training data
- model = XGBClassifier()
- model.fit(X_train, y_train)
- # feature importance
- print(model.feature_importances_)
-
- # make predictions for test data and evaluate
- y_pred = model.predict(X_test)
- predictions = [round(value) for value in y_pred]
- accuracy = accuracy_score(y_test,predictions)
- print("Accuracy:%.2f%%"%(accuracy*100.0))
-
- #fit model using each importance as a threshold
- thresholds = np.sort(model.feature_importances_)
- for thresh in thresholds:
- # select features using threshold
- selection = SelectFromModel(model,threshold=thresh,prefit=True )
- select_X_train = selection.transform(X_train)
- # train model
- selection_model = XGBClassifier()
- selection_model.fit(select_X_train, y_train)
- # eval model
- select_X_test = selection.transform(X_test)
- y_pred = selection_model.predict(select_X_test)
- predictions = [round(value) for value in y_pred]
- accuracy = accuracy_score(y_test,predictions)
- print("Thresh=%.3f, n=%d, Accuracy: %.2f%%" % (thresh, select_X_train.shape[1], accuracy * 100.0))
运行示例,得到输出:
- [0.20993228 0.09029345 0.54176074 0.15801354]
- Accuracy:92.00%
- Thresh=0.090, n=4, Accuracy: 92.00%
- Thresh=0.158, n=3, Accuracy: 92.00%
- Thresh=0.210, n=2, Accuracy: 86.00%
- Thresh=0.542, n=1, Accuracy: 90.00%
我们可以看到,模型的性能通常随着所选择的特征的数量减少,在这一问题上,可以对测试集准确率和模型复杂度做一个权衡,例如选择三个特征,接受准确率为92%,这可能是对这样一个小数据集的清洗,但是对于更大的数据集和使用交叉验证作为模型评估方案可能是更有用的策略。
参考文献:
https://blog.csdn.net/waitingzby/article/details/81610495
https://blog.csdn.net/u011089523/article/details/72812019
https://blog.csdn.net/luanpeng825485697/article/details/79907149
https://xgboost.readthedocs.io/en/latest/parameter.html#general-parameters
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。