一文带你完全了解线性回归模型的梯度下降算法、多项式回归、正则化

1.线性回归参数求解
一般的线性模型,等式如下所示:
  • ŷ是预测值。
  • n是特征的数量。
  • xi是第i个特征值。
  • θj是第j个模型参数(包括偏置项θ0和特征权重θ1,θ2,...,θn)。
这可以使用向量的形式写得更简洁:
  • θ是模型的参数向量,包含偏置项θ0和特征权重θ1至θn
  • θT(一个行向量而不是一个列向量)是θ的转置。
  • x是实例的特征向量,包含x0到xn,其中x0始终等于1。
  • θxθT和x的点积。
  • hθ是假设函数,使用模型参数θ
这就是线性回归模型,那么现在我们该如何训练呢? 在前面的系列文章中,我们看到回归模型的最常见的性能指标是均方根误差(RMSE)。那么,要训练线性回归模型,我们需要找到使RMSE最小化的θ值。 在实践中,最小化均方误差(MSE)往往比RMSE更简单,并且能得到相同的结果(因为使函数最小化的值也使其平方根最小化),因此我们使用如下公式计算:
这些符号中的大部分都在前面系列的文章中介绍过。 唯一的区别是,我们写hθ而不是h,以便清楚地表明模型是通过向量θ来参数化的。 为了简化符号,我们只写MSE(θ)而不是MSE(X,hθ)。
方程有了,剩下的就是对方程中的参数进行求解了,常见的有以下两种方法: 正规方程法和梯度下降法
1.1正规方程
为了找到最小化成本函数的θ的值,可以通过下面的 正规方程 直接得出(具体推导不进行赘述),如下所示:
让我们生成一些线性数据来测试这个方程,如下所示:
现在让我们使用正规方程来计算θ。 我们将使用NumPy的线性代数模块(np.linalg)中的inv()函数来计算矩阵的逆矩阵,以及矩阵乘法的dot()方法,np.c_在矩阵X的左边添加上值的为1的列:
我们用来生成数据的实际函数是y = 4 + 3*X + Gaussian noise。 让我们看看等式可以发现:
我们希望θ0 = 4和θ1 = 3,而不是θ0 = 3.749和θ1 = 3.141。 足够接近,但噪音使得无法恢复原始函数的确切参数。现在你可以使用θ做出预测(分别取X_new的第0和第2个值来预测):
我们来绘制这个模型的预测:
使用Scikit-Learn的等效代码如下所示:

1.2梯度下降法
梯度下降是一种非常通用的优化算法,能够为广泛的问题寻找最佳解决方案。 梯度下降的一般思路是迭代地调整参数,以使代价函数最小化。
假设你在一片浓雾的山中, 你只能感觉到脚下的地面的斜坡。很快到达山谷底部的一个很好的策略就是沿着最陡的斜坡走下坡路。 这正是梯度下降主要思想:它运算测量误差函数的方式是沿着梯度下降的方向计算参数向量 θ 的局部梯度。 一旦梯度为零,说明已经达到了最低值!
具体来说,首先用随机值填充 θ (这被称为随机初始化),然后逐渐改进,每次步进一步,每一步都试图降低代价函数(例如,MSE),直到算法收敛到最小, (可以公众号回复 机器学习 ,参照里面的优化算法文章), 入图所示:
梯度下降中的一个重要参数是学习速率 (也就是我们通常所说的步长) 。 如果学习速率太小,那么算法将需要经过许多迭代才能收敛,这将需要很长时间,如下图所示:
另一方面,如果学习速率太高,你可能会跳过山谷,最后到达另一边,甚至可能比以前更高。 这可能会使算法发散,数值越来越大,无法找到一个好的解,如下图所示:
最后,并不是所有的代价函数都像普通的碗的形状。 可能会有洞,脊,高原和各种不规则的图形,使迭代最小化非常困难。 如下图所示,显示了梯度下降的两个主要挑战:如果随机初始化启动在左侧,则会收敛到局部最小值,这不是全局最小值。 如果它从右边开始,那么穿越高原将需要很长时间,如果你的算法迭代停止的时间得太早,你将永远达不到全局最低值。
幸运的是,线性回归模型的MSE代价函数碰巧是一个凸函数,这意味着如果选择曲线上的任意两点,连接它们的线段就不会穿过曲线。 也就是说着没有局部最小值,只有一个全局最小值。 它也是一个连续的函数,斜率永远不会突变。 这两个特性有一个重要的结果:梯度下降保证最终结果能够无限接近全局最小值(如果你等待足够长的时间,并且学习速率不是太高)。
实际上,代价函数是一个碗的形状,但是如果这些特征具有比例不同的尺度,那么它可以是一个拉长的碗。如下图所示,显示了代价函数的梯度下降迭代结果:
该图说明了如下事实:训练模型意味着搜索模型参数的组合(使训练集合上的代价函数最小化)。 它是模型参数空间中的一个搜索:模型的参数越多,这个空间的维数就越多,搜索就越困难。幸运的是,由于在线性回归的情况下代价函数是凸的,所以结果只是在碗的底部。这里我们详细介绍一下常见的梯度下降法:
  • 批量梯度下降(BGD)
