【机器学习】推荐系统、机器学习面试题整理

目录:

1、排序模型为什么一般都是从LR到GBDT再到DNN进行迭代的?

LR

GBDT

DNN

2、分类问题为什么大都使用交叉熵作为损失函数而不是MSE?

3、过拟合与欠拟合

过拟合over-fitting

欠拟合under-fitting

如何判断过拟合还是欠拟合

如何防止过拟合

如何解决欠拟合

4、梯度与学习率

什么是梯度?

梯度的几何意义

梯度下降法及相关概念

5、L1正则化、L2正则化

​L1正则化和L2正则化的定义:

​L1正则化和L2正则化的作用:

6、word2vec优化方法的层次softmax和负采样

传统的神经网络语言模型下的CBOW与SkipGram

word2vec为什么使用霍夫曼树

如何用层次softmax计算概率

为什么要用负采样或者层次softmax

Hierarchical Softmax的的缺点及负采样的优势

7、XGBOOST与GBDT

GBDT概述

XGBOOST概述

GBDT的优缺点

XGBOOST对GBDT进行的优化

XGBoost算法主流程

GBDT与XGBOOST的损失函数

为什么xgboost要用泰勒展开,优势在哪里?

8、关于机器学习样本不平衡的问题

欠采样

过采样

欠采样的优点和缺点

过采样的优缺点

缺失值较少的特征处理

9、神经网络不收敛的一些原因及解决方案

1. 忘记对你的数据进行归一化

2. 忘记检查输出结果

3. 没有对数据进行预处理

4. 没有使用任何的正则化方法

5. 使用了一个太大的 batch size

6. 使用一个错误的学习率

7. 在最后一层使用错误的激活函数

8. 网络包含坏的梯度

9. 网络权重没有正确的初始化

10. 使用了一个太深的神经网络

11. 隐藏层神经元数量设置不正确


1、排序模型为什么一般都是从LR到GBDT再到DNN进行迭代的?

在业务开始阶段,数据量和特征量都比较少,通常会采用LR模型。随着算法的迭代,数据量和特征规模越来越多的时候,基于XGBOOST或者LightGBM构建GBDT模型是业务成长期快速拿到收益的好的选择。当数据量越来越大的时候,需要基于DNN的框架来把个性化模型做的更细。

  • LR

在LR里,决策边界函数是线性的。

模型的优点:可以通过模型的权重大小,解释特征的重要性;同时LR支持增量更新;在引入大规模离散特征的情况下,业界在LR时代的经典做法是对LR加L1正则并通过OWLQN或者 Coordinate Descent的方式进行优化,也可以通过FTRL算法让模型稀疏避免过拟合。

模型的缺点:线性决策边界这个假设太强,会让模型的精度受到限制;另外,模型的可扩展性程度低。

  • GBDT

在GBDT中,决策边界是非线性的;模型通过将样本空间分而治之的方式,来提高模型精度。

模型的优点:树模型可以计算每个特征的重要性程度,来获得一些可解释性;同时模型比LR有更高的精度。

模型的缺点:不支持大规模的离散特征,不支持增量更新;模型可扩展性程度低。

我们在酒店推荐场景中,尝试了pointwise loss和pairwise loss,每次尝试都获得了不少的提升。

  • DNN

在DNN中,决策边界是高度非线性的。我们知道计算机通过与或非这种简单的逻辑,可以表达各种复杂的对象:音频,视频,网页等。而DNN每一层网络比与或非更加复杂,DNN通过多层神经元叠加,成为一个万能函数逼近器。在理想情况下,只要有足够的数据量,不论我们实际的决策边界如何复杂,我们都可以通过DNN来表达。

同时DNN,支持增量更新,支持根据业务场景进行灵活定制各种网络结构,支持大规模离散DNN,在离散模型中学习出来的Embedding向量还可以用在向量相似召回里面。正因为有这么多的好处,DNN正在成为业界推荐算法的标配。

这个模型的缺点是:特征经过不同层交叉,交互耦合关系过于复杂,而导致可解释性不好;工程复杂度在我们用不同结构的时候所有不同。


2、分类问题为什么大都使用交叉熵作为损失函数而不是MSE?

假设给定输入为x,label为y,其中y的取值为0或者1,是一个分类问题。我们要训练一个最简单的Logistic Regression来学习一个函数f(x)使得它能较好的拟合label,如下图所示:

【机器学习】推荐系统、机器学习面试题整理_第1张图片

 可知,我们要学的函数为:a(x)=\sigma (w*x+b),目标为使a(x)与label y越逼近越好。

