Xgboost是Boosting算法的其中一种,Boosting算法的思想是将许多弱分类器集成在一起,形成一个强分类器。因为Xgboost是一种提升树模型,所以它是将许多树模型集成在一起,形成一个很强的分类器。而所用到的树模型则是CART回归树模型。Xgboost是在GBDT的基础上进行改进,使之更强大,适用于更大范围。
Xgboost算法可以给预测模型带来能力的提升。
实际上,Xgboost是以“正则化提升(regularized boosting)” 技术而闻名。Xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数,每个叶子节点上输出的score的L2模的平方和。从Bias-variance tradeoff角度来讲,正则项降低了模型的variance(方差),使学习出来的模型更加简单,防止过拟合,这也是Xgboost优于传统GBDT的一个特征。
Xgboost工具支持并行。众所周知,Boosting算法是顺序处理的,也是说Boosting不是一种串行的结构吗?怎么并行的?注意Xgboost的并行不是tree粒度的并行。Xgboost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含)。Xgboost的并行式在特征粒度上的,也就是说每一颗树的构造都依赖于前一颗树。
我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),Xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分类时,需要计算每个特征的增益,大大减少计算量。这个block结构也使得并行成为了可能,在进行节点的分裂的时候,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。
Xgboost支持用户自定义目标函数和评估函数,只要目标函数二阶可导就行。它对模型增加了一个全新的维度,所以我们的处理不会受到任何限制。
对于特征的值有缺失的样本,Xgboost可以自动学习出他的分裂方向。Xgboost内置处理缺失值的规则。用户需要提供一个和其他样本不同的值,然后把它作为一个参数穿进去,以此来作为缺失值的取值。Xgboost在不同节点遇到缺失值时采用不同的处理方法,并且会学习未来遇到缺失值时的处理方法。
Xgboost先从顶到底建立所有可以建立的子树,再从底到顶反向机芯剪枝,比起GBM,这样不容易陷入局部最优解。
Xgboost允许在每一轮Boosting迭代中使用交叉验证。因此可以方便的获得最优Boosting迭代次数,而GBM使用网格搜索,只能检测有限个值。
Xgboost可以加载多种数据格式的训练数据:
libsvm 格式的文本数据;
Numpy 的二维数组;
XGBoost 的二进制的缓存文件。加载的数据存储在对象 DMatrix 中。
加载libsvm格式数据:
data_train = xgb.DMatrix('train.svm.txt')
加载二进制的缓存数据:
data_train = xgb.DMatrix('train.svm.buffer')
加载numpy的数组:
data = np.random.rand(5,10) # 5行10列数据集
label = np.random.randint(2,size=5) # 二分类目标值
data_train = xgb.DMatrix(data,label=label) # 组成训练集
将scipy.sparse格式的数据转化为Dmatrix格式:
csr = scipy.sparse.csr_matrix((dat,(row,col)))
data_train = xgb.DMatrix( csr )
将Dmatrix格式的数据保存成Xgboost的二进制格式,在下次加载时可以提高加载速度,使用方法如下:
data_train = xgb.DMatrix('train.svm.txt')
data_train.save_binary("train.buffer")
可以使用如下方式处理DMatrix中的缺失值:
data_train = xgb.DMatrix( data, label=label, missing = -999.0)
当需要给样本设置权重时,可以用如下方式:
w = np.random.rand(5,1)
data_train = xgb.DMatrix( data, label=label, missing = -999.0, weight=w)
Xgboost使用key-value字典的方式存储参数:
# xgboost模型
params = {
'booster':'gbtree', # 使用哪种助推器。可以是gbtree,gblinear或dart; gbtree并dart使用基于树的模型,同时gblinear使用线性函数。
'objective':'multi:softmax', # 多分类问题
'num_class':10, # 类别数,与multi softmax并用
'gamma':0.1, # 用于控制是否后剪枝的参数,越大越保守,一般0.1 0.2的样子
'max_depth':12, # 构建树的深度,越大越容易过拟合
'lambda':2, # 控制模型复杂度的权重值的L2 正则化项参数,参数越大,模型越不容易过拟合
'subsample':0.7, # 随机采样训练样本
'colsample_bytree':3,# 这个参数默认为1,是每个叶子里面h的和至少是多少
# 对于正负样本不均衡时的0-1分类而言,假设h在0.01附近,min_child_weight为1
#意味着叶子节点中最少需要包含100个样本。这个参数非常影响结果,
# 控制叶子节点中二阶导的和的最小值,该参数值越小,越容易过拟合
'silent':0, # 设置成1 则没有运行信息输入,最好是设置成0
'eta':0.007, # 如同学习率
'seed':1000,
'nthread':7, #CPU线程数
#'eval_metric':'auc'
}
在运行Xgboost之前,必须设置三种类型参数:general parameters,booster parameters和task parameters:
这个参数是来控制理想的优化目标和每一步结果的度量方法。
xgboost.train(params,dtrain,num_boost_round=10,evals(),obj=None,
feval=None,maximize=False,early_stopping_rounds=None,evals_result=None,
verbose_eval=True,learning_rates=None,xgb_model=None)
num_round = 10
bst = xgb.train( plst, data_train, num_round, evallist )
# X_test类型可以是二维List,也可以是numpy的数组
data_test = DMatrix(X_test)
ans = model.predict(data_test)
xgb_model.get_booster().save_model('xgb.model')
tar = xgb.Booster(model_file='xgb.model')
x_test = xgb.DMatrix(x_test)
pre=tar.predict(x_test)
act=y_test
print(mean_squared_error(act, pre))
bst.save_model('test.model')
导出模型到txt文件并浏览模型的含义:
# 导出模型到文件
bst.dump_model('dump.raw.txt')
# 导出模型和特征映射
bst.dump_model('dump.raw.txt','featmap.txt')
bst = xgb.Booster({'nthread':4}) # init model
bst.load_model("model.bin") # load data
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()
# accuarcy:93.33%
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()
from xgboost.sklearn import XGBClassifier
clf = XGBClassifier(
silent=0, # 设置成1则没有运行信息输出,最好是设置为0,是否在运行升级时打印消息
# nthread = 4 # CPU 线程数 默认最大
learning_rate=0.3 , # 如同学习率
min_child_weight = 1,
# 这个参数默认为1,是每个叶子里面h的和至少是多少,对正负样本不均衡时的0-1分类而言
# 假设h在0.01附近,min_child_weight为1 意味着叶子节点中最少需要包含100个样本
# 这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易过拟合
max_depth=6, # 构建树的深度,越大越容易过拟合
gamma = 0,# 树的叶子节点上做进一步分区所需的最小损失减少,越大越保守,一般0.1 0.2这样子
subsample=1, # 随机采样训练样本,训练实例的子采样比
max_delta_step=0, # 最大增量步长,我们允许每个树的权重估计
colsample_bytree=1, # 生成树时进行的列采样
reg_lambda=1, #控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合
# reg_alpha=0, # L1正则项参数
# scale_pos_weight =1 # 如果取值大于0的话,在类别样本不平衡的情况下有助于快速收敛,平衡正负权重
# objective = 'multi:softmax', # 多分类问题,指定学习任务和响应的学习目标
# num_class = 10, # 类别数,多分类与multisoftmax并用
n_estimators=100, # 树的个数
seed = 1000, # 随机种子
# eval_metric ='auc')
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()
# accuracy:93%
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()
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.datasets import make_hastie_10_2
import xgboost as xgb
#记录程序运行时间
import time
start_time = time.time()
X, y = make_hastie_10_2(random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)##test_size测试集合所占比例
#xgb矩阵赋值
xgb_train = xgb.DMatrix(X_train, label=y_train)
xgb_test = xgb.DMatrix(X_test,label=y_test)
##参数
params={
'booster':'gbtree',
'silent':1 ,#设置成1则没有运行信息输出,最好是设置为0.
#'nthread':7,# cpu 线程数 默认最大
'eta': 0.007, # 如同学习率
'min_child_weight':3,
# 这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言
#,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。
#这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。
'max_depth':6, # 构建树的深度,越大越容易过拟合
'gamma':0.1, # 树的叶子节点上作进一步分区所需的最小损失减少,越大越保守,一般0.1、0.2这样子。
'subsample':0.7, # 随机采样训练样本
'colsample_bytree':0.7, # 生成树时进行的列采样
'lambda':2, # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
#'alpha':0, # L1 正则项参数
#'scale_pos_weight':1, #如果取值大于0的话,在类别样本不平衡的情况下有助于快速收敛。
#'objective': 'multi:softmax', #多分类的问题
#'num_class':10, # 类别数,多分类与 multisoftmax 并用
'seed':1000, #随机种子
#'eval_metric': 'auc'
}
plst = list(params.items())
num_rounds = 100 # 迭代次数
watchlist = [(xgb_train, 'train'),(xgb_test, 'val')]
#训练模型并保存
# early_stopping_rounds 当设置的迭代次数较大时,early_stopping_rounds 可在一定的迭代次数内准确率没有提升就停止训练
model = xgb.train(plst, xgb_train, num_rounds, watchlist,early_stopping_rounds=100,pred_margin=1)
#model.save_model('./model/xgb.model') # 用于存储训练出的模型
print "best best_ntree_limit",model.best_ntree_limit
y_pred = model.predict(xgb_test,ntree_limit=model.best_ntree_limit)
print ('error=%f' % ( sum(1 for i in range(len(y_pred)) if int(y_pred[i]>0.5)!=y_test[i]) /float(len(y_pred))))
#输出运行时长
cost_time = time.time()-start_time
print "xgboost success!",'\n',"cost time:",cost_time,"(s)......"
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.datasets import make_hastie_10_2
from xgboost.sklearn import XGBClassifier
X, y = make_hastie_10_2(random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)##test_size测试集合所占比例
clf = XGBClassifier(
silent=0 ,#设置成1则没有运行信息输出,最好是设置为0.是否在运行升级时打印消息。
#nthread=4,# cpu 线程数 默认最大
learning_rate= 0.3, # 如同学习率
min_child_weight=1,
# 这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言
#,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。
#这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。
max_depth=6, # 构建树的深度,越大越容易过拟合
gamma=0, # 树的叶子节点上作进一步分区所需的最小损失减少,越大越保守,一般0.1、0.2这样子。
subsample=1, # 随机采样训练样本 训练实例的子采样比
max_delta_step=0,#最大增量步长,我们允许每个树的权重估计。
colsample_bytree=1, # 生成树时进行的列采样
reg_lambda=1, # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
#reg_alpha=0, # L1 正则项参数
#scale_pos_weight=1, #如果取值大于0的话,在类别样本不平衡的情况下有助于快速收敛。平衡正负权重
#objective= 'multi:softmax', #多分类的问题 指定学习任务和相应的学习目标
#num_class=10, # 类别数,多分类与 multisoftmax 并用
n_estimators=100, #树的个数
seed=1000 #随机种子
#eval_metric= 'auc'
)
clf.fit(X_train,y_train,eval_metric='auc')
#设置验证集合 verbose=False不打印过程
clf.fit(X_train, y_train,eval_set=[(X_train, y_train), (X_val, y_val)],eval_metric='auc',verbose=False)
#获取验证集合结果
evals_result = clf.evals_result()
y_true, y_pred = y_test, clf.predict(X_test)
print"Accuracy : %.4g" % metrics.accuracy_score(y_true, y_pred)
#回归
#m_regress = xgb.XGBRegressor(n_estimators=1000,seed=0)
调参步骤:
下面详细的进行这些操作:
为了确定Boosting参数,我们要先给其他参数一个初始值。咱们先按照如下方法取值:
from xgboost import XGBClassifier
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)
param_test1 = {
'max_depth':range(3,10,2),
'min_child_weight':range(1,6,2)
}
#param_test2 = {
'max_depth':[4,5,6],
'min_child_weight':[4,5,6]
}
from sklearn import svm, grid_search, datasets
from sklearn import grid_search
gsearch1 = grid_search.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_
#网格搜索scoring='roc_auc'只支持二分类,多分类需要修改scoring(默认支持多分类)
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_
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_
尝试不同的subsample 和 colsample_bytree 参数。我们分两个阶段来进行这个步骤。这两个步骤都取0.6,0.7,0.8,0.9作为起始值。
#取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_
由于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_
最后,我们使用较低的学习速率,以及使用更多的决策树,我们可以用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)等。
import xgboost as xgb
import pandas as pd
#获取数据
from sklearn import cross_validation
from sklearn.datasets import load_iris
iris = load_iris()
#切分数据集
X_train, X_test, y_train, y_test = cross_validation.train_test_split(iris.data, iris.target, test_size=0.33, random_state=42)
#设置参数
m_class = xgb.XGBClassifier(
learning_rate =0.1,
n_estimators=1000,
max_depth=5,
gamma=0,
subsample=0.8,
colsample_bytree=0.8,
objective= 'binary:logistic',
nthread=4,
seed=27)
#训练
m_class.fit(X_train, y_train)
test_21 = m_class.predict(X_test)
print "Accuracy : %.2f" % metrics.accuracy_score(y_test, test_21)
#预测概率
#test_2 = m_class.predict_proba(X_test)
#查看AUC评价标准
from sklearn import metrics
print "Accuracy : %.2f" % metrics.accuracy_score(y_test, test_21)
##必须二分类才能计算
##print "AUC Score (Train): %f" % metrics.roc_auc_score(y_test, test_2)
#查看重要程度
feat_imp = pd.Series(m_class.booster().get_fscore()).sort_values(ascending=False)
feat_imp.plot(kind='bar', title='Feature Importances')
import matplotlib.pyplot as plt
plt.show()
#回归
#m_regress = xgb.XGBRegressor(n_estimators=1000,seed=0)
#m_regress.fit(X_train, y_train)
#test_1 = m_regress.predict(X_test)
print(model.feature_importances_)
# plot
pyplot.bar(range(len(model.feature_importances_)), model.feature_importances_)
pyplot.show()
# 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 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()
特征重要性得分,可以用于在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%,这可能是对这样一个小数据集的清洗,但是对于更大的数据集和使用交叉验证作为模型评估方案可能是更有用的策略。
from sklearn.model_selection import GridSearchCV
tuned_parameters= [{'n_estimators':[100,200,500],
'max_depth':[3,5,7], ##range(3,10,2)
'learning_rate':[0.5, 1.0],
'subsample':[0.75,0.8,0.85,0.9]
}]
tuned_parameters= [{'n_estimators':[100,200,500,1000]
}]
clf = GridSearchCV(XGBClassifier(silent=0,nthread=4,learning_rate= 0.5,min_child_weight=1, max_depth=3,gamma=0,subsample=1,colsample_bytree=1,reg_lambda=1,seed=1000), param_grid=tuned_parameters,scoring='roc_auc',n_jobs=4,iid=False,cv=5)
clf.fit(X_train, y_train)
##clf.grid_scores_, clf.best_params_, clf.best_score_
print(clf.best_params_)
y_true, y_pred = y_test, clf.predict(X_test)
print"Accuracy : %.4g" % metrics.accuracy_score(y_true, y_pred)
y_proba=clf.predict_proba(X_test)[:,1]
print "AUC Score (Train): %f" % metrics.roc_auc_score(y_true, y_proba)
from sklearn.model_selection import GridSearchCV
parameters= [{'learning_rate':[0.01,0.1,0.3],'n_estimators':[1000,1200,1500,2000,2500]}]
clf = GridSearchCV(XGBClassifier(
max_depth=3,
min_child_weight=1,
gamma=0.5,
subsample=0.6,
colsample_bytree=0.6,
objective= 'binary:logistic', #逻辑回归损失函数
scale_pos_weight=1,
reg_alpha=0,
reg_lambda=1,
seed=27
),
param_grid=parameters,scoring='roc_auc')
clf.fit(X_train, y_train)
print(clf.best_params_)
y_pre= clf.predict(X_test)
y_pro= clf.predict_proba(X_test)[:,1]
print "AUC Score : %f" % metrics.roc_auc_score(y_test, y_pro)
print"Accuracy : %.4g" % metrics.accuracy_score(y_test, y_pre)
输出特征重要性:
import pandas as pd
import matplotlib.pylab as plt
feat_imp = pd.Series(clf.booster().get_fscore()).sort_values(ascending=False)
feat_imp.plot(kind='bar', title='Feature Importances')
plt.ylabel('Feature Importance Score')
plt.show()
https://blog.csdn.net/waitingzby/article/details/81610495
https://xgboost.readthedocs.io/en/latest/parameter.html#general-parameters
https://www.cnblogs.com/wj-1314/p/9402324.html