批量梯度下降法为最小化所有训练样本的损失函数(对全部训练数据求得误差后再对参数进行更新),使得最终求解的是全局的最优解,即求解的参数是使得风险函数最小。批梯度下降类似于在山的某一点环顾四周,计算出下降最快的方向(多维),然后踏出一步,这属于一次迭代。批梯度下降一次迭代会更新所有theta,每次更新都是向着最陡的方向前进。
要实现梯度下降,需要计算每个模型参数θj的代价函数的梯度。换句话说,如果只是稍微改变θj,就需要计算代价函数的变化量,这被称为偏导数。 这就好比是问我“浓雾山坡中,如果我面向东方,脚下的斜度是多少”。 计算代价函数关于参数θj的偏导数,如下所示。
可以不用逐个计算这些梯度,而使用如下公式一次性计算它们。注意到的梯度向量包含了代价函数的所有偏导数。
一旦我们知道的哪个方向脚下的坡度最陡,我们就朝着那个方向走去,也就是说从θ中减去∇θMSE(θ)。则 参数迭代更新 如下所示,其中η为学习率,将梯度向量乘以η来为下坡步长的大小:
让我们看看这个算法的快速实现:
再看看最终的theta:
有没有发现这个和上面提到的正规方程解的结果一样!梯度下降表现也一样棒。 但是如果你使用了不同的学习速率呢? 下图显示了使用三种不同学习速率的梯度下降的前10个步骤(虚线表示起点)。
如上图,最左边,学习速率太低:算法虽最终会达到最佳解,但这将需要很长时间。 在中间,学习速率看起来相当不错:只需几次迭代,就已经收敛到了最佳解。 在右边,学习速率太高:算法发散,跳来跳去,实际上每一步都越来越远离最佳解。
为了找到一个好的学习速率,你可以使用网格搜索(前系列文章)。 但是,您可能需要限制迭代次数,以便网格搜索可以使模型快速收敛。
我们可能想知道如何设置迭代的次数。 如果它太低,算法停止时会离最优解很远,但是如果它太高,则会浪费时间。 一个简单的解决方案是设置大的迭代次数,但是在梯度向量变化变小的时候中断算法。
优点:全局最优解;易于并行实现;
缺点:当样本数目很多时,训练过程会很慢。
  • 随机梯度下降(SGD)
