ML Lecture 1: Regression - Case Study

ML Lecture 1: Regression - Case Study


Regression(回归):输出数值

之前提到,机器学习要做的事情就是寻找函数,而回归要做的事情就是使我们所找的那个函数,其输出为数值型。或者说,如果我们找到的函数,它的输出是数值型的,这类型的任务就称为回归。举几个关于回归的例子:

  1. 股票市场的预测:找一个函数,其输入是过去股票市场的变动情况,输出是明天道琼工业指数的数值
  2. 驾驶无人车:找一个复杂函数,其输入是无人车上的各个感受器收集的数据,输出是方向盘角度
  3. Amazon的商品推荐/Youtube的视频推荐:找一个函数,其输入是用户A、商品B的各种特性,输出是用户A购买商品B的可能性

应用实例:做回归,预测pokemon进化后的CP值(战斗力)

回归任务:找一个函数,其输入用 x 来表示,代表pokemon进化前的各种指标(例如:进化前的CP值 x c p 、所属物种 x s 、进化前的HP值 x h p 、重量 x w 、高度 x h 等),输出是进化后的CP值,用 y 来表示。

如何找出这个函数?之前提到,机器学习的三个步骤分别是:

  1. 第一步,寻找一个模型(即一组函数/一个函数集)。假设我们认为进化后的CP值 y 与进化前的CP值 x c p 有密切的关系,那么就可以将模型表示为:

    y = b + w x c p
    并称之为线性模型(Linear Model),这个模型随着参数 b w 取不同值,可以形成多个函数 f 1 f 2 f 3 . . . 。显然,该模型(函数集)中的函数并非全部是合理的,我们需要从中挑取有利于预测的函数。进一步地,考虑其他的各种指标,可以将模型推广表示为:
    y = b + w i x i
    其中, x i 泛指各种指标/特征(Feature) x c p x h p x w x h w i 称为权重(Weight) b 称为偏置(Bias)

  2. 第二步,判断函数的优劣。为此,我们必须收集一些训练资料,其中包括不同pokemon的 x c p i y ^ i ) 。其中 x c p i 代表第 i 只pokemon进化前的CP值, y ^ i 代表第 i 只pokemon进化后的真实CP值。下图是收集到 10 只pokemon的训练资料(蓝色点):

    有了数据以后,就可以考察模型中的任意一个函数的优劣,这种“评价”是通过定义另一个函数,即损失函数(Loss Function)来完成的,通常用 L 表示。注意,损失函数是关于 f 1 f 2 f 3 . . . 的函数,即函数的函数。它的输入是:模型中的任意一个函数 f (由参数 b w 决定);输出是:关于这个函数优劣的评价。
    统计学习常用的损失函数有:0-1损失函数平方损失函数绝对损失函数对数损失函数等,这里采用最常见的平方损失函数:

    L ( f ) = L ( w , b ) = n = 1 10 ( y ^ n ( b + w x c p n ) ) 2

  3. 第三步,根据定义的损失函数 L ( f ) ,按照 L ( f ) 越小越好(即损失越少越好)的原则,从模型中挑选最佳函数 f ,这个过程用公式表示为:

    f = a r g m i n f L ( f )

    寻找 f 就是寻找最佳参数 ( w , b ) 。一个有效方法是梯度下降法(Gradient Descent),只要损失函数 L ( f ) 是可微分的,都可以用此方法求解最佳函数/参数: f = f ( w , b )
    梯度下降法是如何工作的呢?首先不考虑 b ,假设待求解的参数只有 w ,再定义一个关于 w 的损失函数 L ( w ) ,这个 L ( w ) 可以是任何形式的函数,只要满足:可微分、能够衡量 w 的优劣。有了 L ( w ) 后,我们要做的就是找一个 w ,使得 L ( w ) 最小。最容易联想到的做法就是暴力穷举所有 w ,逐个代入 L ( w ) ,比较之后得到最小的 L ( w ) ,然而此举效率十分低下。
    采用梯度下降法可以克服上述困难:它不是穷举所有 w ,而是首先随机选取一个初始 w 0 ,计算 L ( w ) w = w 0 处的导数: d L d w | w = w 0 ,得到的数值即损失函数的曲线在 w 0 处的切线斜率:

    • d L d w | w = w 0 < 0 ,说明 L ( w ) 的曲线正在下降,应该增大 w 0 ,以降低 L ( w )
    • d L d w | w = w 0 > 0 ,说明 L ( w ) 的曲线正在上升,应该减小 w 0 ,以降低 L ( w )

    w 0 增大或减小的幅度取决于两件事:

    • 当前导数值 d L d w | w = w 0 的大小。它代表了损失函数的曲线当前正处于陡峭,还是平坦状态。显然,在曲线越陡峭的位置, w 0 稍微增大或减小一点,就会使损失函数发生很大的变动
    • 学习率(Learning Rate) η 的大小。 η 是自行设定的常数项,它决定了参数学习速度有多快。 η 越大,则 w 0 下一步要跨越的距离就越大(即参数更新的幅度大),意味着参数的学习效率比较高

    注意,由于导数值 d L d w | w = w 0 的正负与 w 0 的移动方向恰好相反,所以 w 0 更新时,应该加上负号,即 w 1 = w 0 η d L d w | w = w 0 。按照这样的规则,从初始参数开始迭代: w 0 w 1 w 2 . . .
    在针对线性回归的迭代过程中,参数的更新使得损失函数不断下降,最终逼近最优参数 w ,使损失函数取得最小值。梯度下降法之所以能用来解决线性回归任务的参数求解,是因为这里的损失函数 L 是一个凸函数(Convex Function),其中不存在局部最小值的问题,最后只有一个全局最小值,所得即所求。
    事实上其他许多参数求解问题,虽然每一次更新也使损失函数不断下降,但最后到达的是局部最小值(Local Minimum)。此时,损失函数看似到达最低点,并且由于导数值 d L d w | w = w 0 = 0 ,参数会停止更新。但在整个损失函数中,可能存在着一个更低点全局最小值(Global Minimum),而全局最小值才是我们的终极目标。关于这一点,后面会作图解释。

    同理,当有两个参数 ( w , b ) 时,首先定义一个关于 ( w , b ) 的损失函数 L ( w , b ) ,然后随机选取一组初始参数 ( w 0 , b 0 ) ,计算在 w = w 0 , b = b 0 处, L ( w , b ) w b 的偏导数: L w | w = w 0 , b = b 0 L b | w = w 0 , b = b 0
    按照 w 1 = w 0 η L w | w = w 0 , b = b 0 b 1 = b 0 η L b | w = w 0 , b = b 0 ,进行两个参数的迭代更新,直到最后偏导数等于 0 ,参数停止更新。此时的参数 ( w , b ) 能够使损失函数最小。
    梯度下降中的梯度,就是指损失函数 L 对各个参数求偏导后,所组成的向量:

    L = [ L w L b ]

    上述关于两个参数的迭代过程,可以理解如下:图中每一个点分别代表不同的 ( w , b ) ,越往中间(紫色部分),损失函数的值越小,对 ( w , b ) 的每一次更新,都是沿着等高线的法线方向,往中间地区移动。

    同样地,可以推广到用梯度下降法求解多个参数的情形。假设 θ 表示一个参数的集合,运用梯度下降法求解时,我们希望参数的每一次更新,都能使损失函数再降低一点:

    θ 0 θ 1 θ 2
    L ( θ 0 ) > L ( θ 1 ) > L ( θ 2 )

    但正如前面所说,梯度下降法的缺陷在于:

    • 选取不同的初始参数,可能会得到不同的局部最小值

    • 在全局/局部最小值处,参数不再更新,是因为这里的导数值为 0 。但其实在整个误差曲面(Error Surface)上,导数值为 0 的点不止全局/局部最小值,也有可能是鞍点(Saddle Point)。鞍点的位置如下图浅蓝色框所示,在该点处,导数值为 0 却并非最小值点

    • 在实际迭代操作中,我们往往不会真的等到导数值为 0 ,才停止参数的更新,而是会设定一个阈值(Threshold),当导数值小于此阈值时,我们就认为损失函数已经差不多接近最小值,参数也差不多接近最优,并停止迭代。但这样的做法会带来问题:绿色框对应的点,其实离全局/局部最小值、鞍点还很远,但由于处在非常平坦的地方,其计算出来的导数值特别小,每一次参数更新都只前进一点点,若此时误以为已经接近目标而停止迭代,那么求出来的参数是无法使损失函数最小的

    必须强调的是,在线性回归模型中,由于损失函数是一个凸函数,类似于碗的形状,不存在多个最小值,因此从任何一个初始位置出发,最后都会回到唯一的最低点,所以能够克服上述缺陷。


