文章目录
基于树模型的XGBoost则能很好地处理表格数据.所以打比赛常用
一.基础知识
1.损失函数
损失函数分为经验风险损失函数和结构风险损失函数。经验风险损失函数指预测结果和实际结果的差别,结构风险损失函数是指经验风险损失函数加上正则项。
机器学习模型关于单个样本的预测值与真实值的差称为损失。损失越小,模型越好,如果预测值与真实值相等,就是没有损失。
用于计算损失的函数称为损失函数。模型每一次预测的好坏用损失函数来度量。
通常机器学习每一个算法中都会有一个目标函数,算法的求解过程是通过对这个目标函数优化的过程。在分类或者回归问题中,通常使用损失函数(代价函数)作为其目标函数。损失函数用来评价模型的预测值和真实值不一样的程度,损失函数越好,通常模型的性能越好。不同的算法使用的损失函数不一样。
-
损失函数或者代价函数的目的是:衡量模型的预测能力的好坏。
-
损失函数(Loss function):是定义在单个训练样本上的,也就是就算一个样本的误差,比如我们想要分类,就是预测的类别和实际类别的区别,是一个样本的哦,用L表示。
-
代价函数(Cost function):是定义在整个训练集上面的,也就是所有样本的误差的总和的平均,也就是损失函数的总和的平均,有没有这个平均其实不会影响最后的参数的求解结果。
2.GBDT与XGBoost区别
- 1.目标函数通过二阶泰勒展开式做近似。传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。注:支持自定义代价函数,只要函数可一阶和二阶求导。
- 2.定义了树的复杂度,即xgboost在代价函数里加入了正则项,用于控制模型的复杂度,正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。代替了剪枝。
- 3.分裂结点处通过结构打分和分割损失动态生长。结构分数代替了回归树的误差平方和。
- 4.分裂结点特征分割点选取使用了近似算法-可并行的近似直方图算法。树节点在进行分裂时,我们需要计算每个特征的每个分割点对应的增益,即用贪心法枚举所有可能的分割点。当数据无法一次载入内存或者在分布式情况下,贪心算法效率就会变得很低,所以xgboost还提出了一种可并行的近似直方图算法,用于高效地生成候选的分割点。用于加速和减小内存消耗。
- 5.可以处理稀疏、缺失数据(节点分裂算法能自动利用特征的稀疏性),可以学习出它的分裂方向,加快稀疏计算速度。
- 6.列抽样(column subsampling)[传统GBDT没有],Shrinkage(缩减),相当于学习速率(xgboost中的eta)[传统GBDT也有]
- 7.支持并行化处理。xgboost的并行是在特征粒度上的,在训练之前,预先对特征进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行,即在不同的特征属性上采用多线程并行方式寻找最佳分割点。
- 8.传统GBDT以CART作为基分类器,xgboost还支持线性分类器,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。通过booster [default=gbtree]设置参数:gbtree: tree-based models/gblinear: linear models。
二.xgboost原理
(1)目标函数
xgboost目标函数
解释:
(2)正则化(惩罚项)
- 打个比方:你喝粥,我加一点白砂糖,你可能会更喜欢喝(+2),如果什么都不加你照样和平时一样喝(+1),如果加一点点胡椒粉你会硬着头皮喝下去(0.1),如果加沙子的话你就不会喝了(-1)
正则项
解释
(3)损失函数(代价函数)
解释: 简单来说,代价指的就是预测值(估计值)与实际值之间的差,代价函数J就是让这个差趋于0,当代价函数J等于0的时候,这时候的预测值就和实际值是完全相等的,也就是说明此时我们已经对实际情况进行了完美的估计了。
如果是回归问题我们使用损失函数的是
MSE 即:
使用这个损失函数的原因就是这是一个线性回归问题所以使用这个损失函数
如果是分类问题我们使用的是对数损失函数:
即:
为什么这个损失函数函数能够用于分类问题呢?
我们不妨代入几个真实值和预测值进去(0-1)
三. 实战
基本步骤
1. 数据接口
XGBoost python 模块能够使用以下方式加载数据:
-
LIBSVM text format file (LIBSVM文本格式文件)
-
Comma-separated values (CSV) file (逗号分隔值(CSV)文件)
-
NumPy 2D array (NumPy 2D矩阵)
-
SciPy 2D sparse array (二维稀疏矩阵)
-
cuDF DataFrame
-
Pandas data frame
-
XGBoost binary buffer file (XGBoost二进制缓冲文件)
2. 参数
常用参数:
(1)一般参数:
- booster[default=gbtree]选择基分类器 gbtree、gblinear 树或线性分类器
- silent [default=0] 是否输出详细信息 0不输出 1输出
- nthread [default to maximum number of threads available if not set]线程数默认最大
(2)Tree Booster参数:
- eta [default=0.3]:shrinkage参数,用于更新叶子节点权重时,乘以该系数,避免步长过大。参数值越大,越可能无法收敛。把学习率 eta 设置的小一些,小学习率可以使得后面的学习更加仔细。
- min_child_weight [default=1]:这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。
- max_depth [default=6]: 每颗树的最大深度,树高越深,越容易过拟合。
- gamma [default=0]:在树的叶子节点上作进一步分区所需的最小损失减少。越大,算法越保守。[0,∞]
- max_delta_step [default=0]:这个参数在更新步骤中起作用,如果取0表示没有约束,如果取正值则使得更新步骤更加保守。可以防止做太大的更新步子,使更新更加平缓。 通常,这个参数是不需要的,但它可能有助于逻辑回归时,类是非常不平衡。设置它的值为1-10可能有助于控制更新。
- subsample [default=1]:样本随机采样,较低的值使得算法更加保守,防止过拟合,但是太小的值也会造成欠拟合。
- colsample_bytree [default=1]:列采样,对每棵树的生成用的特征进行列采样.一般设置为: 0.5-1
- lambda [default=1]:控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
- alpha [default=0]:控制模型复杂程度的权重值的 L1 正则项参数,参数值越大,模型越不容易过拟合。
- scale_pos_weight [default=1]如果取值大于0的话,在类别样本不平衡的情况下有助于快速收敛。
- tree_method[default=’auto’]可选 {‘auto’, ‘exact’, ‘approx’} 贪心算法(小数据集)/近似算法(大数据集)
(3)学习任务参数:
- objective [ default=reg:linear ]定义最小化损失函数类型
最常用的值有: - binary:logistic 二分类的逻辑回归,返回预测的概率(不是类别)。
- multi:softmax 使用softmax的多分类器,返回预测的类别(不是概率)。
在这种情况下,你还需要多设一个参数:num_class(类别数目)。 - multi:softprob 和multi:softmax参数一样,但是返回的是每个数据属于各个类别的概率。
- seed [ default=0 ]随机种子
- eval_metric[根据目标objective默认]
对于有效数据的度量方法。
对于回归问题,默认值是rmse,对于分类问题,默认值是error。
典型值有:- rmse 均方根误差( ∑Ni=1ϵ2N‾‾‾‾‾‾‾√ )
- mae 平均绝对误差( ∑Ni=1|ϵ|N )
- logloss 负对数似然函数值
- error 二分类错误率(阈值为0.5)
- merror 多分类错误率
- mlogloss 多分类logloss损失函数
- auc 曲线下面积
(4)命令行参数:
- num_round 迭代次数/树的个数
基于天气数据集的XGBoost分类实战
## 基础函数库
import numpy as np
import pandas as pd
## 绘图函数库
import matplotlib.pyplot as plt
import seaborn as sns
#我们利用Pandas自带的read_csv函数读取并转化为DataFrame格式
data = pd.read_csv('train.csv')
## 利用.info()查看数据的整体信息
data.info()
首先我们打印出数据集整体信息:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 106644 entries, 0 to 106643
Data columns (total 23 columns):
Date 106644 non-null object
Location 106644 non-null object
MinTemp 106183 non-null float64
MaxTemp 106413 non-null float64
Rainfall 105610 non-null float64
Evaporation 60974 non-null float64
Sunshine 55718 non-null float64
WindGustDir 99660 non-null object
WindGustSpeed 99702 non-null float64
WindDir9am 99166 non-null object
WindDir3pm 103788 non-null object
WindSpeed9am 105643 non-null float64
WindSpeed3pm 104653 non-null float64
Humidity9am 105327 non-null float64
Humidity3pm 103932 non-null float64
Pressure9am 96107 non-null float64
Pressure3pm 96123 non-null float64
Cloud9am 66303 non-null float64
Cloud3pm 63691 non-null float64
Temp9am 105983 non-null float64
Temp3pm 104599 non-null float64
RainToday 105610 non-null object
RainTomorrow 106644 non-null object
dtypes: float64(16), object(7)
memory usage: 18.7+ MB
我们来看看各个数据的含义:
进行简单的数据查看,我们可以利用 .head() 头部.tail()尾部
head=data.head()
Backend Qt5Agg is interactive backend. Turning interactive mode on.
Date Location MinTemp ... Temp3pm RainToday RainTomorrow
0 2012/1/19 MountGinini 12.1 ... 22.0 No No
1 2015/4/13 Nhil 10.2 ... 23.7 No Yes
2 2010/8/5 Nuriootpa -0.4 ... 9.0 Yes No
3 2013/3/18 Adelaide 13.2 ... 21.7 No No
4 2011/2/16 Sale 14.1 ... 28.2 No No
[5 rows x 23 columns]
参考文章:
一.损失函数(代价函数)
二.正则项
三.模型原理
四.优化方法