https://www.zybuluo.com/Dounm/note/1031900
GBDT算法详解
http://mlnote.com/2016/10/05/a-guide-to-xgboost-A-Scalable-Tree-Boosting-System/
XGboost: A Scalable Tree Boosting System论文及源码导读
- 2016/10/29XGboost核心源码阅读
- 2016/10/05XGboost: A Scalable Tree Boosting System论文及源码导读
- 2016/11/18简述FastDBT和LightGBM中GBDT的实现
- 2016/10/29XGboost核心源码阅读
- 2016/10/05XGboost: A Scalable Tree Boosting System论文及源码导读
- 2016/10/02Gradient Boosting Decision Tree[下篇]
- 2016/09/24Gradient Boosting Decision Tree[上篇]
xgboost 解读(2)——近似分割算法
zhihu:
-如何理解 Bregman 散度?
-有哪些指标可以描述两个图(graph)的相似度?
-CNN模型可以输入离散特征吗?
- xgboost 如何使用MAE或MAPE作为目标函数?
-graph convolution network 有什么比较好的应用task?
-清华大学孙茂松组:图神经网络必读论文列表
- 深度学习时代的图模型,清华发文综述图网络
XGBoost 解读(2)——近似分割算法
https://yxzf.github.io/2017/04/xgboost-v2/
exact greedy -> 大数据量时 近似算法寻找分割点
https://yxzf.github.io/2017/03/xgboost-v1/
DNN在CTR预估上的应用
1.CTR预估
CTR预估是计算广告中最核心的算法之一,那么CTR预估是指什么呢?简单来说,CTR预估是对每次广告的点击情况做出预测,预测用户是点击还是不点击。具体定义可以参考 CTR. CTR预估和很多因素相关,比如历史点击率、广告位置、时间、用户等。CTR预估模型就是综合考虑各种因素、特征,在大量历史数据上训练得到的模型。CTR预估的训练样本一般从历史log、离线特征库获得。样本标签相对容易,用户点击标记为1,没有点击标记为0. 特征则会考虑很多,例如用户的人口学特征、广告自身特征、广告展示特征等。这些特征中会用到很多类别特征,例如用户所属职业、广告展示的IP地址等。一般对于类别特征会采样One-Hot编码,例如职业有三种:学生、白领、工人,那么会会用一个长度为3的向量分别表示他们:[1, 0, 0]、[0, 1, 0]、[0, 0, 1]. 可以这样会使得特征维度扩展很大,同时特征会非常稀疏。目前很多公司的广告特征库都是上亿级别的。
2.DNN
深度神经网络(DNN)近年来在图像、语音、自然语言等领域大放异彩,特别是在图像分类、语音识别、机器翻译方面DNN已经超过人,精度已经达到商业应用程度。不过,DNN在CTR预估这种场景的应用却仍在摸索中。图像、语言、自然语言领域的数据一般是连续的,局部之间存在某些结构。比如,图像的局部与其周围存在着紧密的联系;语音和文字的前后存在强相关性。但是CTR预估的数据如前面介绍,是非常离散的,特征前后之间的关系很多是我们排列的结果,并非本身是相互联系的。
3.Embeding
Neural Network是典型的连续值模型,而CTR预估的输入更多时候是离散特征,因此一个自然的想法就是如何将将离散特征转换为连续特征。如果你对词向量模型熟悉的话,可以发现之间的共通点。在自然语言处理(NLP)中,为了将自然语言交给机器学习中的算法来处理,通常需要首先将语言数学化,词向量就是用来将语言中的词进行数学化的一种方式。
一种最简单的词向量方式是one-hot,但这么做不能很好的刻画词之间的关系(例如相似性),另外数据规模会非常大,带来维度灾难。因此Embeding的方法被提出,基本思路是将词都映射成一个固定长度的向量(向量大小远小于one-hot编码向量大些),向量中元素不再是只有一位是1,而是每一位都有值。将所有词向量放在一起就是一个词向量空间,这样就可以表达词之间的关系,同时达到降维的效果。
既然Embeding可以将离散的词表达成连续值的词向量,那么对于CTR中的类别特征也可以使用Embeding得到连续值向量,再和其他连续值特征构成NN的输入。下图就是这种思路的表达。
因此问题的关键就是采用何种Embeding技术将离线特征转换到离线空间。
3.1 FM Embeding
Factorization Machine是近年来在推荐、CTR预估中常用的一种算法,该算法在LR的基础上考虑交叉项,如下面公式所示:
FM在后半部分的交叉项中为每个特征都分配一个特征向量V,这其实可以看作是一种Embeding的方法。Dr.Zhang在文献[1]中提出一种利用FM得到特征的embeding向量并将其组合成dense real层作为DNN的输入的模型,FNN。FNN模型的具体设计如下:
Dr.Zhang在模型中做了一个假设,就是每个category field只有一个值为1,也就是每个field是个one-hot表达向量。field是指特征的种类,例如将特征occupation one-hot之后是三维向量,但这个向量都属于一个field,就是occupation。这样虽然离散化后的特征有几亿,但是category field一般是几十到几百。 模型得到每个特征的Embeding向量后,将特征归纳到其属于field,得到向量z,z的大小就是1+#fields * #embeding 。z是一个固定长度的向量之后再在上面加入多个隐藏层最终得到FNN模型。
Dr.Zhang在FNN模型的基础上又提出了下面的新模型PNN. PNN和FNN的主要不同在于除了得到z向量,还增加了一个p向量,即Product向量。Product向量由每个category field的feature vector做inner product 或则 outer product 得到,作者认为这样做有助于特征交叉。另外PNN中Embeding层不再由FM生成,可以在整个网络中训练得到。
3.2 NN Embeding
Google团队最近提出Wide and Deep Model。在他们的模型中,Wide Models其实就是LR模型,输入原始的特征和一些交叉组合特征;Deep Models通过Embeding层将稀疏的特征转换为稠密的特征,再使用DNN。最后将两个模型Join得到整个大模型,他们认为模型具有memorization and generalization特性。 Wide and Deep Model中原始特征既可以是category,也可以是continue,这样更符合一般的场景。另外Embeding层是将每个category特征分别映射到embeding size的向量,如他们在TensorFlow代码中所示:
deep_columns = [
tf.contrib.layers.embedding_column(workclass, dimension=8),
tf.contrib.layers.embedding_column(education, dimension=8),
tf.contrib.layers.embedding_column(gender, dimension=8),
tf.contrib.layers.embedding_column(relationship, dimension=8),
tf.contrib.layers.embedding_column(native_country, dimension=8),
tf.contrib.layers.embedding_column(occupation, dimension=8),
age, education_num, capital_gain, capital_loss, hours_per_week]
4.结合图像
目前很多在线广告都是图片形式的,文献[4]提出将图像也做为特征的输入。这样原始特征就分为两类,图像部分使用CNN,非图像部分使用NN处理。 其实这篇文章并没有太多新颖的方法,只能说多了一种特征。对于非图像特征,作者直接使用全连接神经网络,并没有使用Embeding。
5.CNN
CNN用于提取局部特征,在图像、NLP都取得不错的效果,如果在CTR预估中使用却是个难题。我认为最大的困难时如何构建对一个样本构建如图像那样的矩阵,能够具有局部联系和结构。如果不能构造这样的矩阵,使用CNN是没有什么意思的。 文献[5]是发表在CIKM2015的一篇短文,文章提出对使用CNN来进行CTR预估进行了尝试。 一条广告展示(single ad impression)包括:element = (user; query; ad, impression time, site category, device type, etc) 用户是否点击一个广告与用户的历史ad impression有关。这样,一个样本将会是(s, label) ,s由多条l组成(数目不定)
作者提出CCPM模型处理这样的数据。每个样本有n个element,对每个element使用embeding 得到定长为d的向量
,再构造成一个矩阵
,得到s矩阵之后就可以套用CNN,后面的其实没有太多创新点。
6.RNN
考虑搜索场景下的CTR预估,如果考虑历史信息,如可以将一个用户的历史ad impression构成一个时间序列。RNN非常适合时间序列的场景,如语言建模等。这篇 发表在AAAI2014将RNN模型引入CTR预估。作者首先在数据集上验证了用户的点击行为与之前的ad impression历史有关联:
- 如果用户在之前的impression很快离开广告页面,那么将会在接下来一段时间内不会点击类似的广告
- 如果用户最近有过与广告相关的查询,那么接下来点击相关广告的可能性会大幅提升
- 前面的两种行为还可能随着间隔时间的增加而不是那么相关
当前关联不止这些,而且人工难以刻画,需要模型来自动提取。RNN模型对此类问题非常适用,作者的主要工作是将数据集构造成适合RNN的输入(即对用户的历史ad impression根据时间排序),对模型本身并没有改进。
参考文献
- Deep Learning over Multi-field Categorical Data – A Case Study on User Response Prediction
- Product-based Neural Networks for User Response Prediction
- Wide & Deep Learning for Recommender Systems
- Deep CTR Prediction in Display Advertising
- A Convolutional Click Prediction Model
- http://www.52cs.org/?p=1046
- http://techshow.ctrip.com/archives/1149.html
- http://tech.meituan.com/deep-understanding-of-ffm-principles-and-practices.html
- Sequential Click Prediction for Sponsored Search with Recurrent Neural Networks
CNN在NLP的应用--文本分类
刚接触深度学习时知道CNN一般用于计算机视觉,RNN等一般用于自然语言相关。CNN目前在CV领域独领风骚,自然就有想法将CNN迁移到NLP中。但是NLP与CV不太一样,NLP有语言内存的结构,所以最开始CNN在NLP领域的应用在文本分类。相比于具体的句法分析、语义分析的应用,文本分类不需要精准分析。本文主要介绍最近学习到几个算法,并用mxnet进行了实现,如有错误请大家指出。
1 Convolutional Neural Networks for Sentence Classification
1.1 原理
CNN的输入是矩阵形式,因此首先是构造矩阵。句子有词构成,DL中一般使用词向量,再对句子的长度设置一个固定值(可以是最大长度),那么就可以构造一个矩阵,这样就可以应用CNN了。这篇论文就是这样的思想,如上图所示。
输入层
句子长度为n,词向量的维度为k,那么矩阵就是n∗k。具体的,词向量可以是静态的或者动态的。静态指词向量提取利用word2vec等得到,动态指词向量是在模型整体训练过程中得到。
卷积层
一个卷积层的kernel大小为$hk,k为输入层词向量的维度,那么h为窗口内词的数目。这样可以看做为N−Gram的变种。如此一个卷积操作可以得到一个(n-h+1)1$的feature map。多个卷积操作就可以得到多个这样的feature map
池化层
这里面的池化层比较简单,就是一个Max-over-time Pooling,从前面的1维的feature map中取最大值。这篇文章中给出了NLP中CNN的常用Pooling方法。最终将会得到1维的size=m的向量(m=卷积的数目)
全连接+输出层
模型的输出层就是全连接+Softmax。可以加上通用的Dropout和正则的方法来优化
1.2 实现
这篇文章用TensorFlow实现了这个模型,代码。我参考这个代码用mxnet实现了,代码
2 Character-level Convolutional Networks for Text Classification
2.1 原理
图像的基本都要是像素单元,那么在语言中基本的单元应该是字符。CNN在图像中有效就是从原始特征不断向上提取高阶特征,那么在NLP中可以从字符构造矩阵,再应用CNN来做。这篇论文就是这个思路。
输入层
一个句子构造一个矩阵,句子由字符构成。设定一个句子的字符数目n(论文中n=1014)。每个字符是一个字符向量,这个字符向量可以是one-hot向量,也可以是一个char embeding. 设字符向量为k,那么矩阵为n∗k。
卷积层
这里的卷积层就是套用在图像领域的, 论文中给出具体的设置
全连接+输出层
全连接层的具体设置如下 ![/images/deeplearning/cnn_nlp/model2_fc.png]
2.2 实现
代码给出了TensorFlow的实现,我用mxnet实现的代码
3 Character-Aware Neural Language Models
3.1 原理
这篇文章提出一种CNN+RNN结合的模型。CNN部分,每个单词由character组成,如果对character构造embeding向量,则可以对单词构造矩阵作为CNN的输入。CNN的输出为词向量,作为RNN的输入,RNN的输出则是以整个词为单位。
3.1.1 CNN层
输入层: 一个句子(sentence)是一个输入样本,句子由词(word)构成,词由字符(character)组成。每个字符学习一个embeding字符向量,设字符向量长度为k,那么一个word(长度为w)就可以构造成一个矩阵C(k∗w)
卷积层: 对这个矩阵C使用多个卷积层,每个卷积层的kernel大小为($kn)。卷积层可以看作是character的n−gram,那么每个卷积操作后得到的矩阵为(1(w-n+1)$)
池化层: 池化层仍是max-pooling,挑选出(w−n+1)长度向量中的最大值,将所有池化层的结果拼接就可以得到定长的向量p,p的长度为所有卷积层的数目
Highway层: Highway层是最近刚提出的一种结构,借鉴LSTM的gate概念。x为该层的输入,那么首先计算一个非线性转换T(x),T(x)∈[0,1](T一般为sigmod)。除了T(x),还有另外一个非线性转换H(x),最终的输出为y=T(x)∗H(x)+(1−T(x))∗x。从公式来看,T(x)充当了gate,如果T(x)=1,那么输出同传统的非线性层一样,输出是H(x),如果T(x)=0,则直接输出输入x。作者认为Highway层的引入避免了梯度的快速消失,这种特性可以构建更深的网络。
输出层: 每个单词将得到一个词向量,与一般的词向量获取不同,这里的词向量是DNN在character embeding上得到的。
3.1.2 RNN层
输入层: 将一个句子的每个CNN输出作为词向量,整个句子就是RNN的输入层
隐藏层: 一般使用LSTM,也可以是GRU
输出层: 输出层以word为单位,而不是character.
3.2实现
代码给出了TensorFlow的实现,我的MXNet实现见代码
参考资料
- https://github.com/Lasagne/Lasagne/blob/highway_example/examples/Highway%20Networks.ipynb
- http://www.jeyzhang.com/cnn-apply-on-modelling-sentence.html
- http://www.wildml.com/2015/11/understanding-convolutional-neural-networks-for-nlp/
- http://www.wtoutiao.com/p/H08qKy.html
- http://karpathy.github.io/2015/05/21/rnn-effectiveness/
- https://papers.nips.cc/paper/5782-character-level-convolutional-networks-for-text-classification.pdf
当GridSearch遇上XGBoost 一段代码解决调参问题
写在最前
数据比赛,GBM(Gredient Boosting Machine)少不了,我们最常见的就是XGBoost和LightGBM。
模型是在数据比赛中尤为重要的,但是实际上,在比赛的过程中,大部分朋友在模型上花的时间却是相对较少的,大家都倾向于将宝贵的时间留在特征提取与模型融合这些方面。在实战中,我们会先做一个baseline的demo,尽可能快尽可能多的挖掘出模型的潜力,以便后期将精力花在特征和模型融合上。这里就需要一些调参功底。
本文从这两种模型的一共百余参数中选取重要的十余个进行探讨研究。并给大家展示快速轻量级的调参方式。当然,有更高一步要求的朋友,还是得戳LightGBM和XGBoost这两个官方文档链接。
为了更好的试验,我将预处理后的数据放在百度云上。大家戳链接下载。
XGBoost 的一些重要参数
XGBoost的参数一共分为三类:
- 通用参数:宏观函数控制。
- Booster参数:控制每一步的booster(tree/regression)。booster参数一般可以调控模型的效果和计算代价。我们所说的调参,很这是大程度上都是在调整booster参数。
- 学习目标参数:控制训练目标的表现。我们对于问题的划分主要体现在学习目标参数上。比如我们要做分类还是回归,做二分类还是多分类,这都是目标参数所提供的。
Note: 我下面介绍的参数都是我觉得比较重要的, 完整参数请戳官方文档
通用参数
booster
:我们有两种参数选择,gbtree
和gblinear
。gbtree是采用树的结构来运行数据,而gblinear是基于线性模型。silent
:静默模式,为1
时模型运行不输出。nthread
: 使用线程数,一般我们设置成-1
,使用所有线程。如果有需要,我们设置成多少就是用多少线程。
Booster参数
n_estimator
: 也作num_boosting_rounds
这是生成的最大树的数目,也是最大的迭代次数。
learning_rate
: 有时也叫作eta
,系统默认值为0.3
,。每一步迭代的步长,很重要。太大了运行准确率不高,太小了运行速度慢。我们一般使用比默认值小一点,
0.1
左右就很好。gamma
:系统默认为0
,我们也常用0
。在节点分裂时,只有分裂后损失函数的值下降了,才会分裂这个节点。
gamma
指定了节点分裂所需的最小损失函数下降值。 这个参数的值越大,算法越保守。因为gamma
值越大的时候,损失函数下降更多才可以分裂节点。所以树生成的时候更不容易分裂节点。范围:[0,∞]
subsample
:系统默认为1
。这个参数控制对于每棵树,随机采样的比例。减小这个参数的值,算法会更加保守,避免过拟合。但是,如果这个值设置得过小,它可能会导致欠拟合。 典型值:
0.5-1
,0.5
代表平均采样,防止过拟合. 范围:(0,1]
,注意不可取0colsample_bytree
:系统默认值为1。我们一般设置成0.8左右。用来控制每棵随机采样的列数的占比(每一列是一个特征)。 典型值:
0.5-1
范围:(0,1]
colsample_bylevel
:默认为1,我们也设置为1.这个就相比于前一个更加细致了,它指的是每棵树每次节点分裂的时候列采样的比例
max_depth
: 系统默认值为6
我们常用
3-10
之间的数字。这个值为树的最大深度。这个值是用来控制过拟合的。max_depth
越大,模型学习的更加具体。设置为0
代表没有限制,范围:[0,∞]
max_delta_step
:默认0
,我们常用0
.这个参数限制了每棵树权重改变的最大步长,如果这个参数的值为
0
,则意味着没有约束。如果他被赋予了某一个正值,则是这个算法更加保守。通常,这个参数我们不需要设置,但是当个类别的样本极不平衡的时候,这个参数对逻辑回归优化器是很有帮助的。lambda
:也称reg_lambda
,默认值为0
。权重的L2正则化项。(和Ridge regression类似)。这个参数是用来控制XGBoost的正则化部分的。这个参数在减少过拟合上很有帮助。
alpha
:也称reg_alpha
默认为0
,权重的L1正则化项。(和Lasso regression类似)。 可以应用在很高维度的情况下,使得算法的速度更快。
scale_pos_weight
:默认为1
在各类别样本十分不平衡时,把这个参数设定为一个正值,可以使算法更快收敛。通常可以将其设置为负样本的数目与正样本数目的比值。
学习目标参数
objective [缺省值=reg:linear]
reg:linear
– 线性回归reg:logistic
– 逻辑回归binary:logistic
– 二分类逻辑回归,输出为概率binary:logitraw
– 二分类逻辑回归,输出的结果为wTxcount:poisson
– 计数问题的poisson回归,输出结果为poisson分布。在poisson回归中,max_delta_step的缺省值为0.7 (used to safeguard optimization)multi:softmax
– 设置 XGBoost 使用softmax目标函数做多分类,需要设置参数num_class(类别个数)multi:softprob
– 如同softmax,但是输出结果为ndata*nclass的向量,其中的值是每个数据分为每个类的概率。
eval_metric [缺省值=通过目标函数选择]
rmse
: 均方根误差mae
: 平均绝对值误差logloss
: negative log-likelihooderror
: 二分类错误率。其值通过错误分类数目与全部分类数目比值得到。对于预测,预测值大于0.5被认为是正类,其它归为负类。 error@t: 不同的划分阈值可以通过 ‘t’进行设置merror
: 多分类错误率,计算公式为(wrong cases)/(all cases)mlogloss
: 多分类log损失auc
: 曲线下的面积ndcg
: Normalized Discounted Cumulative Gainmap
: 平均正确率
一般来说,我们都会使用xgboost.train(params, dtrain)
函数来训练我们的模型。这里的params
指的是booster
参数。
两种基本的实例
我们要注意的是,在xgboost中想要进行二分类处理的时候,我们仅仅在 objective
中设置成 binary
,会发现输出仍然是一堆连续的值。这是因为它输出的是模型预测的所有概率中最大的那个值。我们可以后续对这些概率进行条件处理得到最终类别,或者直接调用xgboost
中的XGBClassifier()
类,但这两种函数的写法不太一样。大家看我下面的例子。
from sklearn.model_selection import train_test_splitfrom sklearn.metrics import roc_auc_score
train_data = pd.read_csv('train.csv') # 读取数据y = train_data.pop('30').values # 用pop方式将训练数据中的标签值y取出来,作为训练目标,这里的‘30’是标签的列名
col = train_data.columns
x = train_data[col].values # 剩下的列作为训练数据
train_x, valid_x, train_y, valid_y = train_test_split(x, y, test_size=0.333, random_state=0) # 分训练集和验证集
train = xgb.DMatrix(train_x, train_y)
valid = xgb.DMatrix(valid_x, valid_y) # train函数下需要传入一个Dmatrix值,具体用法如代码所示
'max_depth': 15, 'learning_rate': 0.1, 'n_estimators': 2000, 'min_child_weight': 5, 'max_delta_step': 0, 'subsample': 0.8, 'colsample_bytree': 0.7, 'reg_alpha': 0, 'reg_lambda': 0.4, 'scale_pos_weight': 0.8, 'silent': True, 'objective': 'binary:logistic', 'missing': None, 'eval_metric': 'auc', 'seed': 1440,
} # 这里的params特指booster参数,注意这个eva_metric是评估函数
xlf = xgb.train(params, train, evals=[(valid, 'eval')], num_boost_round=2000, early_stopping_rounds=30, verbose_eval=True)
# 训练,注意验证集的写法, 还有early_stopping写法,这里指的是30轮迭代中效果未增长便停止训练
y_pred = xlf.predict(valid_x, ntree_limit=xlf.best_ntree_limit)
# xgboost没有直接使用效果最好的树作为模型的机制,这里采用最大树深限制的方法,目的是获取刚刚early_stopping效果最好的,实测性能可以
auc_score = roc_auc_score(valid_y, y_pred) # 算一下预测结果的roc值
以上是xgboost.train()
写法,这是xgboost最原始的封装函数。这样训练我们预测输出的是一串连续值,是xgboost在这几个类别上概率最大的概率值。我们如果想要得到我们的分类结果,还需要进行其他操作。
幸运的是,xgboost为了贴合sklearn的使用,比如gridsearch这些实用工具,又开发了XGBoostClassifier()
和XGBoostRegression()
两个函数。可以更加简单快捷的进行分类和回归处理。注意xgboost的sklearn包没有 feature_importance
这个量度,但是get_fscore()
函数有相同的功能。当然,为了和sklearn保持一致,写法也发生变化,具体请看下面代码:
from sklearn.model_selection import train_test_splitfrom sklearn.metrics import roc_auc_score
train_data = pd.read_csv('train.csv') # 读取数据y = train_data.pop('30').values # 用pop方式将训练数据中的标签值y取出来,作为训练目标,这里的‘30’是标签的列名
col = train_data.columns
x = train_data[col].values # 剩下的列作为训练数据
train_x, valid_x, train_y, valid_y = train_test_split(x, y, test_size=0.333, random_state=0) # 分训练集和验证集
xlf = xgb.XGBClassifier(max_depth=10,
objective='binary:logistic',
xlf.fit(train_x, train_y, eval_metric='error', verbose=True, eval_set=[(valid_x, valid_y)], early_stopping_rounds=30)
# 这个verbose主要是调节系统输出的,如果设置成10,便是每迭代10次就有输出。
# 注意我们这里eval_metric=‘error’便是准确率。这里面并没有accuracy命名的函数,网上大多例子为auc,我这里特意放了个error。
y_pred = xlf.predict(valid_x, ntree_limit=xlf.best_ntree_limit)
auc_score = roc_auc_score(valid_y, y_pred)
y_pred = xlf.predict(valid_x, ntree_limit=xlf.best_ntree_limit)
# xgboost没有直接使用效果最好的树作为模型的机制,这里采用最大树深限制的方法,目的是获取刚刚early_stopping效果最好的,实测性能可以
auc_score = roc_auc_score(valid_y, y_pred) # 算一下预测结果的roc值
那么我们介绍了这么多,重点就来了:如何又快又好的调参?首先我们需要了解grid search是个什么原理。
GridSearch 简介
这是一种调参手段;穷举搜索:在所有候选的参数选择中,通过循环遍历,尝试每一种可能性,表现最好的参数就是最终的结果。其原理就像是在数组里找最大值。(为什么叫网格搜索?以有两个参数的模型为例,参数a有3种可能,参数b有4种可能,把所有可能性列出来,可以表示成一个3*4的表格,其中每个cell就是一个网格,循环过程就像是在每个网格里遍历、搜索,所以叫grid search)
其实这个就跟我们常用的遍历是一样的。建议大家使用sklearn里面的GridSearch函数,简洁速度快。
from sklearn.model_selection import train_test_splitfrom sklearn.metrics import roc_auc_score
train_data = pd.read_csv('train.csv') # 读取数据y = train_data.pop('30').values # 用pop方式将训练数据中的标签值y取出来,作为训练目标,这里的‘30’是标签的列名
col = train_data.columns
x = train_data[col].values # 剩下的列作为训练数据
train_x, valid_x, train_y, valid_y = train_test_split(x, y, test_size=0.333, random_state=0) # 分训练集和验证集
'max_depth': [5, 10, 15, 20, 25], 'learning_rate': [0.01, 0.02, 0.05, 0.1, 0.15], 'n_estimators': [500, 1000, 2000, 3000, 5000], 'min_child_weight': [0, 2, 5, 10, 20], 'max_delta_step': [0, 0.2, 0.6, 1, 2], 'subsample': [0.6, 0.7, 0.8, 0.85, 0.95], 'colsample_bytree': [0.5, 0.6, 0.7, 0.8, 0.9], 'reg_alpha': [0, 0.25, 0.5, 0.75, 1], 'reg_lambda': [0.2, 0.4, 0.6, 0.8, 1], 'scale_pos_weight': [0.2, 0.4, 0.6, 0.8, 1]
xlf = xgb.XGBClassifier(max_depth=10,
objective='binary:logistic',
# 有了gridsearch我们便不需要fit函数
gsearch = GridSearchCV(xlf, param_grid=parameters, scoring='accuracy', cv=3)
gsearch.fit(train_x, train_y)
print("Best score: %0.3f" % gsearch.best_score_)print("Best parameters set:")
best_parameters = gsearch.best_estimator_.get_params()
for param_name in sorted(parameters.keys()): print("\t%s: %r" % (param_name, best_parameters[param_name]))
我们需要注意的是,Grid Search 需要交叉验证支持的。这里的cv=3
,是个int数,就代表3-折验证。实际上cv可以是一个对象,也可以是其他类型。分别代表不同的方式验证。具体的大家可看下面这段表述。
Possible inputs for cv are: - None, to use the default 3-fold cross-validation, - integer, to specify the number of folds. - An object to be used as a cross-validation generator. - An iterable yielding train/test splits.