模型选择与评估

至此,关于如何用梯度下降法求解回归方程参数的基本原理就结束了,下面开始运用实际数据做拟合。以 10 只pokemon的基本信息(每个样本的指标 x i 及其对应的输出 y )作为训练集,考虑到进化后的CP值 y 应该与进化前的CP值 x c p 值有密切联系,因此尝试拟合第一个模型

y = b + w x c p
定义损失函数:
L ( f ) = L ( w , b ) = n = 1 10 ( y ^ n ( b + w x c p n ) ) 2

计算两个偏导数:

假设在第一个模型上,通过训练集的数据资料,迭代求得最优参数为 ( w , b ) = ( 2.7 188.4 ) 。于是我们得到的最优函数为: y = 188.4 + 2.7 x c p ,这个函数基于训练集的平均误差为 31.9 平均误差(Average Error)的计算公式为:

A E = 1 10 n = 1 10 | e n |

再抓取 10 只新的pokemon的基本信息(新样本的指标 x i 及其对应的输出 y )作为测试集,对函数的泛化性能作一评估,得到测试集上的平均误差为 35.0

考虑进化后的CP值 y 与进化前的CP值 x c p 、及其平方项 x c p 2 之间的关系,拟合第二个模型

y = b + w 1 x c p + w 2 ( x c p ) 2
得到训练集的平均误差为 15.4 ,测试集的平均误差为 18.4 ,预测性能明显有所提升。