我们可以回忆下交叉熵Loss和均方差Loss定义是什么:

【机器学习】推荐系统、机器学习面试题整理_第2张图片

我们想衡量模型输出a和label y的逼近程度,其实这两个Loss都可以。但是为什么Logistic Regression采用的是交叉熵作为损失函数呢?看下这两个Loss function对w的导数,也就是SGD梯度下降时,w的梯度。

【机器学习】推荐系统、机器学习面试题整理_第3张图片

sigmoid函数\sigma (z)如下图所示,可知的导数sigmoid  {\sigma }'(z)在输出接近 0 和 1 的时候是非常小的,故导致在使用最小均方差Loss时,模型参数w会学习的非常慢。而使用交叉熵Loss则没有这个问题。为了更快的学习速度,分类问题一般采用交叉熵损失函数。

【机器学习】推荐系统、机器学习面试题整理_第4张图片

补充说明:

MSE求w和b的导数分别为:

【机器学习】推荐系统、机器学习面试题整理_第5张图片

从以上公式可以看出,w和b的梯度跟激活函数的梯度成正比,激活函数的梯度越大,w和b的大小调整得越快,训练收敛得就越快。

【机器学习】推荐系统、机器学习面试题整理_第6张图片

在上图的绿色部分,初始值是0.98,红色部分初始值是0.82,假如真实值是0。直观来看那么0.82下降的速度明显高于0.98,但是明明0.98的误差更大,这就导致了神经网络不能像人一样,误差越大,学习的越快。也就是说,MSE损失函数并不是误差越大学习的越快

反观交叉熵:

【机器学习】推荐系统、机器学习面试题整理_第7张图片

可以看出梯度中不再含有sigmoid的导数,有的是sigmoid的值和实际值之间的差,也就满足了我们之前所说的错误越大,下降的越快。也就是说,交叉熵损失函数能够做到误差越大,下降的越快。

总结:

  • 神经网络中如果预测值与实际值的误差越大,那么在反向传播训练的过程中,各种参数调整的幅度就要更大,从而使训练更快收敛,如果预测值与实际值的误差小,各种参数调整的幅度就要小,从而减少震荡。
  • 使用平方误差损失函数,误差增大参数的梯度会增大,但是当误差很大时,参数的梯度就会又减小了。
  • 使用交叉熵损失是函数,误差越大参数的梯度也越大,能够快速收敛。

为什么分类问题的损失函数采用交叉熵而不是均方误差MSE?

知乎:简单的交叉熵,你真的懂了吗?

CSDN:分类问题为什么要使用交叉熵损失函数而不是均方误差


3、过拟合与欠拟合

什么是拟合?拟合是指你逼近目标函数的远近程度。机器学习中的拟合,可以分为过拟合和欠拟合两种。

图1(回归问题的三种拟合状态):欠拟合--正常拟合--过拟合

【机器学习】推荐系统、机器学习面试题整理_第8张图片

  • 过拟合over-fitting

所谓过拟合,其实就是训练的模型在训练样本中表现得过于优越,近乎完美的预测/区分了所有的数据,但是在验证数据集以及测试数据集中表现不佳。在性能的角度上讲,过拟合就是协方差过大(variance is large),同样在测试集上的损失函数(cost function)会表现得很大。

过拟合会使模型变得复杂,并尽可能拟合训练集,造成在训练集上的准确率特别高,这里就会有一个问题就是:训练集是不靠谱的,其中有容错的数据。直接点,训练集中特别是十几万的数据,会有脏数据,这些脏数据也成为负样本,会造成模型训练有误差,模型在训练的时候并不清楚那些是脏数据,它只会不停的去拟合这些数据,所以过拟合的模型在训练集上准确率特别高,但训练集其实只是整个数据集中的一部分,其包含两部分特征,一部分是整个数据集共有的特征,一部分是训练集自身共有的特征,当过拟合时,模型学到的是这两部分的特征,此时拿模型去在测试集上测试时,因为测试集不包含训练集自身共有的特征,所以测试集在模型上就不会取得很好的效果。

  • 欠拟合under-fitting

相对于过拟合,欠拟合稍微比较和理解一些。所谓欠拟合,其实就是模型的拟合程度不够,泛化性能差,在训练集上表现效果差,没有充分的利用数据,预测的准确度低。欠拟合在训练集上的准确率不高,同时在测试集上的准确率也不高,这样如何训练出来的模型也得不到较好的效果。

  • 如何判断过拟合还是欠拟合

