龙珠计划-机器学习- day02 利用XGBoost 进行分类

  • 龙珠计划-机器学习- day02 利用XGBoost 进行分类

1. XGBoost简介

1.1 简介

XGBoost是2016年由华盛顿大学陈天奇老师带领开发的一个可扩展机器学习系统。严格意义上讲XGBoost并不是一种模型,而是一个可供用户轻松解决分类、回归或排序问题的软件包。它内部实现了梯度提升树(GBDT)模型,并对模型中的算法进行了诸多优化,在取得高精度的同时又保持了极快的速度,在一段时间内成为了国内外数据挖掘、机器学习领域中的大规模杀伤性武器。

XGBoost在机器学习与数据挖掘领域有着极为广泛的应用。据统计在2015年Kaggle平台上29个获奖方案中,17只队伍使用了XGBoost;在2015年KDD-Cup中,前十名的队伍均使用了XGBoost,且集成其他模型比不上调节XGBoost的参数所带来的提升。这些实实在在的例子都表明,XGBoost在各种问题上都可以取得非常好的效果。

同时,XGBoost还被成功应用在工业界与学术界的各种问题中。例如商店销售额预测、高能物理事件分类、web文本分类;用户行为预测、运动检测、广告点击率预测、恶意软件分类、灾害风险预测、在线课程退学率预测。虽然领域相关的数据分析和特性工程在这些解决方案中也发挥了重要作用,但学习者与实践者对XGBoost的一致选择表明了这一软件包的影响力与重要性。

1.2 原理

  • GBDT ---- 梯度提升决策树

GBDT是一种迭代的决策树算法,该算法由多棵决策树组成,所有树的结论累加起来做最终答案。它在被提出之初就和SVM一起被认为是泛化能力较强的算法。GBDT中的树是回归树(不是分类树),GBDT用来做回归预测,调整后也可以用于分类。

  • XGBoost

    image-20210308080456583

XGBoost是基于CART树的集成模型,它的思想是串联多个决策树模型共同进行决策

那么如何串联呢?XGBoost采用迭代预测误差的方法串联。举个通俗的例子,我们现在需要预测一辆车价值3000元。我们构建决策树1训练后预测为2600元,我们发现有400元的误差,那么决策树2的训练目标为400元,但决策树2的预测结果为350元,还存在50元的误差就交给第三棵树……以此类推,每一颗树用来估计之前所有树的误差,最后所有树预测结果的求和就是最终预测结果!

2. 基于天气数据集的XGBoost分类实战

2.1 数据集

  • 数据集的链接: train.csv

    下载完成数据集后,准备对其进行预处理。

  • 数据集预处理

    先导入所需要的工具包

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
  • 读入数据

    data = pd.read_csv("2_dataset/train.csv")
    data
    
    image-20210307164903333

    可见数据已经读入完毕。数据清洗中很重要的一环是对缺失值的处理。pandas 对这种情况有很友好的函数。

  • 缺失值处理

    首先查看有无缺失值

    data.info()
    
    
    image-20210307165542391

    可见,非空值的数量并不一致,说明有非空值。

    然后填充缺失值

    data = data.fillna(-1)
    data
    
    image-20210307165651815
  • 统计两种类别的分布

pd.Series(data['RainTomorrow']).value_counts()
image-20210307170100663

2.2 数据可视化

  • 标记出来数据类型的特征和文字类型的数据
numercial_features = [x for x in data.columns if data[x].dtype==np.float]
numercial_features


category_features = [x for x in data.columns if data[x].dtype != np.float and x!="RainTomorrow"]
category_features
image-20210307170443213
  • 下面开始画各种特征之间的关联性
sns.pairplot(data=data[["Rainfall","Evaporation","Sunshine"]+["RainTomorrow"]],diag_kind="hist",hue="RainTomorrow")
plt.show()
image-20210307170717661

如果两种特征之间的关联性很强的话,其实在进行分类建模的时候,可以祛除其中一个。在上图中,特征之间 的关联性强表现在点的分布是不是类似的。当然,除了这种图之外,也可以用协方差等表示。

  • 看一下哪个特征与明天是否下雨的关联性较大

现在要决定利用哪些特征来进行分析了,需要确定哪些特征与结果的关联性更大。这个时候可以画箱型图。箱型图,展示了某个数据特征的最大值最小值中位数、及上下四分位数。利用,这些数据,可以直观的观察到哪些特征的数据分布和明天是否下雨这个结果的分布相似,从而可以确定哪些特征是我们需要的特征。选取的原则之一,是要选取尽量大的,并且各种分布最好和目标数据类似。

for col in data[numercial_features].columns:
    if col != "RainTomorrow":
        sns.boxplot(x="RainTomorrow",y=col,saturation=0.5,palette="pastel",data=data)
        plt.title(col)
        plt.show()
image-20210307194337651

上图并没有展示完全,读者可以自己尝试运行之后看看结果。

最后得出的结论为:Sunshine,Humidity3pm,Cloud9am,Cloud3pm的区分能力较强。

  • 降雨偏好-空间
tlog = {}
for i in category_features:
    tlog[i] = data[data['RainTomorrow'] == 'Yes'][i].value_counts()