以此类推,考虑 x c p 、平方项 x c p 2 、三次方项 x c p 3 ,拟合第三个模型

y = b + w 1 x c p + w 2 ( x c p ) 2 + w 3 ( x c p ) 3
得到训练集的平均误差为 15.3 ,测试集的平均误差为 18.1 ,预测性能只有小幅提升。

当拟合第四个模型

y = b + w 1 x c p + w 2 ( x c p ) 2 + w 3 ( x c p ) 3 + w 4 ( x c p ) 4
得到训练集的平均误差为 14.9 ,测试集的平均误差为 28.8 。对比第三个模型,此时测试集的平均误差反而上升,泛化性能下降,这是由于模型开始出现过拟合的问题。

当拟合第五个模型

y = b + w 1 x c p + w 2 ( x c p ) 2 + w 3 ( x c p ) 3 + w 4 ( x c p ) 4 + w 5 ( x c p ) 5
得到训练集的平均误差为 12.8 ,测试集的平均误差为 232.1 。对比第四个模型,测试集的平均误差急速上升,说明已经严重过拟合。

【注】:上述拟合的五个模型都是线性的,因为模型是相对于参数 w b 而言的, x c p x c p 2 x c p 3 …则视为不同的样本特征(feature),可以用 x 1 x 2 x 3 代替。