可以通过绘制损失函数随数据集增加的学习曲线来判断过拟合还是欠拟合。

模型欠拟合(高偏差),是指拥有足够的训练样本时,训练误差和测试误差都很高,并且训练误差约等于测试误差。

模型过拟合(高方差),是指随着训练样本的增加,训练误差在增加,测试误差在减少,但训练误差远远小于测试误差。

注:准备几个不同时间窗口、不同范围的训练集和测试集,然后在不同数据集里分别对模型进行交叉验证,这是工业界判断模型欠拟合或过拟合的最常用方法。

  • 如何防止过拟合

过拟合问题的根本原因是特征维度过多,导致拟合的函数完美的经过训练集,但是对新数据的预测结果则较差。

解决过拟合的方法:

  1. 减少特征维度,可以人工选择保留的特征,或者模型选择算法。
  2. 正则化:正则化是指在优化目标函数或代价函数是,在目标函数后面加上一个正则项。通过正则项来影响模型的复杂度。
  3. 数据集扩增:即需要得到更多的符合要求的数据,让训练集中的噪音数据占比越来越小,这样噪音对模型的影响就较小,可以防止模型过拟合。
  4. 模型选择:挑选相对简单的模型进行训练,对模型中的参数、训练层数等做限制。
  5. Dropout:在神经网络的训练过程中,对于神经单元按一定的概率将其随机从网络中丢弃,从而达到对于每个mini-batch都是在训练不同网络的效果,防止过拟合。

深度学习防止过拟合的几种方法

  • 如何解决欠拟合

欠拟合的问题比较好理解,根本的原因是特征维度过少,导致拟合的函数无法满足训练集,误差较大。

解决欠拟合的方法:

  1. 增加训练数据:让模型学习的更充分一些。
  2. 增加特征维度:即添加新特征,从业务思路上构造新特征是最重要的优化措施。优化算法:提升模型复杂度。

4、梯度与学习率

  • 什么是梯度?

梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)。简单的说,梯度不是一个实数,而是一个向量,即有大小又有方向。

在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式表示出来,就是梯度。比如函数f(x,y), 分别对x,y求偏导数,求得的梯度向量就是(∂f/∂x, ∂f/∂y)T。对于在点(x0,y0)的具体梯度向量就是(∂f/∂x0, ∂f/∂y0)T,或者▽f(x0,y0)。如果是3个参数的向量梯度,就是(∂f/∂x, ∂f/∂y,∂f/∂z)T,以此类推。

  • 梯度的几何意义

梯度向量的意义从几何意义上讲,就是函数变化增加最快的地方。具体来说,对于函数f(x,y),在点(x0,y0),沿着梯度向量的方向就是(∂f/∂x0, ∂f/∂y0)T的方向是f(x,y)增加最快的地方。或者说,沿着梯度向量的方向,更加容易找到函数的最大值。反过来说,沿着梯度向量相反的方向,也就是 -(∂f/∂x0, ∂f/∂y0)T的方向,梯度减少最快,也就是更加容易找到函数的最小值。

  • 梯度下降法及相关概念

在机器学习算法中,在最小化损失函数时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数,和模型参数值。反过来,如果我们需要求解损失函数的最大值,这时就需要用梯度上升法来迭代了。

梯度下降法和梯度上升法是可以互相转化的。比如我们需要求解损失函数f(θ)的最小值,这时我们需要用梯度下降法来迭L1正则化、L2正则化 梯度与学习率代求解。但是实际上,我们可以反过来求解损失函数 -f(θ)的最大值,这时梯度上升法就派上用场了。

监督式学习通过定义一个模型,并根据训练集上的数据估计最优参数。梯度下降法是一个广泛被用来最小化模型误差的参数优化算法。梯度下降法通过多次迭代,并在每一步中最小化成本函数(cost function)来估计模型的参数(weights)。

步长(Learning rate):步长也叫学习率,决定了在梯度下降迭代的过程中,每一步沿梯度负方向前进的长度。学习率决定了参数移动到最优值的速度快慢。如果学习率过大,那么参数更新的幅度就非常大,很可能会越过最优值,导致网络收敛到局部最优点;如果学习率过小,会导致网络loss下降非常慢,优化的效率可能过低,长时间算法无法收敛。

