机器学习-》统计学习方法03--XGBoost(适合初学者,直接看代码,注释很全)

公式推导详见刘建平老师博客

https://www.cnblogs.com/pinard/p/11114748.html

代码:(可直接运行(前提是各种包已经安装))

代码框架

1.关于xgboost的基本实现操作
2.利用XGBClassifier的fit函数的参数实现–》每插一棵树,看看效果
3.利用xgboost库的plot_importance(通过图片)展示特征的重要程度
4.关于超参数的选择(结合交叉验证)
from sklearn.model_selection import GridSearchCV,StratifiedKFold
5.关于XGBClassifier的参数(详解)

代码中的数据

.csv文件 链接:https://pan.baidu.com/s/1lxWzQbL1hYpEm2t-l3il8g
提取码:rbyi

#需要安装pip install -i https://pypi.tuna.tsinghua.edu.cn/simple xgboost


from numpy import  loadtxt
from  xgboost import XGBClassifier
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score


print("==================测试①xgboost的基本操作++++++++++++++++++++")
#第一步加载数据(9列768行)
dataset=loadtxt("pima-indians-diabetes.csv",delimiter=",")
#对数据进行划分(区分X和Y)
X=dataset[:,0:8]  #前8列是X
Y=dataset[:,8]    #第9列是Y{0,1}

#定义种子
seed=7
test_size=0.33   #将X的33%作为测试集
#使用函数train_test_split进行训练集  测试集的切分
#一定要注意train_test_split生成的X Y的测试集训练集的顺序
X_train,X_test,Y_train,Y_test=train_test_split(X,Y,test_size=test_size,random_state=seed)

#创建分类器对象
xgb=XGBClassifier()
#使用训练数据拟合(学习)
xgb.fit(X_train,Y_train)

#开始预测测试集-->得到预测的结果y_prev
y_pred=xgb.predict(X_test)
# print(y_pred)
# print(y_pred.shape)      # (254,)
# print(type(y_pred))      #<class 'numpy.ndarray'>
# print("-----------------")
#对预测数据y_pred进行数据处理
predictions=[round(value) for value in y_pred]
# print(predictions)
# print(len(predictions))  #254
# print(type(predictions)) #<class 'list'>
#使用accuracy_score方法进行评估真实y与predictions
accuracy1=accuracy_score(Y_test,y_pred)
accuracy2=accuracy_score(Y_test,predictions)
print("Accuracy1 :%.2f%%"%(accuracy1*100.0))
print("Accuracy2 :%.2f%%"%(accuracy2*100.0))

# print("=========")
# print(Y_test.shape)   #(254,)
# print(type(Y_test))   #<class 'numpy.ndarray'>
# print(len(Y_test))    #254

#所以其实prediction其实没有用

print("==================测试②每插一棵树,看看效果++++++++++++++++++++")

#实验②-->利用fit中的属性,每插一棵树,看看效果
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
Y = dataset[:,8]
# split data into train and test sets
seed = 7
test_size = 0.33
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)
# fit model no training data
model = XGBClassifier()
eval_set = [(X_test, y_test)]

#early_stopping_rounds=10(意思是当你的Loss连续10次都没有下降,则停止)
#eval_metric(评估指标)    eval_metric=["auc",“rmse”,"logloss"]
        # eval_metric的值不同不影响结果
#eval_set(是每次我们的模型会增加树模型,然后利用eval_set设置的数据进行测试)
#verbose(默认是True)(每加入一个模型之后表达效果有啥变化,用eval_set的数据进行测试,用eval_metric进行评估)
    #verbose=True会输出如下(前提是存在eval_metric):
                # [0]	validation_0-logloss:0.60491
                # [1]	validation_0-logloss:0.55934
                # [2]	validation_0-logloss:0.53068
                # [3]	validation_0-logloss:0.51795
                # [4]	validation_0-logloss:0.51153
                # [5]	validation_0-logloss:0.50935
                # [6]	validation_0-logloss:0.50818

model.fit(X_train, y_train, early_stopping_rounds=10, eval_metric="logloss", eval_set=eval_set, verbose=True)
# make predictions for test data
y_pred = model.predict(X_test)
# predictions = [round(value) for value in y_pred]
accuracy = accuracy_score(y_test, y_pred)
# accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))


from xgboost import plot_importance
print("++++++++++++++++++++++实验③展示特征的重要程度++++++++++++")
#实验③ --》没有测试集

dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
y = dataset[:,8]
# fit model no training data
model = XGBClassifier()
model.fit(X, y)
# plot feature importance
#借助xgboost的函数plot_importance展示特征的重要程度
plot_importance(model)
plt.show()







print("++++++++++++++++++++++实验④交叉验证++++++++++++")
#实验④交叉验证(对应刘建平的博客--》网格搜索调参)