从第一个模型到第五个模型,易观察到,随着模型越来越复杂,基于训练集所求出来的平均误差是越低的,而基于测试集的平均误差则是先减小后增大,出现了过拟合问题。为什么会出现过拟合?考察上面五个模型(函数集)之间的关系,它们之间满足:

w 5 = 0 ,就能使第五个模型等于第四个模型;令 w 4 = 0 ,就能使第四个模型等于第三个模型…以此类推。显然,第五个模型涵盖了前面所有模型的可能情况,它在 训练集上的性能会越来越好,至少不会劣于第一、二、三、四个模型,其在训练集上的平均误差是越来越小的。

而在测试集上,第三个模型的性能是最好的,从第四个模型开始,平均误差逐渐增大。可见,并不是越复杂的模型就越好,它在测试集上的性能并非一直提升。一个复杂模型在训练集上得到了比较好的性能,而在测试集上性能表现十分不理想,这就是过拟合(Overfitting)问题。事实上,我们更关注的是模型在测试集(而非训练集)上的表现,因此在模型选择过程中,应该以在测试集上表现最佳的模型作为最终选择。

解决过拟合的其中一个方法是收集更多的数据。当持有更多数据的时候,会发现进化后的CP值 y 并不只与进化前的CP值 x c p 有关,还与pokemon的物种有关。


因此重新设计模型,加入 x s ,代表pokemon的种类。当 x s 取不同的值,分别对应不同的函数表达式。这样的模型仍然是一个线性模型:

上述线性模型引入 δ (相当于哑变量)后,可进一步表示为:

其中,蓝色方框内的 8 个变量可视为 x i i = 1 , 2...8 b 1 , w 1 , . . . , b 4 , w 4 则视为 8 个参数,因此该模型仍然是一个线性模型。用此模型在训练集上拟合,可求得 8 个参数,代表四条曲线,分别反映四个物种的进化情况:蓝色是波波(Pidgey),绿色是绿毛虫(Caterpie),黄色是独角虫(Weedle),红色是伊布(Eevee)。图中由于绿毛虫与独角虫的直线重合,所以看上去只有三条。最后,在训练集上平均误差为 3.8 ,在测试集上平均误差为 14.3

考虑物种后,尽管模型性能进一步提升,但在训练集上的平均误差还是没有接近 0 ,这可能是由于直线不足以描述 y x c p 之间的关系,又或者是还有其他相关的因素未加以考虑:例如观察散点图,认为pokemon的HP值可能与进化后的CP值存在一定的关系。

因此,在考虑物种因素的模型基础上,尝试加入:进化前的CP值的平方项 ( x c p ) 2 、体重 x w 、高度 x h 、HP值 x h p ,构成了含有 18 个参数( w 1 , . . . , w 14 b 1 , . . . , b 4 )的新模型。最后得到训练集上的平均误差为 1.9 ,测试集上的平均误差高达 102.3 ,出现严重过拟合,说明上述尝试并不能改进模型。


防止过拟合:正则化

以往我们定义损失函数后,就按照使训练集的损失函数最小化/平均误差最小化的原则求取参数,并得到最佳的预测函数 f 。但通过这种方法得到的函数,可能是过拟合的,导致在测试集上的预测结果有时并不理想。

针对上一节的过拟合问题,如果具备相应的领域知识(Domain Knowledge),那么可以根据专业知识删除一些不重要的因素。但在无法对各个因素做出准确判断的情况下,通常采正则化(Regularization)来防止过拟合。

正则化方法对损失函数进行了重新定义,在原有损失函数的基础上,加入了一个正则项。假设线性模型为:

y = b + i w i x i
其中 x i 代表不同的特征/指标: x c p x h p x w x h 等。则原来的损失函数(未加入正则项)定义为:
L = n ( y ^ n ( b + i w i x i n ) ) 2
重新定义后的损失函数(加入正则项)为:
L = L + λ i ( w i ) 2 = n ( y ^ n ( b + i w i x i n ) ) 2 + λ i ( w i ) 2