学习率的选择策略在网络的训练过程中是不断在变化的,在刚开始的时候,参数比较随机,所以我们应该选择相对较大的学习率,这样loss下降更快;当训练一段时间之后,参数的更新就应该有更小的幅度,所以学习率一般会做衰减,衰减的方式也非常多,比如到一定的步数将学习率乘上0.1,也有指数衰减等。

梯度下降算法中使用学习率更新参数向量:

\theta =\theta -\eta \cdot \frac{\partial L(\theta )}{\partial \theta }

特征(feature):特征指的是样本中输入部分,与特征对应的是样本的label,以二分类为例,正样本label=1,负样本label=0。

假设函数(hypothesis function):在监督学习中,为了拟合输入样本,而使用的假设函数,记为ℎ?(?)。比如对于单个特征的m个样本(?(?),?(?))(?=1,2,...?),可以采用拟合函数如下: ℎ?(?)=?0+?1?hθ(x)=θ0+θ1x。

损失函数(loss function):为了评估模型拟合的好坏,通常用损失函数来度量拟合的程度。损失函数极小化,意味着拟合程度最好,对应的模型参数即为最优参数。

关于梯度下降法的具体细节,可以参考这篇博客:梯度下降小结


5、L1正则化、L2正则化

机器学习中几乎都可以看到损失函数后面会添加一个额外项,常用的额外项一般有两种,一般英文称作ℓ1-norm和ℓ2-norm,中文称作L1正则化和L2正则化,或者L1范数和L2范数。

L1正则化和L2正则化可以看做是损失函数的惩罚项。所谓『惩罚』是指对损失函数中的某些参数做一些限制。对于线性回归模型,使用L1正则化的模型建叫做Lasso回归,使用L2正则化的模型叫做Ridge回归(岭回归)。

  • L1正则化和L2正则化的定义:

假设w表示特征的系数:

L1正则化是指权值向量w中各个元素的绝对值之和,通常表示为\left \|w \right \|_{1}
​L2正则化是指权值向量w中各个元素的平方和然后再求平方根,通常表示为\left \|w \right \|_{2}

  • L1正则化和L2正则化的作用:

L1正则化可以产生稀疏权值矩阵,即产生一个稀疏模型,可以用于特征选择。

L2正则化可以防止模型过拟合(overfitting);一定程度上,L1也可以防止过拟合。

机器学习中正则化项L1和L2的直观理解


6、word2vec优化方法的层次softmax和负采样

  • 传统的神经网络语言模型下的CBOW与SkipGram

【机器学习】推荐系统、机器学习面试题整理_第9张图片

以上图为例进行说明。

CBOW:根据上下文预测中心词。

假设CBOW的输入是8个词向量,输出是所有词的softmax概率(训练的目标是期望训练样本特定词对应的softmax概率最大),对应的CBOW神经网络模型输入层有8个神经元,输出层有词汇表大小个神经元。隐藏层的神经元个数我们可以自己指定。通过DNN的反向传播算法,我们可以求出DNN模型的参数,同时得到所有的词对应的词向量。这样当我们有新的需求,要求出某8个词对应的最可能的输出中心词时,我们可以通过一次DNN前向传播算法并通过softmax激活函数找到概率最大的词对应的神经元即可。

SkipGram:根据中心词预测上下文。

SkipGram模型和CBOW的思路是反着来的,即输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量。还是上面的例子,我们的上下文大小取值为4, 特定的这个词"Learning"是我们的输入,而这8个上下文词是我们的输出。

SkipGram的输入是特定词, 输出是softmax概率排前8的8个词,对应的SkipGram神经网络模型输入层有1个神经元,输出层有词汇表大小个神经元。隐藏层的神经元个数我们可以自己指定。通过DNN的反向传播算法,我们可以求出DNN模型的参数,同时得到所有的词对应的词向量。这样当我们有新的需求,要求出某1个词对应的最可能的8个上下文词时,我们可以通过一次DNN前向传播算法得到概率大小排前8的softmax概率对应的神经元所对应的词即可。

以上就是神经网络语言模型中如何用CBOW与SkipGram来训练模型与得到词向量的大概过程。但是这和word2vec中用CBOW与SkipGram来训练模型与得到词向量的过程有很多的不同。由于神经网络语言模型的输出层需要进行softmax计算各个词的输出概率的的计算量很大,所以word2vec在此进行了优化。

一句话简述传统的神经网络方法得到词向量的语言模型存在的问题:从隐藏层到输出的softmax层的计算量很大,因为要计算所有词的softmax概率,再去找概率最大的值。word2vec使用层次softmax和负采样两种方法解决这个问题。

  • word2vec为什么使用霍夫曼树

