天池龙珠计划——机器学习训练营 Task2

目录

  • 前言
  • XGBoost介绍
  • 基于天气数据集的XGBoost分类实战

前言

笔记,记录龙珠机器学习训练营的第二阶段,关于xgboost的学习

XGBoost介绍

xgboost有听说过,也在kaggle上经常看到有人用。关于原理这方面,网络上大都只有应用的资料,关于原理的很少,通俗来讲,xgboost属于梯度提升树(GBDT)模型的范畴,GBDT的基本思想是让n层模型去拟合n-1层模型的偏差,从而不断使加法模型的偏差降低。相比于GBDT,xgboost做了一些改进,从而在效果和性能上有明显的提升。本节我们的重点还是放在实战应用上。

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

#代码是在DSW上运行,首先下载天池提供的天气数据集
!wget https://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/7XGBoost/train.csv
#读取数据并简略查看
import pandas as pd
data = pd.read_csv('train.csv')
data.head(5)
#可以看到train数据集中每一条数据有23个特征值

天池龙珠计划——机器学习训练营 Task2_第1张图片
可以看到数据是某天的天气状况,其中RainTomorrow属于预测label

特征名称 意义 取值范围
Date 日期 字符串
Location 气象站的地址 字符串
MinTemp 最低温度 实数
MaxTemp 最高温度 实数
Rainfall 降雨量 实数
Evaporation 蒸发量 实数
Sunshine 光照时间 实数
WindGustDir 最强的风的方向 字符串
WindGustSpeed 最强的风的速度 实数
WindDir9am 早上9点的风向 字符串
WindDir3pm 下午3点的风向 字符串
WindSpeed9am 早上9点的风速 实数
WindSpeed3pm 下午3点的风速 实数
Humidity9am 早上9点的湿度 实数
Humidity3pm 下午3点的湿度 实数
Pressure9am 早上9点的大气压 实数
Pressure3pm 早上3点的大气压 实数
Cloud9am 早上9点的云指数 实数
Cloud3pm 早上3点的云指数 实数
Temp9am 早上9点的温度 实数
Temp3pm 早上3点的温度 实数
RainToday 今天是否下雨 No,Yes
RainTomorrow 明天是否下雨 No,Yes
#对于缺省值,用-1填充
data = data.fillna(-1)
#查看数据集中label的分布情况
pd.Series(data['RainTomorrow']).value_counts()
#可以看到负样本的数量是要大于正样本,不平衡

在这里插入图片描述

#将数字value和非数字value分别存储
numerical_features = [x for x in data.columns if data[x].dtype == np.float]
category_features = [x for x in data.columns if data[x].dtype != np.float and x != 'RainTomorrow']
#选取降雨量、蒸发量、光照时间以明日是否降雨进行分类并绘制散点图
sns.pairplot(data=data[['Rainfall','Evaporation','Sunshine'] + 
						['RainTomorrow']], diag_kind='hist', hue= 'RainTomorrow')
plt.show()

天池龙珠计划——机器学习训练营 Task2_第2张图片
从上图可以发现,在2D情况下不同的特征组合对于第二天下雨与不下雨的散点分布,以及大概的区分能力。相对的Sunshine与其他特征的组合更具有区分能力

for col in data[numerical_features].columns:
    if col != 'RainTomorrow':
        sns.boxplot(x='RainTomorrow', y=col, saturation=0.5, palette='pastel', data=data)
        plt.title(col)
        plt.show()

天池龙珠计划——机器学习训练营 Task2_第3张图片

天池龙珠计划——机器学习训练营 Task2_第4张图片
天池龙珠计划——机器学习训练营 Task2_第5张图片
天池龙珠计划——机器学习训练营 Task2_第6张图片
利用箱型图我们也可以得到不同类别在不同特征上的分布差异情况。我们可以发现Sunshine,Humidity3pm,Cloud9am,Cloud3pm的区分能力较强

#用tlog和flog统计明日是否降雨的所有value的分布情况
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()

如tolg中Location项存储所有地区出现raintomorrow的次数情况
天池龙珠计划——机器学习训练营 Task2_第7张图片

#绘制降雨和不降雨两幅图,以地区为分类条件
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()

天池龙珠计划——机器学习训练营 Task2_第8张图片
从上图可以发现不同地区降雨情况差别很大,有些地方明显更容易降雨

#分析raintoday对raintomorrow的影响
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()

天池龙珠计划——机器学习训练营 Task2_第9张图片
两图分别代表today下雨的yes or no对raintomorrow下雨的影响,图一看出今天下雨并不会对明天下雨有影响,但是今天天晴,明天大概率天气为晴

# 把所有的相同类别的特征编码为同一个值
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:#非数字value编码
    data[i] = data[i].apply(get_mapfunction(data[i]))
data['Location'].unique()
#例如Location被从0到48进行编码,转化成数字类型

天池龙珠计划——机器学习训练营 Task2_第10张图片

from sklearn.model_selection import train_test_split
data_target_part = data['RainTomorrow']#预测label提出
data_features_part = data[[x for x in data.columns if x != 'RainTomorrow']]#除去label的data作为train的数据
x_train, x_test, y_train, y_test = train_test_split(data_features_part, data_target_part, test_size = 0.2, random_state = 2021)
#训练集和测试集4:1划分
#导入模型并对traindata和trainlabel进行拟合
from xgboost.sklearn import XGBClassifier
clf = XGBClassifier()
clf.fit(x_train, y_train)
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)
#对x_train进行回测正确率0.85,在划分的x_test测试正确率0.84

在这里插入图片描述

#我们可以通过查看模型的参数观察不同feature的权重
sns.barplot(y=data_features_part.columns, x=clf.feature_importances_)
#如下图,所有feature中,最为突出的为下午三点湿度和今日是否下雨,这两个也是影响明日降雨的最关键因素

天池龙珠计划——机器学习训练营 Task2_第11张图片
另外对于model的调参,使用GridSearchCV寻找最佳参数或是手动调参都是可以的。
XGBoost中包括但不限于下列对模型影响较大的参数:

  1. learning_rate: 有时也叫作eta,系统默认值为0.3。每一步迭代的步长,很重要。太大了运行准确率不高,太小了运行速度慢。
  2. subsample:系统默认为1。这个参数控制对于每棵树,随机采样的比例。减小这个参数的值,算法会更加保守,避免过拟合, 取值范围零到一。
  3. colsample_bytree:系统默认值为1。我们一般设置成0.8左右。用来控制每棵随机采样的列数的占比(每一列是一个特征)。
  4. max_depth: 系统默认值为6,我们常用3-10之间的数字。这个值为树的最大深度。这个值是用来控制过拟合的。max_depth越大,模型学习的更加具体。
#下面举例,对四个参数分别选取可能的最优结果并存储到para字典,传入GridSearchCV进行三次cv验证得到最优参数的clf
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)
clf = GridSearchCV(model, parameters, cv=3, scoring='accuracy',verbose=1,n_jobs=-1)
clf = clf.fit(x_train, y_train)
clf.best_params_
#如本次参数选取了如下图所示为最优

在这里插入图片描述

你可能感兴趣的:(龙珠机器学习训练营,机器学习,python)