flog = {}
for i in category_features:
    flog[i] = data[data['RainTomorrow'] == 'No'][i].value_counts()


plt.figure(figsize=(10,10))
plt.subplot(1,2,1)
plt.title('RainTomorrow')
sns.barplot(x = pd.DataFrame(tlog['Location']).sort_index()['Location'], y = pd.DataFrame(tlog['Location']).sort_index().index, color = "red")
plt.subplot(1,2,2)
plt.title('Not RainTomorrow')
sns.barplot(x = pd.DataFrame(flog['Location']).sort_index()['Location'], y = pd.DataFrame(flog['Location']).sort_index().index, color = "blue")
plt.show()
image-20210307200321424

从上图中可以看到,不同地区的降雨偏好是有很大区别的。


上图是一种barplot,是seaborn的一种反应某种数据均值的一种图,个人猜测,上图代表了不同地区的平均降雨量。


  • 降雨偏好-时间

我们已经知道了空间分布对降雨量的影响是比较大的。那么,时间分布是否对降雨量有关联的,比如,今天下雨了,那么明天下雨的可能性是怎样的。

plt.figure(figsize=(10,2))
plt.subplot(1,2,1)
plt.title('RainTomorrow')
sns.barplot(x = pd.DataFrame(tlog['RainToday'][:2]).sort_index()['RainToday'], y = pd.DataFrame(tlog['RainToday'][:2]).sort_index().index, color = "red")
plt.subplot(1,2,2)
plt.title('Not RainTomorrow')
sns.barplot(x = pd.DataFrame(flog['RainToday'][:2]).sort_index()['RainToday'], y = pd.DataFrame(flog['RainToday'][:2]).sort_index().index, color = "blue")
plt.show()

image-20210307202530163

可以看到, 今天下雨明天未必下雨,但是今天不下雨,明天多数可能也不下雨。

2.3 对类别非数值值进行编码

由于本文所使用的XGBoost模型不能识别字符串类型的数据,所以呢,需要先对数据集中的以字符串存储的数据进行编码,比如,yes=1, no =0 等编码方式就可以。

## 把所有的相同类别的特征编码为同一个值
def get_mapfunction(x):
    mapp = dict(zip(x.unique().tolist(),
         range(len(x.unique().tolist()))))
    def mapfunction(y):
        if y in mapp:
            return mapp[y]
        else:
            return -1
    return mapfunction
for i in category_features:
    data[i] = data[i].apply(get_mapfunction(data[i]))

image-20210307204030764

可以看到,数据已经进行了编码。

现在,就准备将数据投入XGBoost模型中了。

2.4 训练模型

from sklearn.model_selection import train_test_split

data_target_part = data['RainTomorrow']
data_features_part = data[[x for x in data.columns if x!= "RainTomorrow"]]

x_train,x_test,y_train,y_test = train_test_split(data_features_part,data_target_part,test_size=0.2,random_state=20210307)

from xgboost.sklearn import XGBClassifier
clf = XGBClassifier()
clf.fit(x_train,y_train)

2.5 模型评估

train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)

#%%
from sklearn import metrics

#%%
metrics.accuracy_score(train_predict,y_train)

#%%
metrics.accuracy_score(test_predict,y_test)
image-20210308081441516

2.6 混淆矩阵热力图

confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)
confusion_matrix_result

#%%
plt.figure(figsize=(8,6))
sns.heatmap(confusion_matrix_result,annot=True,cmap='Blues')
plt.xlabel("predict lables")
plt.ylabel('true labels')
plt.show()

image-20210308081621472

plus: 还可以利用xgboost确定重要特征。

sns.barplot(y=data_features_part.columns,x=clf.feature_importances_)
plt.show()
image-20210308081743037

2.7 参数优化

from sklearn.model_selection import GridSearchCV

learning_rate = [0.1,0.3,0.6]
subsample = [0.8,0.9]
colsample_bytree = [0.6,0.8]
max_depth = [3,5,8]

parameters = {
    'learning_rate':learning_rate,
    'subsample':subsample,
    'colsample_bytree':colsample_bytree,
    'max_depth':max_depth
}

model = XGBClassifier(n_estimators=50)


#%%
model

#%%
clf = GridSearchCV(model,parameters,cv=3,scoring='accuracy',verbose=1,n_jobs=1)
clf = clf.fit(x_train,y_train)
clf

#%%
clf.best_params_
Fitting 3 folds for each of 36 candidates, totalling 108 fits
image-20210308081918086

利用优化后的参数再次训练模型

clf = XGBClassifier(colsample_bytree=0.8,learning_rate=0.3,max_depth=5,subsample=0.9)
clf.fit(x_train,y_train)

#%%
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)

#%%
metrics.accuracy_score(train_predict,y_train)


#%%
metrics.accuracy_score(test_predict,y_test)

#%%
## 查看混淆矩阵 (预测值和真实值的各类情况统计矩阵)
confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)
print('The confusion matrix result:\n',confusion_matrix_result)

# 利用热力图对于结果进行可视化
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.show()


image-20210308082014396
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

古承风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值