word2vec的优化使用的数据结构是用霍夫曼树来代替隐藏层和输出层的神经元,霍夫曼树的叶子节点起到输出层神经元的作用,叶子节点的个数即为词汇表的小大。 而内部节点则起到隐藏层神经元的作用。

霍夫曼树的好处:一般得到霍夫曼树后我们会对叶子节点进行霍夫曼编码,由于权重高的叶子节点越靠近根节点,而权重低的叶子节点会远离根节点,这样我们的高权重节点编码值较短,而低权重值编码值较长。这保证的树的带权路径最短,也符合我们的信息论,即我们希望越常用的词拥有更短的编码。对于一个霍夫曼树的节点(根节点除外),可以约定左子树编码为0,右子树编码为1。但是,在word2vec中,约定编码方式和上面的例子相反,word2vec约定左子树编码为1,右子树编码为0,同时约定左子树的权重不小于右子树的权重。

word2vec对传统神经网络语言模型的改进:从隐藏层到输出的softmax层这里的计算量进行了改进。为了避免要计算所有词的softmax概率,word2vec采样了霍夫曼树来代替从隐藏层到输出softmax层的映射。

和之前的神经网络语言模型相比,霍夫曼树的所有内部节点就类似之前神经网络隐藏层的神经元。其中,根节点的词向量对应我们的投影后的词向量,而所有叶子节点就类似于之前神经网络softmax输出层的神经元,叶子节点的个数就是词汇表的大小。在霍夫曼树中,隐藏层到输出层的softmax映射不是一下子完成的,而是沿着霍夫曼树一步步完成的,因此这种softmax取名为"Hierarchical Softmax"。

层次softmax对输出层进行优化的策略,输出层从原始模型利用softmax计算概率值改为利用Huffman树计算概率值。

使用霍夫曼树有什么好处呢?首先,由于是二叉树,之前计算量为,现在变成了2。第二,由于使用霍夫曼树是高频的词靠近树根,这样高频词需要更少的时间会被找到,这符合我们的贪心优化思想。

  • 如何用层次softmax计算概率

根据单词出现频率构建好的huffman树,沿着路径从根节点到对应的叶子节点,一层一层的利用sigmoid函数做二分类,判断向左还是向右走,规定沿着左子树走,那么就是负类(霍夫曼树编码1),沿着右子树走,那么就是正类(霍夫曼树编码0)。一路上的概率连乘,最终得到某个单词的输出概率。

  • 为什么要用负采样或者层次softmax

最大的问题在于从隐藏层到输出softmax层的计算量很大,因为要计算所有词的softmax概率,再去找概率最大的值作为当前输入的网络输出。并且在隐层到输出层的权重更新时,每一个样本迭代时,都会更新矩阵的所有元素。可以看softmax的计算公式, f(x) = e^x / sum( e^x_i ) ,需要对所有的词e^x求和,复杂度O(V)。当V非常大的时候,计算量庞大。

  • Hierarchical Softmax的的缺点及负采样的优势

使用霍夫曼树来代替传统的神经网络,可以提高模型训练的效率。但是如果我们的训练样本里的中心词是一个很生僻的词,那么就得在霍夫曼树中辛苦的向下走很久了。

也就是说,分层softmax在每次循环迭代过程中依然要处理大量节点上的更新运算,而负采样技术只需更新“输出向量”的一部分。

负抽样的目的是为了最终输出的上下文单词(正样本)在采样过程中应该保留下来并更新,同时也需要采集部分负样本(非上下文单词)。通过负采样,在更新隐层到输出层的权重时,只需更负采样的单词,而不用更新词汇表所有单词,从而节省巨大计算量。


7、XGBOOST与GBDT

  • GBDT概述

GBDT使用了前向分布算法进行迭代,弱学习器限定了只能使用CART回归树模型。

在GBDT的迭代中,假设我们前一轮迭代得到的强学习器是f_{t-1}(x),损失函数是(, −1()),我们本轮迭代的目标是找到一个CART回归树模型的弱学习器ℎ(),让本轮的损失函数(,())=(,−1()+ℎ())最小。也就是说,本轮迭代是为了找到一棵CART决策树,要让样本的损失尽量变得更小。GBDT用损失函数的负梯度来拟合本轮损失的近似值,进而拟合一个CART回归树。不难,基本就是

  • XGBOOST概述