随机梯度下降法为最小化每条样本的损失函数,虽然不是每次迭代得到的损失函数都向着全局最优方向, 但是大的整体的方向是向全局最优解的,最终的结果往往是在全局最优解附近。随机也就是说我用样本中的一个例子来近似我所有的样本,来调整theta,其不会计算斜率最大的方向,而是每次只选择一个维度踏出一步;下降一次迭代只更新某个theta,报着并不严谨的走走看的态度前进。
批量梯度下降的主要问题在于,它使用整个训练集来计算每一步的梯度,这使得训练集很大时训练非常缓慢。 而随机梯度下降在每个步骤中只是在训练集中选取一个随机实例,并仅基于单个实例计算梯度。 显然这使得算法更快,因为它在每次迭代中都只用非常少的数据来操作。
另一方面,由于更新参数时,采用的是随机单个样本替代BGD中的整体样本进行参数迭代,所以在寻找最小值的过程中,代价函数的值会随着样本的不同而进行上下波动。然而随着迭代次数的增加,最终的结果会非常接近最小值,但是即使到达最小值,代价函数还是会随着不同的样本进行上下波动,永远不会稳定下来,这样如下图,算法一旦停止,最终的参数值是好的,但是不一定是最优的。
当代价函数非常随机的时候,实际上可以帮助算法跳出局部最小值,所以随机梯度下降比批量梯度下降有更好的找到全局最小值的机会。
因此,随机性虽能很好地逃离局部最优,但是这并不好,因为这意味着该算法永远无法最小化。 解决这个难题的一个办法就是逐渐降低学习速率。 步骤开始很大(这有助于快速进展,避免局部最小值),然后变得越来越小,使得算法在全局最小值处达到最小。 这个过程被称为模拟退火,因为它类似于冶金学的熔融金属慢慢冷却的退火过程。 决定每次迭代的学习速率的函数被称为学习时间表。 如果学习速率降得太快,可能会陷入局部最低限度,甚至还没到达最优解就冻结了。 如果学习速率降低得太慢,您可能会长时间跳过最优解,而且若过早停止训练,还会出现次优解。
此代码使用简单的学习时间表实现随机梯度下降:
按照惯例,我们通过多轮的m次迭代; 每一轮被称为一个epoch。批量处理梯度下降代码在整个训练集中迭代1000次,而这个代码只经过训练集50次,达到了相当好的结果:
如下图显示了前10步的训练(注意过程是十分不规则的)。
要使用Scikit-Learn的SGD执行线性回归,可以使用SGDRegressor类,该类默认优化平方误差代价函数。 下面的代码运行50个时期,从学习率0.1开始,使用默认的学习计划(和我们之前使用的是不同的),并且不使用任何正则项(正则项后面会说):
同样,你会得到非常接近正规方程的解:
优点:训练速度快;
缺点:准确度下降,并不是全局最优;不易于并行实现。
  • 小批量梯度下降(MBGD)
我们来看一下最后一个梯度下降算法的变种被称为小批量梯度下降(Mini-batch Gradient Descent)。其实MBGD是一种介于SGD和BGD两种方法之间的一种折中的梯度下降法,一旦知道批量和随机梯度下降就很容易理解小批量梯度下降:在每一步中,不是基于完整训练集(如BGD)或仅基于一个实例(如SGD中那样)计算梯度,而是在小随机实例集上的梯度。
如下图所示,显示了训练期间三个梯度下降算法在参数空间中所采用的路径。 他们都接近最优值,BGD的路径最终停在最优值,而SGD和MBGD继续四处走动。 但是,不要忘记BGD需要花费很多时间来完成每个步骤,如果您使用了一个良好的学习计划表,Stochastic GD和Mini-batch GD也会达到最小。
当然,上面我们详细讲述了如何通过正规方程和梯度下降法进行求解线性回归方程的参数,但是很多数据实际上要比线性数据复杂的多,那么到如何处理呢?


