咱们先来聊几个使用监督学习来解决问题的实例。假如咱们有一个数据集,里面的数据是俄勒冈州波特兰市的戴户套房屋的面积和价格:
这里要先规范一下符号和含义,咱们假设 x^{i} 表示“输入的” 变量值(在这个例子中就是房屋面积),也可以叫做输入特征;然后咱们用 y^{i} 来表示“输出值”,或者称之为目标变量,这个例子里面就是房屋价格。这样的一对 (x^{(i)}, y^{(j)}) 就称为一组训练样本,然后咱们让机器来学习的数据集,就是一个长度为 m 的训练样本的列表 {(x^{(i)}, y^{(j)}) ; i=1, ..., m} ,也叫做一个训练集。另外我们还会用大写的 x 来表示输入值的空间,大写的 y 表示输出值的空间。在本节的这个例子中,输入输出的空间都是实数域,所以 X=Y=R
输入特征和目标变量都是人为确定的,都是样本中的某些元素
比如这里是用面积作为特征,价格作为目标变量;我们也可以反过来用价格作为特征,面积作为目标变量;哪个作为目标变量需要进行现实考量,即我们关心的东西。
这里实际上可以举个例子,比如我们在现实生活中,想要去预测“患者的生存期”,那么这个就是目标变量;而这同时明确了样本为“患者”,那么输入特征也需要是患者的某些特征,那么我们就可以去寻找与患者有关的特征去预测生存期,这个与患者有关可以是各个方面的有关,比如:患者居住地点、患者影像学检查的图像、患者生化指标、患者就诊医院等等,这些都与患者有关系,理论上都可以作为输入特征。
然后再用更加规范的方式来描述一下监督学习问题,我们的目标是,给定一个训练集,来让机器学习一个函数 h: X \mapsto Y ,让 h(x) 能是一个与对应的真实 y 值比较接近的评估值。这个函数 h 被叫做假设(hypothesis)。用一个图来表示的话,这个过程大概就是下面这样:
如果我们要预测的目标变量是连续的,这种学习问题就被称为回归问题。如果 y 只能取一小部分的离散的值(比如给定房屋面积,咱们要来确定这个房子是一个住宅还是公寓),这样的问题就叫做分类问题。
线性回归
为了让我们的房屋案例更有意思,咱们稍微对数据集进行一下补充,增加上每一个房屋的卧室数目
现在,输入特征 x 就是在 \mathbb{R}^{2} 范围取值的一个二维向量了。例如 x_{1}^{(i)} 就是训练集中第 i 个房屋的面积,而 x_{2}^{(i)} 就是训练集中第 i 个房屋的卧室数目。(通常来说,设计一个学习算法的时候,选择哪些输入特征都取决于你。关于特征筛选的内容会在后面的章节进行更详细的介绍。)
要进行这个监督学习,咱们必须得确定好如何在计算机里面对这个函数/假设 h 进行表示。咱们把 y 假设为一个以x 为变量的线性函数:
h_\theta(x) = \theta_0 + \theta_1 x_1 + \theta_2 x_2
另外为了简化公式,咱们还设 x_{0}=1 (这个也是截距项)。这样简化之后就有了:
h_\theta(x) = \sum_{j=0}^n \theta_j x_j = \theta^T x
等式的最右边的θ和 x 都是向量,等式中的 n 是输入变量的个数(不包括 x_{0} )。
现在,给定了一个训练集了,咱们怎么来挑选学习参数θ呢?一个看上去比较合理的方法就是让 h(x) 尽量逼近 y ,至少对已有的训练样本能适用。用公式的方式来表示的话,就要定义一个函数,来衡量对于每个不同的 θ 值, h(x^{(i)}) 与对应的 y^{(i)} 的距离。这样用如下的方式定义了一个成本函数:
J(\theta) = \frac{1}{2} \sum_{i=1}^m (h_\theta(x^{(i)}) - y^{(i)})^2
J(\theta) 中的变量是 \theta ,x^{(i)} 和 y^{(i)} 都是确定了的,只有改变 \theta 才能改变成本函数值
如果之前你接触过线性回归,你会发现这个函数和常规最小二乘法拟合模型中的最小二乘法成本函数非常相似。不管之前接触过没有,咱们都接着往下进行,以后就会发现这是一个更广泛的算法家族中的一个特例。
我们想要做的事情是,建立一个假设(hypothesis),使得训练集的特征输入后,输出值能最大化逼近真实值。而训练集的数据已经确定了,我们需要做的是修改模型来达到这个目的,而修改模型的方法就是调整参数 \theta ,调整 \theta 的方法就是梯度下降。
最小均方算法
我们希望选择一个能让 J(\theta) 最小的 θ 值。怎么做呢,咱们可以考虑使用梯度下降法,这个方法就是从某一个 θ 的初始值开始,然后逐渐重复更新:
\theta_j := \theta_j - \alpha \frac{\partial}{\partial \theta_j} J(\theta)
注: 本文中“:=” 表示的是计算机程序中的一种赋值操作,是把等号右边的计算结果赋值给左边的变量, a:=b 就表示用 b 的值覆盖 a 原有的值。要注意区分,如果写的是 “ a=b” 则表示的是判断二者相等的关系。
(上面的这个更新要同时对应从 0 到 n 的所有 j 值进行,也就是所有参数需要同时更新)这里的 α 也称为学习速率,影响梯度下降的步长。这个算法的本质就是使每个参数 \theta 逐步重复朝向 J 降低最快的方向移动。
要实现这个算法,咱们需要解决等号右边的导数项。首先来解决只有一组训练样本 (x, y) 的情况,这样就可以忽略掉等号右边对 J 的求和项目了。
对单个训练样本,更新规则如下所示:
\theta_j := \theta_j + \alpha (y^{(i)} - h_\theta(x^{(i)})) x_j^{(i)}
这个规则也叫最小均方更新规则,也被称为 Widrow-Hoff 学习规则。这个规则有几个看上去就很自然直观的特性。例如,更新的大小(步长)与 (y^{(i)}-h_{\theta}(x^{(i)})) 成正比;另外,当我们遇到训练样本的预测值与 y^{(i)} 的真实值非常接近的情况下,就会发现基本没必要再对参数进行修改了;与此相反的情况是,如果我们的预测值 h_{\theta}(x^{(i)}) 与 y^{(i)} 的真实值有很大的误差,那就需要对参数进行更大地调整。
当只有一个训练样本的时候,我们推导出了最小均方规则。当一个训练集有超过一个训练样本的时候,有两种对这个规则的修改方法。第一种就是下面这个算法:
\text{重复直到收敛 {} \theta_j := \theta_j + \alpha \sum_{i=1}^m (y^{(i)} - h_\theta(x^{(i)})) x_j^{(i)} \text{ }}
每个样本 i 的 x_i 都不一样,y^{(i)} - h_\theta(x^{(i)}) 也不一样,我们需要在这里对每个样本的结果进行求和
这一方法在每一个步长(每一次下降)内检查所有整个训练集中的所有样本,也叫做批量梯度下降法。这里要注意,因为梯度下降法容易被局部最小值影响,而我们要解决的这个线性回归的优化问题只能有一个全局的而不是局部的最优;因此,梯度下降法应该总是收敛到全局最小值(假设学习速率 α 不设置的过大)。 J 是一个凸的二次函数。下面是一个样例,其中对一个二次函数使用了梯度下降法来找到最小值。
上图的椭圆就是一个二次函数的轮廓图。图中还有梯度下降法生成的规矩,初始点位置。图中的画的 x (用直线连接起来了)标记了梯度下降法所经过的 θ 的可用值。(图中每个点代表一个参数组合)
对咱们之前的房屋数据集进行批量梯度下降来拟合θ,把房屋价格当作房屋面积的函数来进行预测,我们得到的结果是 \theta_{0}=71.27 , \theta_{1}=0.1345 。 如果把 h_{\theta}(x) 作为一个定义域在 x 上的函数来投影,同时也投上训练集中的已有数据点,会得到下面这幅图:
如果在数据集中添加上卧室数目作为输入特征,那么得到的结果就是 \theta_{0}=89.60 , \theta_{1}=0.1392 , \theta_{2}=-8.738
此外还有另外一种方法能替代批量梯度下降法,这种方法效果也不错。如下所示:
\text{循环 { 对于每一个训练样本 } i: \theta_j := \theta_j + \alpha (y^{(i)} - h_\theta(x^{(i)})) x_j^{(i)} \text{ }}
在这个算法里,我们对整个训练集进行了循环遍历,每次遇到一个训练样本,根据每个单一训练样本的误差梯度来对参数进行更新。这个算法叫做随机梯度下降法,或者叫增量梯度下降法。批量梯度下降法要在运行第一步之前先对整个训练集进行扫描遍历,当训练集的规模 m 变得很大的时候,因此引起的性能开销就很不划算了;随机梯度下降法就没有这个问题,而是可以立即开始,对查询到的每个样本都进行运算。通常情况下,随机梯度下降法查找到足够接近最低值的 θ 的速度要比批量梯度下降法更快一些。也要注意,也有可能会一直无法收敛到最小值,这时候 θ 会一直在 J(\theta) 最小值附近震荡;不过通常情况下在最小值附近的这些值大多数其实也足够逼近了,足以满足咱们的精度要求,所以也可以用。当然更常见的情况通常是我们事先对数据集已经有了描述,并且有了一个确定的学习速率 α ,然后来运行随机梯度下降,同时逐渐让学习速率α随着算法的运行而逐渐趋于 θ ,这样也能保证我们最后得到的参数会收敛到最小值,而不是在最小值范围进行震荡。
由于以上种种原因,通常更推荐使用的都是随机梯度下降法,尤其是在训练用的数据集规模大的时候。
监督学习的终极目的就是降低泛化误差,其力所能及的目的是降低训练误差,手段是梯度下降。如果模型足够复杂那这个目的(这个目的指降低训练误差)往往很轻易就能达到。但模型若太复杂则泛化误差不足,所以还需要结合VC维的思想来进行模型优化(VC维与样本量的关系,也就是模型复杂度与样本量的关系,VC维越大,模型越复杂,所需要的样本量越多)(要么调整样本量,要么调整VC维也就是模型复杂度)