XGBoost的核心算法思想

  1. 不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数f(x),去拟合上次预测的残差。
  2. 当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数
  3. 最后只需要将每棵树对应的分数加起来就是该样本的预测值。
  • GBDT的优缺点

GBDT主要的优点有:

  1. 可以灵活处理各种类型的数据,包括连续值和离散值。
  2. 在相对少的调参时间情况下,预测的准确率也可以比较高。这个是相对SVM来说的。
  3. 使用一些健壮的损失函数,对异常值的鲁棒性非常强。比如 Huber损失函数和Quantile损失函数。

GBDT的主要缺点有:

  1. 由于弱学习器之间存在依赖关系,难以并行训练数据。不过可以通过自采样的SGBT来达到部分并行。
  2. 在高维稀疏数据上,表现不如SVM或神经网络。
  3. 在处理文本分类特征问题上,相对其他模型优势不如在处理数值特征时明显。
  4. 训练过程需要串行,只能在决策树内部采用一些局部并行手段提高训练速度。
  • XGBOOST对GBDT进行的优化

算法本身的优化:

  1. 在算法的弱学习器模型选择上,对比GBDT只支持决策树,XGBOOST还可以直接很多其他的弱学习器。
  2. 在算法的损失函数上,除了本身的损失,还加上了正则化部分。
  3. 在算法的优化方式上,GBDT的损失函数只对误差部分做负梯度(一阶泰勒)展开,而XGBoost损失函数对误差部分做二阶泰勒展开,更加准确。

算法运行效率的优化:对每个弱学习器,比如决策树建立的过程做并行选择,找到合适的子树分裂特征和特征值。在并行选择之前,先对所有的特征的值进行排序分组,方便前面说的并行选择。对分组的特征,选择合适的分组大小,使用CPU缓存进行读取加速。将各个分组保存到多个硬盘以提高IO速度。

算法健壮性的优化:对于缺失值的特征,通过枚举所有缺失值在当前节点是进入左子树还是右子树来决定缺失值的处理方式。算法本身加入了L1和L2正则化项,可以防止过拟合,泛化能力更强。

  • XGBoost算法主流程

【机器学习】推荐系统、机器学习面试题整理_第10张图片

  • GBDT与XGBOOST的损失函数

GBDT损失函数的损失函数一般可以表示为如下形式:(, −1()+ℎ())。youquedian

对于分类算法,GBDT的损失函数一般有对数损失函数和指数损失函数两种:

  1. 对数损失:(, ())=(−())
  2. 指数损失:youquedian

对于回归算法,常用损失函数有如下4种:

  1. 均方差:(, ())=(−())2
  2. 绝对损失:(, ())=|−()|
  3. Huber损失:
  4. 分位数损失:

XGBOOST的损失函数是在GBDT损失函数(, −1()+ℎ())的基础上,加入了正则化项如下:

最终XGBoost的损失函数可以表达为:

最终损失函数的形式可以表示为:

  • 为什么xgboost要用泰勒展开,优势在哪里?

xgboost使用了一阶和二阶偏导,二阶导数有利于梯度下降的更快更准。使用泰勒展开取得函数做自变量得二阶导数形式,可以在不选定损失函数具体形式的情况下,仅仅依靠输入数据的值就可以进行叶子分裂优化计算,本质上也就把损失函数的选取和模型算法优化/参数选择分开了,这种去耦合增加了xgboost的适用性,使得它按需选取损失函数,可以用于分类,也可以用于回归。

梯度提升树(GBDT)原理小结

XGBoost算法原理小结


8、关于机器学习样本不平衡的问题

在许多情况下,机器学习、深度学习都面临着样本不平衡的问题。

举一个简单但真实的例子:你正在训练你的深层网络,出于安全原因,预测视频中的某人是否持有致命武器。但是在你的训练数据中,你只有50个持有武器的人的视频,1000个没有武器的人的视频。如果你直接使用这些数据来训练你的网络,那么你的模型肯定会偏向于预测没有人拥有武器。

你可以做一些事情来解决这个问题:

在loss函数中使用class weights。本质上,未充分表示的类在loss函数中获得更高的权重,因此对特定类的任何分类错误都会导致loss函数中出现非常高的错误。

  • 样本过采样:重复一些包含代表性不足的类的训练示例,有助于平衡分布。如果可用数据很小,那么这种方法最有效。
  • 样本欠采样:你可以简单地跳过一些包含过度表示类的训练示例。如果可用数据非常大,那么这种方法最有效。
  • 数据增强:对于少数类,你可以为代表性不足的类综合创建更多的训练样本!例如,在上一个检测致命武器的例子中,你可以更改属于拥有致命武器类的视频的一些颜色和灯光
  • 欠采样