2. 多项式回归和学习曲线
2.1 多项式回归
如果你的数据实际上比简单的直线更复杂呢?我们仍然可以使用线性模型来拟合非线性数据。 一个简单的方法是将每个特征的n次方作为新特征添加,然后在这个扩展的特征集上训练一个线性模型。 这种技术被称为多项式回归。
我们来看一个例子。 首先,我们根据一个简单的二次方程(加上一些噪声)生成一些非线性数据,如下图所示:
显然,一条直线永远拟合不了这些数据。 因此,让我们使用Scikit-Learn的PolynomialFeatures类来转换我们的训练数据,在训练集中添加每个特征的平方(二次多项式)作为新特征:
X_poly现在包含X的原始特征加上该特征的平方。 现在,我们可以将LinearRegression模型拟合这个扩展的训练数据(如下图):
估计的结果(0.49,0.97,1.90)和原来的参数(0.5,1.0,2.0)差不多。
2.2 学习曲线
如果执行高维的多项式回归,可能比简单的线性回归更好地拟合训练数据。 例如,如下图,将300维多项式模型应用于前面的训练数据,并将结果与纯线性模型和二次模型(二次多项式)进行比较。
当然,这个高维多项式回归模型严重过拟合训练数据,而线性模型不适应。 在这种情况下最好的模型是二次模型,这是由于数据是使用二次模型生成的。但是一般来说,我们不知道生成数据的函数是什么,那么如何确定模型的复杂程度呢? 你怎么知道你的模型是过度拟合还是欠拟合呢?
我们使用交叉验证来估计模型的泛化性能,如果一个模型在训练数据上表现良好,但是根据交叉验证度量标准推广得不好,那么你的模型就是过拟合。 如果两者都表现不佳,那么这是欠拟合。 这是一种判断模型拟合质量的方法。
另一种方法是查看学习曲线。下面的代码定义了一个函数,该函数绘制给定的训练数据的模型的学习曲线:
我们来看看简单线性回归模型的学习曲线:
上图 中横坐标为训练集的大小,纵坐标为RMSE,蓝色曲线代表模型在不同大小的验证集上的RMSE,红色曲线代表不同大小训练集上的RMSE。
这里值得解释一下。首先,我们来看看训练数据的特性:当训练集中只有一个或两个实例时,模型可以完美地拟合它们,这就是曲线从零开始的原因。但是,当新的实例被添加到训练集时,模型不可能完美地拟合训练数据,这既是因为数据是复杂的,也因为它不是线性的。所以训练数据上的误差会上升到一个台阶,在这一点上,增加新的训练集并不会使平均误差变好或变差。现在我们来看看验证数据上模型的特性。当模型在很少的训练实例上进行训练时,就不能正确泛化,这就是为什么验证错误最初是相当大的。然后当模型引入更多的训练样例,通过学习,验证错误缓慢下降。然而,直线因为不能很好地模拟数据,所以错误在一个高度上停止下降,非常接近训练曲线。
这些学习曲线是典型的欠拟合模型。 两条曲线误差都很高; 他们比较接近,误差值相当高。
现在让我们看看相同数据上的10阶多项式模型的学习曲线:
这些学习曲线看起来有点像上面的,但有两个非常重要的区别:
  • 训练数据的误差远远低于线性回归模型。
  • 曲线之间有较大的间隙。 这意味着模型在训练数据上的表现明显优于验证数据,这是过度拟合模型的标志。 但是,如果你使用了更大的训练集,这两条曲线会继续靠近。