# Tune learning_rate
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
Y = dataset[:,8]
# grid search
model = XGBClassifier()
learning_rate = [0.0001, 0.001, 0.01, 0.1, 0.2, 0.3]
param_grid = dict(learning_rate=learning_rate)
# print("param_grid:",param_grid)
            # param_grid: {'learning_rate': [0.0001, 0.001, 0.01, 0.1, 0.2, 0.3]}

#使用StratifiedFold进行交叉验证n_splits表示数据被分成几份
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=7)
# n_jobs=-1(让当前所有空闲的cpu都是跑这个)cv(交叉验证)=cross validation
grid_search = GridSearchCV(model, param_grid, scoring="neg_log_loss", n_jobs=-1, cv=kfold)
#这里如果不用grid_result也想,因为fit的返回值就是grid_search本身
grid_search.fit(X, Y)
# grid_result = grid_search.fit(X, Y)


# summarize results
#输出最好的一个学习率grid_search.best_score_来自_ grid_search.cv_results_['mean_test_score']
print("Best: %f using %s" % (grid_search.best_score_, grid_search.best_params_))

means = grid_search.cv_results_['mean_test_score']
params = grid_search.cv_results_['params']
# print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
# means = grid_result.cv_results_['mean_test_score']
# params = grid_result.cv_results_['params']
for mean, param in zip(means, params):
    print("%f  with: %r" % (mean, param))

# print(grid_search.cv_results_)
# {'mean_fit_time': array([0.52748313, 0.24913204, 0.23796189, 0.20395479, 0.19727135,0.19348218]),
#  'std_fit_time': array([0.33185264, 0.00882057, 0.00832465, 0.00587139, 0.00415489,0.00670483]),
#  'mean_score_time': array([0.00598423, 0.00768082, 0.00528574, 0.00448804, 0.00438888,0.00369058]),
#  'std_score_time': array([0.00260037, 0.00391546, 0.0023623 , 0.00091941, 0.00101705, 0.00089786]),
#  'param_learning_rate': masked_array(data=[0.0001, 0.001, 0.01, 0.1, 0.2, 0.3],mask=[False, False, False, False, False, False],fill_value='?',dtype=object),
#  'params': [{'learning_rate': 0.0001}, {'learning_rate': 0.001}, {'learning_rate': 0.01}, {'learning_rate': 0.1}, {'learning_rate': 0.2}, {'learning_rate': 0.3}],
#  'split0_test_score': array([-0.68950881, -0.6610532 , -0.54414835, -0.51705357, -0.60573395,-0.61618698]),
#  'split1_test_score': array([-0.69012355, -0.6650752 , -0.55696859, -0.70147709, -0.82469679,-0.87524744]),
#  'split2_test_score': array([-0.6882004 , -0.64987884, -0.46720184, -0.38750816, -0.4409432 ,-0.46860517]),
#  'split3_test_score': array([-0.68832627, -0.64981491, -0.50416831, -0.4390301 , -0.47235685,-0.53397724]),
#  'split4_test_score': array([-0.69059757, -0.66760606, -0.57257549, -0.69417489, -0.81282785,-0.89401205]),
#  'split5_test_score': array([-0.68935359, -0.66286262, -0.566491  , -0.67075771, -0.84372165,-0.92912194]),
#  'split6_test_score': array([-0.6899003 , -0.66205624, -0.48384999, -0.40248874, -0.41321876,-0.50515709]),
#  'split7_test_score': array([-0.68981991, -0.66299202, -0.55079499, -0.66440508, -0.89767134,-0.94604623]),
#  'split8_test_score': array([-0.69042595, -0.66881538, -0.54517815, -0.57131025, -0.64574119,-0.77252969]),
#  'split9_test_score': array([-0.68937626, -0.65852875, -0.51013966, -0.47902893, -0.5764963 ,-0.64700845]),
#  'mean_test_score': array([-0.68956326, -0.66086832, -0.53015164, -0.55272345, -0.65334079,-0.71878923]),
#  'std_test_score': array([0.00076006, 0.00620164, 0.03445209, 0.11763608, 0.17160916,0.17664138]),
#  'rank_test_score': array([5, 4, 1, 2, 3, 6])}






print("++++++++++++++++++关于XGBClassifier的参数+++++++++++++++++")


xgb1 = XGBClassifier(
 learning_rate =0.1,
 n_estimators=1000,
 max_depth=5,
 min_child_weight=1,
 gamma=0,#不是0,是比较小的数,
 subsample=0.8,
 colsample_bytree=0.8,
 objective= 'binary:logistic',
 nthread=4,
 scale_pos_weight=1,
 seed=27)