欠采样是通过减少丰富类的大小来平衡数据集,当数据量足够时就该使用此方法。通过保存所有稀有类样本,并在丰富类别中随机选择与稀有类别样本相等数量的样本,可以检索平衡的新数据集以进一步建模。

  • 过采样

相反,当数据量不足时就应该使用过采样,它尝试通过增加稀有样本的数量来平衡数据集,而不是去除丰富类别的样本的数量。通过使用重复、自举或合成少数类过采样等方法(SMOTE)来生成新的稀有样品。

  • 欠采样的优点和缺点

优点:

  1. 当训练数据集很大时,它可以通过减少训练数据样本的数量来帮助改善运行时间和存储问题。

缺点:

  1. 它可以丢弃可能有用的信息,这对于构建规则分类器可能很重要。
  2. 通过随机欠采样选择的样本可能是有偏差的样本。可能导致实际测试数据集的结果不准确。
  • 过采样的优缺点

优点:

  1. 与欠采样不同,此方法不会导致信息丢失。
  2. 在抽样条件下表现更佳

缺点:

  1. 由于它复制了少数群体事件,因此增加了过度拟合的可能性。
  • 缺失值较少的特征处理

特征缺失值都在10%以内,我们可以采取很多的方式来处理:

  1. 用均值填充
  2. 用上下行数据进行填充
  3. 用插值法填充
  4. 用算法拟合进行填充

9、神经网络不收敛的一些原因及解决方案

模型不收敛并不一定表示模型是无效的,模型不收敛的原因有很多,常见原因如下:

这里给出11个可能的原因,具体的细节问题可参考:

My Neural Network isn't working! What should I do?

1. 忘记对你的数据进行归一化

我们需要对数据进行归一化操作的原因,主要是我们一般假设输入和输出数据都是服从均值为 0,标准差为 1 的正态分布。这种假设在深度学习理论中非常常见,从权重初始化,到激活函数,再到对训练网络的优化算法。

2. 忘记检查输出结果

当你开始训练你的网络几个 epoch 后,发现误差在减小了。这表示成功训练网络了吗?很不幸这并不是,这说明你的代码中很可能还有一些问题,可能是在数据预处理、训练代码或者推理部分有问题。仅仅因为误差在减小并不意味着你的网络正在学习有用的信息。

与传统编程不同,机器学习系统几乎在所有情况下都会悄无声息地失败。在传统的编程中,我们习惯于电脑在出现问题时抛出一个错误,并以此作为返回和检查错误的信号。

不幸的是在机器学习中并不是这样的机制,所以我们应该非常小心检查的通过人眼来观察每个阶段的处理过程,这样当一个错误已经产生的时候,我们可以及时发现并且可以更彻底的检查代码。

3. 没有对数据进行预处理

神经网络只对它们作为输入的数据做出几个基本假设,但这些基本假设之一是数据所处的空间有些连续性,对于大多数空间来说,两个数据点之间的点至少在某种程度上是这两个数据点的"混合",而附近的两个数据点在某种程度上代表着"类似"的东西。数据空间中出现大的不连续性,或者代表同一事物的大组分离数据,将使学习任务更加困难。

4. 没有使用任何的正则化方法

正则化是现在训练神经网络一个非常重要的方法,通常是以 dropout、噪音或者其他某种随机过程的形式来加入到网络中。

即便数据维度比参数更多,或者是在某种情况下不需要在意过拟合或者不可能出现过拟合,加入 dropout 或者某些形式的噪音仍然是很有帮助的。

正则化方法不仅仅是用于控制过拟合,通过在训练过程中引入一些随机过程,在某种程度上是"平滑"了成本格局。这可以加快训练收敛的速度,帮助处理数据中的噪声或异常值,并防止网络的极端权值配置。

5. 使用了一个太大的 batch size

使用一个太大的 batch size 会因为降低了梯度下降的随机性,导致降低了网络的准确率。

使用较小的batch大小会产生波动更大,更随机的权值更新。这有两个好处:

  • 首先,在训练的时候它可以有助于"跳"出以前可能会陷入的局部最小值;
  • 其次,它可以让训练进入到极小值中,这表示其有更好的泛化性能。

6. 使用一个错误的学习率