3.正则化线性模型
减少过拟合的一个很好方法就是使模型正规化(即限制它):自由度越少,越难过拟合数据。对于线性模型,正则化通常是通过约束模型的权重来实现的。现在我们来看看Ridge回归(Ridge Regression),Lasso回归(Lasso Regression)和Elastic Net,它们实现了三种不同的权重约束方法。
3.1 Ridge Regression
Ridge回归(也称为Tikhonov正则化,俗称L2正则化)是线性回归的正则化版本,如下等式:
该正则化项被添加到代价函数中。 这迫使学习算法不仅适合数据,而且保持模型权重尽可能小。 请注意,正则化只应在数据训练期间被添加到代价函数中。 一旦模型训练完成,我们就需要使用非正则化的测量值来评估模型的表现。
超参数α控制你想要正则项惩罚模型的程度。如果α = 0,则Ridge回归就是线性回归。 如果α非常大,那么所有的权重都非常接近于零,结果是一条平坦的通过数据的均值的线。 给出Ridge回归代价函数:
如下图,显示了使用不同的α值对一些线性数据进行训练的几个Ridge模型。 在左边,使用普通的Ridge模型,导致线性预测。 在右边,首先使用 PolynomialFeatures (维度 = 10)扩展数据,然后使用StandardScaler对数据进行缩放,最后将Ridge模型应用于所得到的特征:这是具有Ridge正则化的多项式回归。 请注意,α的增加会导致更平坦的(即不太极端的,更合理的)预测。
和线性回归一样,我们可以通过计算解析式或执行梯度下降来执行Ridge回归。 下式显示了解析式的解(其中A是n×n单位矩阵)。
以下是如何使用Scikit-Learn计算解析式解(使用André-Louis Cholesky的矩阵分解技术,上述公式的变体)执行Ridge回归:
或者你可以直接使用随机梯度下降,代码如下所示:
3.2 Lasso Regression
Least Absolute Shrinkage和Selection Operator Regression(简称Lasso回归)是Linear Regression的另一个正则化版本:就像Ridge回归一样,它为成本函数增加了一个正则化项,但它使用权向量的L1范数而不是L2范数,如下式所示。
下图显示了与上一小节相同的情况,但用Lasso模型替换了Ridge模型,并使用较小的α值。
Lasso回归的一个重要特性是它倾向于完全消除最不重要的特征的权重(即将它们设置为零)。例如,上图(α= 10-7)右边的虚线看上去是二次的,高阶多项式特征的所有权重等于零。 换句话说,Lasso回归自动执行特征筛选并且输出稀疏模型(即,具有很少的非零特征权重)。
通过查看下图,我们可以了解为什么会出现这种情况:在左上角的图上,背景等高线(椭圆)代表未经调整的MSE代价函数(α = 0),白色圆圈显示具有该代价函数的BGD路径。 前景轮廓(菱形)表示L1惩罚,而黄色小三角形(相对于白色小圆圈的另一条路径)表示示该惩罚的BGD路径(α→∞),注意惩罚路径首先到达θ1= 0,然后直接到达到θ2 = 0。在右上角的图上,背景等高线代表相同的代价函数加上α = 0.5的L1惩罚。 全局最小值在θ2 = 0轴上。 BGD首先达到θ2 = 0,然后向下滚动直到达到全局最小值。 两个底部的图表显示了相同的情况,但是使用了L2正则项。 正则化的最小值比非规范化的最小值更接近于 θ = 0,但是权重并没有被完全消除。
在θi= 0(对于i = 1,2,...,n),Lasso回归的代价函数是不可微分的,但是如果在任何θi = 0时使用次梯度向量 g (可以将次梯度向量看作是不可微点周围的梯度向量之间的中间向量),梯度下降仍然可以正常工作。下式是一个使用Lasso类的小型Scikit-Learn示例(其实也可以改为使用SGDRegressor(参数设置penalty=“l1”),作为小练习题,让读者自己动手编写)。
3.3 Elastic Net
Elastic Net其实是Ridge回归和Lasso回归之间的中间地带,是Ridge和Lasso正则化术语的简单组合。如下式,我们可以控制混合比率r,当r = 0时,Elastic Net相当于Ridge回归,当r = 1时,相当于Lasso回归。
下面是使用Scikit-Learn的ElasticNet(l1_ratio对应于混合比率r)的简单示例:


4. 小结
本文我们一起详细学习了求解线性回归参数的正规方程法,以及三种常见的梯度下降法。然后讲解了如何将多项式回归用于复杂的非线性数据中,最后学习了减少模型过拟合的三种常见的正则化模型方法。

猜你喜欢

转载自blog.csdn.net/luckoovy/article/details/80790240
今日推荐