# 下面这些参数都是需要调参的,
#     不过一般先调  max_depth,
#                 min_child_weight
#                 gamma。
# 如果发现有过拟合的情况下,再尝试调后面几个参数。
#①max_depth:特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,
            #需要限制这个最大深度,具体的取值一般要网格搜索调参
#②min_child_weight: 最小的子节点权重阈值,如果某个树节点的权重小于这个阈值,
            # 则不会再分裂子树,即这个树节点就是叶子节点。
#③gamma: XGBoost的决策树分裂所带来的损失减小阈值。

#④subsample: 在选择样本时是否随机,如果不随机就设置为1
            # 子采样参数,这个也是不放回抽样,和sklearn  GBDT的subsample作用一样。
            # 选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,
            # 因此取值不能太低。初期可以取值1,如果发现过拟合后可以网格搜索调参找一个相对小一些的值
#⑤colsample_bytree/
# colsample_bylevel/
# colsample_bynode:
            # 这三个参数都是用于特征采样的,默认都是不做采样,即使用所有的特征建立决策树。
            # colsample_bytree控制整棵树的特征采样比例,
            # colsample_bylevel控制某一层的特征采样比例,
            # colsample_bynode控制某一个树节点的特征采样比例。
            # 比如我们一共64个特征,
            # 则假设colsample_bytree,colsample_bylevel和colsample_bynode都是0.5,
            # 则某一个树节点分裂时会随机采样8个特征来尝试分裂子树。
#⑥reg_alpha/
# reg_lambda:
            # 这2个是XGBoost的正则化参数。
            # reg_alpha是L1正则化系数,
            # reg_lambda是L2正则化系数,

#⑦learning_rate
            # learning_rate控制每个弱学习器的权重缩减系数,
            # 和sklearn  GBDT的learning_rate类似,
            # 较小的learning_rate意味着我们需要更多的弱学习器的迭代次数。
            # 通常我们用步长和迭代最大次数一起来决定算法的拟合效果。
            # 所以这两个参数n_estimators和learning_rate要一起调参才有效果。
#⑧n_estimators

#⑨n_jobs
# 控制算法的并发线程数,

#⑩scale_pos_weight(默认为1)用于类别不平衡的时候,负例和正例的比例。
            # 类似于sklearn中的class_weight。
            # 关于scale_pos_weight ,在xgboost里边的源码是
            #
            # if (label == 1.0f) {
            # w *= scale_pos_weight;
            # }


#11.importance_type
            # importance_type则可以查询各个特征的重要性程度。
            # 可以选择“gain”, “weight”, “cover”, “total_gain” 或者  “total_cover”。
            # 最后可以通过调用booster的get_score方法获取对应的特征权重。
            # “weight”通过特征被选中作为分裂特征的计数来计算重要性,
            # “gain”和“total_gain”则通过分别计算特征被选中做分裂特征时带来的平均增益和总增益来计算重要性。
            # “cover”和 “total_cover”通过计算特征被选中做分裂时的平均样本覆盖度和总体样本覆盖度来来计算重要性

#12.booster
            # 决定了XGBoost使用的弱学习器类型,可以是默认的gbtree, 也就是CART决策树,
            # 还可以是线性弱学习器gblinear以及DART。
            # 一般来说,我们使用gbtree就可以了,不需要调参。
#13.n_estimators
            #是非常重要的要调的参数,它关系到我们XGBoost模型的复杂度,
            # 因为它代表了我们决策树弱学习器的个数。这个参数对应sklearn  GBDT的n_estimators。																				n_estimators太小,容易欠拟合,n_estimators太大,模型会过于复杂,一般需要调参选择一个适中的数值。
#14.objective(loss function)
            #代表了我们要解决的问题是分类还是回归,或其他问题,以及对应的损失函数。
            #具体可以取的值很多,一般我们只关心在分类和回归的时候使用的参数。
            #在回归问题一般使用reg:squarederror ,即MSE均方误差。
            #二分类问题一般使用binary:logistic,
            #多分类问题一般使用multi:softmax。

#关于交叉验证
# 机器学习中经常会用到交叉验证,常用的就是KFold和StratifiedKFold
# StratifiedKFold(https://zhuanlan.zhihu.com/p/150446294)
# KFold函数与StratifiedKFold(参数相同)
#     共有三个参数:
            # n_splits:默认为3,表示将数据划分为多少份,即k折交叉验证中的k;
            # shuffle(洗牌):默认为False,表示是否需要打乱顺序,
                # 这个参数在很多的函数中都会涉及,
                # 如果设置为True,则会先打乱顺序再做划分,
                # 如果为False,会直接按照顺序做划分;
            # random_state:默认为None,表示随机数的种子,只有当shuffle设置为True的时候才会生效。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值