许多深度学习框架在默认情况下启用梯度裁剪。这个操作是通过在训练中的每一步中改变一个最大数量的权值来防止出现梯度爆炸的情况。

这可能很有用,特别是当你的数据包含许多异常值,这会产生很大的误差,从而产生很大的梯度和权重更新,但默认设置也会使手工找到最佳学习率变得非常困难。我发现大多数刚接触深度学习的人都将学习速率设置得过高,并通过梯度裁剪来解释这一点,使整体训练速度变慢,并且改变学习率的效果不可预测。

7. 在最后一层使用错误的激活函数

在最后一层使用激活函数有时候会导致网络不能生成要求数值的完整范围,比如最常见的错误就是在最后一层采用 ReLU ,它会导致网络只能输出正数。

想想你的数据值实际代表什么,以及标准化后其范围是什么。最有可能的情况是,你的输出值是无限的正数或负数,在这种情况下,不应该在最后一层使用激活功能。如果输出值可能只在某个范围内有意义,例如它由范围 0-1 中的概率组成,则很可能在最后一层(如 sigmoid 激活功能)上应使用特定的激活功能。

8. 网络包含坏的梯度

使用 ReLU激活函数的神经网络经常会遇到一些因为坏的梯度导致的“死亡神经元”的情况。它会导致网络性能下降,甚至某些情况下导致网络无法继续训练。

对于 ReLU 激活函数来说,其梯度对于正数和负数分别是 1 和 0。这是因为输入的微小更改不会影响小于零的输入输出。这对于正数的大梯度来说似乎不是一个问题,但与许多网络层堆叠在一起,负权重能够将大的正值与强梯度变成负值与零梯度,通常情况下,如果无论输入是什么,网络中有一部分或者所有的权值对于损失函数的梯度都是,这种情况就是网络是死了,权值是没办法更新,也就是无法继续训练下去了。

9. 网络权重没有正确的初始化

如果你不能正确初始化你的神经网络的权值,那么你的神经网络就不太可能进行训练。神经网络中的许多其他组件假定某种形式的正确或标准化的权值初始化,并将权值设置为零,一般使用自己的自定义随机初始化是行不通的。

可能你听说过可以使用“小的随机的数值”来初始化网络的权值,但并没有这么简单。常用的“he”,“xaiver”和“lecun”等权值初始化方式都是使用了很复杂和详细的数学公式并证明了它们为什么是最优的方法。更重要的是,其他的神经网络组件经常是围绕着这些初始化方式建立并根据经验来测试它们,因此如果使用自定义的初始化方式会增加了复现其他研究者成果的难度。

10. 使用了一个太深的神经网络

网络是越深越好吗?实际上并总是这样的,越深越好一般是在做基准实验或者是希望在某些任务上尝试增加 1%甚至更多的准确率,但是如果 3,4,5 层的网络都学不到任何东西,那么使用 100+的网络层也会同样失败, 甚至更加糟糕。

虽然看起来是这样,但神经网络并不是在某人决定堆叠数百层的时候就突然开始获得突破性的结果的。过去十年里对神经网络所做的所有改进都是微小的、根本性的改变,这些改变既适用于深度网络,也适用于小型网络。如果你的网络不工作,更有可能是其他问题,而不是深度问题。

从一个3到8层的神经网络开始。只有当训练的网络有不错的性能,并开始研究如何提高准确性时,才开始尝试更深层次的网络。

11. 隐藏层神经元数量设置不正确

在某些情况下,使用过多或过少的隐藏神经元会让网络难以训练。神经元数量过少,它可能无法表达所需的任务,而神经元数量过多,它可能变得缓慢而笨拙,难以去除残余噪声进行训练。

在决定要使用的隐藏神经元的数量时,关键是要大致考虑你认为表达你希望通过网络传递的信息所需的实际值的最少数量。然后你应该把这个数字放大一点。这将允许 dropout,以便网络使用更冗余的表示,并在你的估计中有一点余地。如果你在做分类,你可能会使用类数量的5到10倍作为一个好的初始猜测,而如果你在做回归,你可能会使用输入或输出变量数量的 2 到 3 倍。当然,所有这些都高度依赖于环境,并且不存在简单的自动解决方案,良好的直觉仍然是决定隐藏单位数量的最重要因素。

从256到1024个隐藏神经元数量开始,待效果不错时,在逐步进行深入的调整。

参考博客:知乎:神经网络不收敛的 11 个原因

 

 

你可能感兴趣的:(机器学习,推荐系统,深度学习,机器学习,算法)