正则项 λ i ( w i ) 2 是由 λ 和所有参数 w i 的平方和构成的。定义新的损失函数后,求 L m i n 意味着同时求 L m i n [ λ i ( w i ) 2 ] m i n :即它不仅要求原有的损失函数 L 最小化,还要求正则项也最小化。

使损失函数 L 最小化容易理解。但最小化正则项对于模型选择有什么帮助呢?或者说,加入正则项的意义是什么?

首先明确,在模型 y = b + i w i x i 中,参数 w i 很小意味着模型里的函数是比较平滑的。所谓函数平滑(Smooth),是指当输入值 x i 发生变化时,这种变化不会引起输出值 y 的剧烈变动,即 w i 越小, Δ x i Δ y 的影响越小(可以理解为较小的 w i ,降低了 x i 变化带来的冲击)。举个极端例子,当 w i = 0 y = b 是一条相当平滑的直线, x i 的任何变化都不会对 y 造成影响。

因此,正则项最小化意味着我们寻找的最佳函数,要尽可能的平滑,能够最大程度地抵挡因输入值变化而对输出值带来的冲击。

正则项的意义就在于:当我们从一个模型(函数集)中挑选最佳函数 f 时,正则项的存在能够防止我们挑到对波动十分敏感的函数。加入正则项,使 f 尽可能平滑的做法之所以成立,是因为“在多数状况下,我们认为平滑曲线更有可能是正确的目标函数,更有利于预测,波动幅度很大的函数往往会造成很大的误差”

然而,正则项也有失灵的时候。正则项的存在是为了使挑出来的预测函数 f 更平滑,减小测试集上的误差。但,假如真实的函数本身就是一个波动性很大的函数,我们还利用正则项去挑选平滑的预测函数,那么与真实函数是背道而驰的。不过一般情况下,还是认为正确的函数不会长得很奇怪,不会波动特别厉害,所以正则项还是颇有帮助。

总而言之,新的损失函数 L 由于加入了正则项,令我们的目标变成了:

  1. 寻找最佳函数 f ,使得原来的损失函数 L 是最小的
  2. 这个最佳函数 f 自身的参数 w i 也是尽可能小的,从而使 f 尽可能地平滑

对于正则项,还有两个需要注意的地方:

  1. 正则项中还有一个常数 λ ,它是一个需要手动设置的参数,决定了 f 的平滑程度( λ 越大,则要求 f 越平滑)
  2. 通常只对权重参数 w i 进行正则化,而不对截距参数 b 做正则化。首先,如果非要为参数 b 构造正则项,其实并不是错误的做法(虽然没有对错,但有好坏之分)。但在实际经验中, b 的正则化通常对改进模型没有帮助。因为参数 b 这一项只代表了一条水平线,它对函数 f 是否平滑没有任何影响,只决定 f 上下移动的位置。

手动设置不同的正则项参数 λ 进行拟合,随着 λ 不断增大,得到的最佳函数 f 也越来越平滑。这个过程中, f 在训练集的平均误差从 1.9 增大到 8.5 ,这个变化是合理的:因为没有加入正则项的时候,我们的优化目标只有 a r g m i n { L } ,而加入正则项使我们同时要考虑减小 w i ,使 f 变得平滑。并且随着 λ 的增大,我们更倾向于得到平滑的 f ,这是以训练集的平均误差上升为代价的。但训练集的平均误差增大,不代表测试集的平均误差会增大。


结论

  • 进化后的CP值与进化前的CP值、pokemon的种类有密切关系,但仍然可能存在其他隐藏的关联因素
  • 接下来会继续介绍梯度下降法的相关理论
  • 加入正则项,最后在测试集上得到的最好结果是, λ = 100 ,平均误差为 11.1 。假如继续收集新的数据,平均误差将会大于 11.1

猜你喜欢

转载自blog.csdn.net/Joyliness/article/details/79778915