介绍一下项目(Why、What、How)
- 由百度和中央网信办举办的面向观点型问题的机器阅读理解大赛(https://aistudio.baidu.com/cailktc.html),针对用户输入的观点型问题与搜索引擎给出的相关答案摘要,模型给出答案摘要所包含的是非观点极性。
- 我作为项目参与者,首先做了数据分析和预处理,针对训练集和测试集长度分布不均衡,使用下采样方法进行调整。
- 其次是调研并实现了一些数据增强方法,比如回译法、UDA、EDA
- 在训练基分类器上,利用paddle paddle平台搭建BERT和ERNIE2.0模型进行参数调优,基于对抗训练思想在word embedding层添加扰动, 提高模型鲁棒性。
- 模型最后的集成上,使用stacking方法结合GBDT对基模型(BERT、RoBERTa-base、RoBERTa-large、ERNIE、ERNIE2.0)进行集成并使用GridSearch CV对GBDT进行参数寻优。
对于这个项目,传统的方法是怎么样的?
- 尝试了TextCNN方法,效果很差,在验证集上只有60%准确率,数据中有很多隐晦的需要理解的东西
尝试了什么方法(失败的)?
- 一开始分析数据,发现有些观点极性数据含有关键词如对、不是、不一定等,于是考虑换一个简单的容易提取特征的分类器比如TextCNN,效果很不理想,发现大部分数据观点极性是隐性的,需要模型对文本有一个语义上的理解。所以考虑BERT、ERNIE等模型。
- 尝试过引入关键词,做了一个关键词分析工作,首先我们发现模型在Depends上预测的不好,一方面是标注质量的问题,一方面模型在数据理解上不够好,尝试引入关键词如不一定、可能、不见得等,在做关键词分析的时候发现很多Yes、No极性的回答中也含有这些关键词,于是放弃掉这一步。
尝试了什么方法(成功的)?
- 数据增强(回译法、EDA、UDA等, 下面有介绍)
- 数据分析:通过分析训练集与测试集数据,我们发现在数据长度分布上不一致,训练集中有40%长度在20字符以内、20%长度在20-40,20%在40-80之间;测试集中40%在40-80之间,20%在80-150之间、20%大于150。于是我们: ①通过下采样的方式去掉部分训练集中长度小于20、小于40的字段,最终使得分布一致; ②调整模型参数,将max_len设置为320(之前是128),效果提升0.4%
- stacking策略
五个基学习器进行stacking,得到五组预测结果,将五组结果进行拼接。 - 集成学习
尝试了GBDT,效果提升1.6% - 引入对抗学习
为什么要加入对抗训练?
- 我们发现,对于有的句子如雪花秀气垫粉底液效果好吗以及雪花秀气垫粉底液效果差吗,这里好和差在上下文中扮演的角色是相近的,都是形容词,此外上下文语境也相似,因此word embedding有可能相近,但是实际上在是非观点极性分析任务中,这两个是完全相反的,所以我们希望在word embedding上添加额外的扰动,使得好可能变为差,来导致他的预测结果错误,从而导致Loss增大,那么模型就只能通过不断地取修改word embedding从而努力降低Loss,从而提高word embedding质量,提高模型鲁棒性实际效果提升0.4%。
- 为了提高word_embedding的质量,在原Loss中加入一个对word_embedding层的梯度惩罚项。
- 具体公式:
- 核心思想:对bert的词向量添加扰动:可能在nlp领域添加扰动不像在图像上那么直观,所以从本质上我们可以将它看做一个正则化的手段.
- 首先我们去跑前向,得到一个Loss,然后去跑反向,得到它对于word embedding层的梯度,将这个梯度的惩罚项加入到原来的Loss中进行后面的反向传播以及真正的优化。
在数据增强上用了哪些方法?
- 首先用了回译法,通过调用谷歌翻译接口,将中文数据通过中→日→英→中、中→法→德→中的顺序进行回译,基于的理论基础是这几种语言在语法结构上是有差异的,从生成的效果来看,有一部分数据在生成后是脱离原意的,将这部分数据丢弃掉。
- 尝试了EDA、UDA方法进行数据增强:其中EDA是进行随机词替换(用word2vec替换)、UDA是非核心词替换:首先计算每个词的tf-idf值,将一段话中每个词的tf-idf值作为其参考概率,tf-idf小的,替换的概率大;这里替换的方式我利用了Word2vec的most_similar函数,得到待替换词的的近义词,同样最后要进行筛选。
- EDA有几种方法:①同义词替换 ②随机插入 ③随机交换 ④随机删除
- 尝试在原训练集上进行数据增强:原始训练集有三个字段:question、answer、documents、其中documents字段是百度搜索引擎根据问题自动爬取到的相关问题及最佳答案,由于这部分信息未标注、且观点极性没有question、answer明确,我们没有使用。后来尝试做数据增强:提取documents字段中容易引发观点极性解答的问题(比如:问题中包含吗、是不是、好不好等词语的,其最佳答案通常包含观点极性)、将这类问题与答案对进行抽取并筛选作为新的样本集。
- 数据扩充最终使得所以基模型准确率平均提升0.4%
stacking策略是什么?怎么做的?
- 将训练集、验证集融合并shuffle,然后生成五折交叉验证数据集,以单个基模型为例,模型对这五组数据分别训练并预测五次,将五次得到的dev的软标签拼接起来,这样就又得到了最初的shuffle数据。
遇到过哪些问题,怎么解决的?
- 五折交叉验证后,我们五个人的模型结果很低,查了较长时间发现在shuffle过程中出错了,每个人shuffle的结果不一样,虽然设置了相同的seed,但是在百度paddlepaddle平台结果不同。解决方法是本地shuffle然后上传到云端。
- 模型引入对抗学习上:看paddlehub官方手册、分析模型源码,发现模型将计算梯度以及梯度更新放在一步,我们将它拆成两步,然后引入基于字向量的embedding。
你在这个项目中遇到的印象最深刻的问题是什么?
- 数据的分布很重要:训练集的分布要拟合测试集的分布。具体反映到实际业务场景中,可能实际真实用户数据并不多,但是你有大量的相关训练数据,那么将训练数据进行变换使其拟合测试数据很有必要。就比如我们下采样,丢弃了40%训练数据,效果反倒提升了。
- 有时候要适当增加一些噪音:这个可以从两方面来讲,首先我在模型中引入基于l2正则化的对抗学习本身相当于噪声。其次,在训练模型的时候我们有一次,将Roberta模型对训练集进行预测,将与原标签结果不同,同时模型预测软标签大于0.95的800条数据抽出来,默认为是在训练集中标注错误的,将其标签反转(即变成模型预测出的标签),重新放入训练集训练,没想到效果提升了0.3%,更没有想到的是,后期在对这800条数据人为复核时候,发现有2/3其实翻转错了,1/3翻转对了,也就是说我们增加了800 * (1/3)条垃圾数据,效果居然有提升。。。
你认为为什么BERT能达到这么好的效果?
- 相比较word2vec、GloVe等传统的静态嵌入 (embeddings),BERT的表征 (representations) 是根据上下文而随时变化的,即每个输入的字符被表示成一个依赖于在该字符出现位置的特定的上下文的向量。具体表现为,同样的词,在不同的语境位置上的词嵌入也是不同的
- 此外,BERT堆叠了大量Transformer层,具有极强的特征抽取能力,越靠后的BERT层能输出越多的特定上下文表征。
- 其三,BERT在训练时用了极其海量的数据集,以及超大规模GPU集群的并行算力,最终才得到如此好的效果。
BERT的mask是如何实现的?
-
MLM方式(MaskedLM):将完整句子中的部分字mask,预测该mask词(mask 15%的词,这15%中80%被mask,10%不变,10%随机替换为其他词)
MLM -
NSP方式(Next Sentence Prediction):为每个训练前的句子A句和B句,50%的概率B真是A后面的句子,50%的概率B是随机的句子。
NSP
BERT的缺点
- mask更多是用在英文上,因为一个mask单元是一个word,而在中文中,一个mask单元是一个字,针对有两个及两个以上连续字组成的词,随机mask字割裂了连续字之间的相关性,使模型不太容易学习到词的语义信息。主要针对这一短板,因此google此后发表了BERT-WWM,国内的哈工大联合讯飞发表了中文版的BERT-WWM。
- 此外,在中文而言,mask一个字使得模型预测变得容易,因为对于很多中文词,它的字都是成对出现的,比如蝙蝠、蜘蛛,这使得模型很容易做预测,那么模型会更容易学习到一个词共现信息,而不是文本语义
- 在实际任务中,我们发现BERT在某些双重否定句式上表现不佳,如不得不
BERT预训练前期怎么处理
- BERT实际上是一个语言模型。语言模型通常采用大规模、与特定NLP任务无关的文本语料进行训练,其目标是学习语言本身应该是什么样的。BERT模型其预训练过程就是逐渐调整模型参数,使得模型输出的文本语义表示能够刻画语言的本质,便于后续针对具体NLP任务作微调。
-
BERT图解
BERT具体任务fine-tune
- 文本分类
对于文本分类任务,BERT模型在文本前插入一个[CLS]符号,并将该符号对应的输出向量作为整篇文本的语义表示,用于文本分类,如下图所示。
文本分类 - 语句对分类
语句对分类任务:该任务的实际应用场景包括:问答(判断一个问题与一个答案是否匹配)、语句匹配(两句话是否表达同一个意思)等。对于该任务,BERT模型除了添加[CLS]符号并将对应的输出作为文本的语义表示,还对输入的两句话用一个[SEP]符号作分割,并分别对两句话附加两个不同的文本向量以作区分,如下图所示:
语句对分类 -
序列标注任务
该任务的实际应用场景包括:中文分词&新词发现(标注每个字是词的首字、中间字或末字)、答案抽取(答案的起止位置)等。对于该任务,BERT模型利用文本中每个字对应的输出向量对该字进行标注,如下图所示(B、I、E分别表示一个词的第一个字、中间字和最后一个字)。
序列标注任务
Self-attention 原理
- 手写self-attention:
a = tf.matmul(q,k,transpose_b=True)
b = tf.multiply(a ,1/math.sqrt(float(size_per_head)))
c = tf.nn.softmax(b)
d = tf.matmul(c,v)
- 图解Transformer
图示展示了第二个字,即目标字的整个Attention计算流程
Attention机制将目标字作为Query、其上下文的各个字作为Key,并将Query与各个Key的相似性作为权重,把上下文各个字的Value融入目标字的原始Value中。
简单谈一下BERT的三个嵌入层
- 首先,三个层分别是Token Embedding、Segment Embedding、Position Embedding。其中Token Embedding层是要将各个词转换成固定维度的向量。在BERT中,每个词会被转换成768维的向量表示。至于Segment Embeddings,BERT的另一种训练模式是NSP,BERT 能够处理对输入句子对的分类任务。这类任务就像判断两个文本是否是语义相似的。句子对中的两个句子被简单的拼接在一起后送入到模型中。那BERT如何去区分一个句子对中的两个句子呢?答案就是segment embeddings。最后,Position Embedding,由于Transformer无法编码输入序列的顺序性,加入Position Embedding会让BERT理解下面这种情况:I think, therefore I am,第一个I应该和第二个I有不同的向量表示。
谈一下BERT的参数量
- 首先vocab_size = 30522,position_embedding有512,segment_embedding有2(bert只用两个句子),隐藏层维数768,∴embedding参数一共
- 其次,每个Transformer,有12个头,,所以,在对KQV进行线性变换的时候,用到了三个参数W1 W2 W3,其维度均为768 x 64,于是,单个Transformer的单个head参数为,一共12个头
- 12个头concat后又一层线性变换,一个个参数,故最后一个multi-heads参数量:
- 全连接层参数:
全连接层。Bert沿用了惯用的全连接层大小设置,W1,W2分别为与,故一共 - 最后,BERT用了12个Transformer,所以一共词向量参数(包括layernorm) + 12 * (Multi-Heads参数 + 全连接层参数 ),即,一共1.1亿个
- BERT-large参数:BERT-large用了24个Trasformer(Bert12个),隐藏层维度1024(BERT768),16个头(BERT12个),总参数量340M
讲一下BERT和Transformer的输入
- Transformer计算token的位置信息这里使用正弦波↓,类似模拟信号传播周期性变化。这样的循环函数可以一定程度上增加模型的泛化能力。注:Transformer尝试了两种位置嵌入:正余弦波和随机初始化位置嵌入,不过最后实验发现二者性能相似,但是使用正余弦波可以避免后期对参数训练,减少训练量。
- BERT直接训练一个position embedding来保留位置信息,每个位置随机初始化一个向量,加入模型训练,最后就得到一个包含位置信息的embedding,最后这个position embedding和word embedding和segment_embedding的结合方式上,BERT选择直接拼接。
讲一下Transformer,attention,然后attention与self-attention的区别
- Transformer中的K、Q、V是同源的,对于vanilla attention,其实是来自于Encoder-Decoder模型,Q来自于上一层Decoder的输出,K和V来自于Encoder的输出。
- Attention输入Source和输出Target内容是不一样的,比如对于英-中机器翻译来说,Source是英文句子,Target是对应的翻译出的中文句子,Attention发生在Target的元素Query和Source中的所有元素之间。
- Self Attention,指的不是Target和Source之间的Attention机制,而是Source内部元素之间或者Target内部元素之间发生的Attention机制,也可以理解为Target=Source这种特殊情况下的Attention。
- 可以这么认为,在vanilla_attention上,,在self-attention上,
elmo、GPT、bert三者之间有什么区别?
- 特征提取器:elmo采用LSTM进行提取,GPT和bert则采用Transformer进行提取。很多任务表明Transformer特征提取能力强于LSTM,elmo采用1层静态向量+2层LSTM,多层提取能力有限,而GPT和bert中的Transformer可采用多层,并行计算能力强。
关于Transformer
- Transformer中的Self-attention多个头的作用?答:类似于CNN中多个卷积核的作用,使用多头注意力,能从多个不同角度提取特征,提高信息提取的全面性。②此外,当维度dk较小的时候,矩阵乘法与加法效率相近,当dk较大时,矩阵乘法效率不高,所以将其分为数个较小维度的矩阵,
- 为什么在进行softmax之前需要对attention进行scaled(为什么除以dk的平方根)?答:将方差稳定到1,解决梯度消失问题。(向量的点积结果会很大,将softmax函数push到梯度很小的区域,scaled会缓解这种现象。)
- Transformer为什么使用不同的Q、K、V?答:在不同的空间进行投影,提高了表达能力和泛化能力。
- 为什么要在self-attention后添加残差?答: 残差结构能够很好的消除层数加深所带来的信息损失问题。
Transformer比LSTM好在哪里?
- 注意力机制很好地找出了文本序列的语义相关度,在语义层面上,能够提取到更关键的特征,比如理解序列中的指示代词。
- 其次是Transformer的结构优势,没有RNN的梯度消失问题,理论上支持任意长度的文本,用了position embedding(正弦波和余弦波)
介绍一下BERT、RoBERTa、ERNIE、ERNIE2.0、BERT-large的区别
- ERNIE与BERT的区别在于mask机制,首先在输入的时候还是以字为单位,但是在训练的时候Mask机制不是随机mask字,而是mask实体信息和短语信息,此外在训练集的选取上也做了改善,训练语料引入了多源数据知识。除了百科类文章建模,还对新闻资讯类、论坛对话类数据进行学习。因此在中文任务上有更好的效果。
BERT与ERNIE - Roberta与BERT:①训练更长时间 ②删除了next_sentence_prediction任务 ③更大的batch_size,更多的数据 ④使用了全词mask(这一点上有点像ERNIE)
- ERNIE2.0
①采用了多个不同的预训练任务 ②交替式多任务学习,模型既可以学习不同任务级别的信息,又能够减轻遗忘现象。
讲讲xgboost和GBDT
- GBDT(Gradient Boosting)是Boosting的一大类算法,其基本思想是根据当前模型损失函数的负梯度信息来训练新加入的弱分类器, 然后将训练好的弱分类器以累加的形式结合到现有模型中。在每一轮迭代中, 首先计算出当前模型在所有样本上的负梯度, 然后以该值为目标训练一个新的弱分类器进行拟合并计算出该弱分类器的权重, 最终实现对模型的更新。由于需要当前模型的负梯度,所以需要训练一个CART回归树。
- GBDT的优点在于预测阶段的计算速度快, 树与树之间可并行化计算,同时泛化能力和表达能力都很好。采用决策树作为弱分类器使得GBDT模型具有较好的解释性和鲁棒性
- GBDT的缺点在于它的训练是串行的,在做参数寻优或者训练的时候很慢。
- GBDT的每一棵树都是在拟合上一棵树的残差(也就是负梯度,其中梯度是根据损失函数计算的,采用l2损失)
- xgboost是GBDT的优化: ①在决策树构建阶段就引入了优化 ②在使用CART作为基分类器时,XGBoost显式地加入了正则项来控制模型的复杂度,有利于防止过拟合,从而提高模型的泛化能力。 ③不同于GBDT,xgboost支持采用多种基分类器如LR
为什么集成学习基分类器要用决策树?
- 调整树的权重,可以调节模型泛化能力、表达能力
- 决策树对数据样本敏感,数据样本的扰动对决策树的影响较大。基分类器的随机性较大。
- 集成学习希望每个分类器的差异越大越好,这样每个分类器都能表述关于数据的一些不同的信息,然后通过集成,得到一个好的分类结果。所以采用决策树作为基分类器。
关于GBDT,你调整了哪些参数?
- n_estimators:最大的弱学习器的个数,太小容易欠拟合,太大容易过拟合
- learning_rate:每个弱学习器的权重衰减系数
- loss:损失函数,对于分类问题来说有对数似然和指数损失;对于回归问题有均方差、huber损失等。
- max_depth:决策树的最大深度
- min_samples_split:内部节点再划分所需最小样本数
- min_samples_leaf:叶子节点最少样本数
- max_leaf_nodes:最大叶子节点数
- min_impurity_split:节点划分最小不纯度
Xgboost、GBDT、RF区别和联系
- RF基于Bagging策略,采用Bootstrap进行有放回采样。
- 组成RF的可以是分类树,也可以是回归树,而组成GBDT的必须是回归树。
- RF可以并行生成,GBDT只能串行生成
- RF采用多数表决投票,GBDT采用将结果累加。
- RF通过减小方差提高性能,GBDT通过减小偏差提高性能。
- RF的随机性体现在 ①每棵树所分配的训练样本是随机的 ②每个节点的分裂属性集合也是随机选择确定的
你能想到的还可以改进的一些方面
- 其一,充分利用BERT的Transformer层,将12个层的[CLS]输出联合起来,进行一个新的神经网络训练
- 其二,应该尝试其他非同源模型如XLNet、NEZHA等,看到其他队伍有这样做
- 考虑做一个文本纠错工作,github上有一个pycorrector项目,可以对文本进行纠错等任务,可以考虑一下
- 尝试其他的集成学习方法比如xgboost。
项目总结与思考
- 数据分布很重要:长度分布、标签分布、特征分布等等,要尽量符合测试样例(真实样例)
- 适当引入噪声,增加模型鲁棒性
- 合理运用正则化
- SVM线性分类器师兄试了一下,取得了与GBDT相同的效果,复杂的基模型用简单的线性分类器取得了更好的效果。
谈谈你对最新的模型如GPT1.0 2.0 3.0 BERT NEZHA XLNET ERNIE ElMO Roberta等的认识
- word2vec不多讲了
- glove融合了矩阵分解和全局统计信息的优势,统计语料库的词-词之间的共现矩阵,为了减轻计算和存储复杂度,使用了矩阵分解方法,但本质上是基于统计学的,没有使用基于非线性变换的神经网络进行特征提取。
- FastText类似word2vec的CBOW模式,只不过CBOW是一个词的上下窗口词,而FastText是用ngram表示的词向量矩阵,此外,CBOW的层次softmax(Hierarchical Softmax)把树的非叶子节点扔掉了,而FastText把这个利用起来了(但也只是在分类数较多的情况,分类数较少的话没法划分树),CBOW的层次softmax叶子节点是一个个词,而FastText的层次softmax叶子节点是一个个分类类别。此外,关于ngram,ngram和其他词一样,也是随机初始化的一个向量,只不过这个数量太大了,于是初始化了一堆hash向量表,拿这些ngram和hash表进行点积生成一个对应的映射位置,比如hash向量表中有10个向量,那么这些ngram最终会被分配到2^10个格子中的一个,每个格子有自己的初始化向量,作为这个ngram的输入向量。
-
ELMo是基于上下文的词表示模型,能学习到复杂的词语特征和这些特征基于上下文的变化,使用多层双向LSTM(通常是三层)作为特征提取器,与BILSTM的区别在于它的结果不是拼接的(为了防止看见自己的问题出现)联合了前向和后项的极大似然
具体的模型结构如图
ELMo
这里需要注意的是,ELMo的主打思想虽然是解决一词多义问题,但它在训练时的输入仍是固定的embedding,只有在LSTM的最终输出上才是我们最终需要的embedding,并且ELMo用了三组双向LSTM,模型最终对这三组vector训练一个权重。 - EMLo的具体训练方式如下:将ELMO输出的向量映射到 vocab_size的长度,softmax后,取出概率最大的元素对应的下标,作为对下一个字的预测。相当于做一个分类,类别数量是词表大小,类似自回归。ELMO有三层,每一层都有一个输出,将这三层的输出按比例相加后即为所得vector。这个比例是模型学习得到的。得到加权后的向量后,如何使用取决于任务的效果。
- 关于ELMo为什么用两个单向LSTM而不是一个双向LSTM,之前有提过,其实是为了避免看见自己,或者看见答案。
如图所示的正向LSTM,"克"是根据“扑”这个字 和 隐藏向量h2 来预测出来的。h2包含了<start>和打 这两个字的信息,所以预测“克”这个字时,是根据前面所有的字来预测的。
但如果加上反向LSTM呢?
反向的话,“克”就是根据 “扑”和 h1 来预测的,但是 h1 包含了“克”的信息,所以反向的话会导致模型看到答案。 - 至于有读者会问,那么Transformer不也是双向嘛?为啥bert看不到自己?答:因为人家bert用了Mask机制,无论你正向反向,都看不到
- GPT1.0采用Transformer的Decoder作为特征提取器,总共堆叠12个,GPT通过mask得分矩阵避免当前字看到之后所要预测的字,所以GPT是只有正向的,缺失了反向信息。
- 至于XLNet,它结合了BERT与GPT的思想,即采用Transformer做特征提取器,但是用mask得分矩阵的方法来替代[MASK]这个字符。
- 综上,可以看出,如果不考虑训练数据大小的影响,谁更好的解决“如何将双向融入语言模型”这个问题,谁效果就更好。
在Mask的过程中为什么要15% - (10%,10%,80%)
Transformer的Decoder
- Transformer 的Decoder部分和Encoder一样,也是有6层,但是每一个单独的decoder与encoder相比,在self-attention层(decoder层中叫masked self-attention)和全连接网络层之间,多了一层Encoder-Decoder-Attention 层。
-
decoder结构中,第一层是一个multi-head-self-attention层,这个与encoder中的区别是这里是masked-multi-head-self-attention。使用mask的原因是因为在预测句子的时候,当前时刻是无法获取到未来时刻的信息的。
- decoder中的第二层attention层就是一个正常的multi-head attention层。但是这里Q,K,V来源不同。Q来自于上一个decoder的输出,而K,V则来自于encoder的输出。剩下的计算就没有其他的不同了。
-
关于这两个attention层,可以理解为 mask-self-attention是计算当前翻译的内容和已经翻译的前文之间的关系,而encoder-decoder-attention 是计算当前翻译内容和编码的特征向量之间的关系。
最后再经过一个全连接层,输出decoder的结果。
Transformer的self-attention为什么要对点积进行缩放?
- 其实起到了归一化的作用,随着的增大,点积的结果也随之增大,这样会将softmax函数推入梯度非常小的区域,使得收敛困难(可能出现梯度消失的情况) (为了说明点积变大的原因,假设Q和K的分量是具有均值0和方差1的独立随机变量,那么它们的点积,其均值为0,方差为,因此为了抵消这种影响,我们将点积缩放
Transformer的并行体现在哪里
- 首先体现在self-attention层,在self-attention模块,对于某个序列,self-attention模块可以直接计算的点积结果,而RNN系列的模型就必须按照顺序从计算到
- Transformer在feed-faward层是由多个feed-farward network组成的,即每word对应一个,而且是互相独立的。
讲讲Transformer的残差
- Transformer的Encoder的每个结构块用了两次残差:第一次是输入多头前和输入多头后的残差,第二次是输入前馈前和输入前馈后的残差。
- 注意,图中的N,是原论文《Attention is all your need》中的,论文里边Encoder和Decoder各用了6个
GBDT如何防止过拟合?
- 控制决策树的个数
- 随机采样迭代,类bagging方法。经验来说随机采样率f在0.5<=f<=0.8比较合适。即可以帮助避免过拟合又可以提高训练速度。
- 控制叶子节点中的最少样本个数。
- 剪枝
- 降低学习率:GBDT中,学习率本质上是误分类样本的权重
除了stacking,你觉得在集成上还有哪些方法?
- 求平均,这是最基础的
- 投票法
网友评论