PATTERN RCOGNITION AND MACHINE LEARNING(PRML)
Introduction
引言:
从一堆数据中挖掘一些可用的数据规则是由古至今科学家一直研究的问题,它有着悠久而成功的历史。 例如,16世纪对天文的广泛观测,使约翰内斯·开普勒发现了行星运动的三大定律,从而对古典力学的发展有了一定的促进作用。同样,在20世纪,原子光谱规律的发现,对早期量子物理学的发展发挥了关键作用。在计算机中, 模式识别领域是通过计算机算法自动发现数据中的规律,并利用这些规律采取行动,如将数据分类到不同的类别.
例如识别手写数字的例子,如图1.1所示。 每个数字对应一个28×28像素的图像,因此可以用包含784个实数的向量x表示。 我们的目标是建立一个机器算法,它将以这样一个向量x作为输入,并将产生数字0到 9作为输出。 这是一个非常重要的问题,因为笔迹的多样性很大。 我们可以根据手工的方式或者启发式的方案,根据笔画的形状来区分数字 ,但在实践中,这种方法会导致规则和规则例外的激增,导致结果总是不好.
采用机器学习的方法可以得到更好的结果,其中一个大的集合{x1,…, xN}称为训练集,用于调整自适应模型的参数。 训练集中数字的类别是预先知道的,通常通过逐个检查并手工标记它们。 我们可以用目标向量t表示一个数字的类别,它表示对应数字的特定输出。 稍后将讨论用向量表示类别的合适技术。注意,每个数字图像x都有一个这样的目标向量t。
运行机器学习算法可以训练处一个函数y(x),该函数以一个新的数字图像x作为输入,生成一个输出向量y ,以与目标向量相同的方式编码 .函数y(x)的精确形式是在训练阶段确定的 ,也称为学习阶段 ,一旦模型被训练,它就可以确定新的数字图像属于什么数字.正确分类不同于训练阶段的新示例的能力称为泛化 .在实际应用中,输入向量的可变性使得训练数据只能包含所有可能输入向量的一小部分,所以泛化是模式识别的核心目标 .
对于大多数实际应用程序,通常对原始输入变量进行预处理,将它们转换为一些新的变量空间,这样会使模式识别问题更容易解决。 例如,在数字识别问题中,通常对数字的图像进行平移和缩放,使每个数字都包含在一个固定大小的框中,这大大降低了每个数字分类中的可变性,因为所有数字的位置和比例都是一样的,这使得我们训练的模式识别算法更容易区分不同的数字.这个预处理阶段有时也称为特征提取。注意:新的测试数据必须使用与测试数据相同的步骤进行预处理。
为了加快计算速度,也可以进行预处理。 比如,如果我们想在高分辨率视频流中实时检测人脸,计算机必须每秒处理大量的像素,这就导致将这些数据直接呈现给我们之前设计的模式识别算法可能在计算上是行不通的。 相反,我们的目标是找到可快速计算的有用特性,这些处理后的图片同时还保存有用的区分信息,使人脸能够从非人脸中区分出来。 然后将这些特性用作模式识别算法的输入。 例如,图像强度在矩形子区域上的平均值可以非常有效地评估,一组这样的特征可以证明在快速人脸检测中是非常有效的。 因为这些特征的数量小于像素的数量,这种预处理是降维的一种形式。 在预处理过程中必须小心,因为可能有用的信息会被我们丢弃, 如果这些信息对问题的解决很重要,那么系统的整体精度就会受到影响。
训练数据包含输入向量及其对应目标向量的示例的应用称为监督学习问题。 数字识别的例子中,我们的目的是将每一个输入向量划分到某一个具体的分类,称为分类问题。 如果期望的输出是一个连续变量,那么这个就被称为回归问题。 回归问题的一个例子是你可以通过输入包括反应物的浓度、温度和压力,来预测化学生产过程的产量。
在其他模式识别问题中,训练数据由一组没有任何对应目标值的输入向量x组成。 这种无监督学习问题的目标可能是在数据中发现一组类似的例子,或确定数据在输入空间中的分布, 这种方式叫做聚类,比如我们常用的密度估计,或者将高维空间中的数据投影到二维或三维空间以实现可视化。
最后,强化学习技术(Sutton and Barto, 1998)关注的是如何在给定的情况下找到合适的行动来实现奖励的最大化。 与监督学习相比,强化学习算法并没有给出对应于输入数据是属于哪个类别的,而是必须通过反复试验来发现它们。 通常有一系列的状态和动作,学习算法在其中与相应的情景交互。 在很多情况下,当前的行为不仅会影响即时的奖励,还会影响后续的所有时间步骤的奖励。 例如,通过使用适当的强化学习技术,神经网络可以学习高水平地玩五子棋。 在这里,网络必须学会以一个棋盘局势作为输入,像掷骰子一样产生一些随机的结果,并选出一个较为好的落子方案作为输出。 这是通过计算机与自己进行左右互搏对抗实现的。 一个主要的挑战是中国象棋可能包含几十步, 然而,只有在游戏结束时,奖励才会出现,所以结果都会归因于导致它的所有动作 ,尽管有些下棋方案是好的,有些则不那么好。 这就是一个信用分配问题的例子 .强化学习的一个普遍特征是探索与探索之间的权衡,在这个过程中,系统会尝试一些新的行为,看看它们是否更有效,最终该系统利用已知的行为来获得最优解。 强化学习是机器学习研究的一个活跃领域。
虽然每个任务都需要相应的处理和技术, 但是支撑它们的许多关键思想都是相同的.本章的主要目标之一是以一种相对非正式的方式 进行介绍 ,并用几个简单的例子加以说明。 在本书的后面,我们将看到这些相同的思想在更复杂的模型上下文中重新出现,这些模型适用于实际的模式识别应用程序。 本书将会重点使用如下三个工具,即概率论,决策论 ,信息论.尽管这些听起来像是令人畏惧的话题,它们实际上很简单,如果要使机器学习技术在实际应用中发挥最佳效果,对它们有一个清晰的了解是必不可少的 .
例子:多项式曲线拟合
我们首先介绍一个简单的回归问题,我们将在本章中使用它作为一个运行示例来启发一些关键概念。假设我们观察输入变量x,我们希望用这个观察来预测一个变量t的输出.就目前而言,考虑一个生成数据的人工例子是有指导意义的,因为这样我们就知道了生成数据的精确过程,以便与任何学习的模型进行比较。 这个例子的数据生成的函数sin(2πx)与随机噪声的目标值,如Figure 1.2所示.
import numpy as np import matplotlib.pyplot as plt from prml.preprocess import PolynomialFeature from prml.linear import ( LinearRegression, RidgeRegression, BayesianRegression ) np.random.seed(1234) #创建随机数据 def create_toy_data(func, sample_size, std): #生成数据在0-1之间,sample_size个数据,包括1 x = np.linspace(0, 1, sample_size) #生成数据加上随机高斯噪声 t = func(x) + np.random.normal(scale=std, size=x.shape) #把x和t的值返回 return x, t #sin(2*π*x) def func(x): return np.sin(2 * np.pi * x) #产生训练数据和测试数据,标准差是0.25 x_train, y_train = create_toy_data(func, 10, 0.25) #测试数据:从0到1一共100个数据 x_test = np.linspace(0, 1, 100) #计算标准的测试数据的值 y_test = func(x_test) #绘制测试数据的点 plt.scatter(x_train, y_train, facecolor="none", edgecolor="b", s=50, label="training data") #绘制测试数据的线条 plt.plot(x_test, y_test, c="g", label="$\sin(2\pi x)$") #右上角显示名称 plt.legend() plt.show()
图例:训练数据集有十个蓝色的圆圈,每个包含一个输入变量x以及相应的目标变量t,绿色曲线显示了函数sin(2πx)用于生成数据。我们的目标是在不知道绿色曲线的情况下,预测x的某个新值的值。
现在假设我们有一个训练集包含N个x的观察值,写作 ,还有一些相应的t值的观测值,写作 .图1.2显示了包含10个训练数据的图。图1.2中的输入数据集x是通过选择[0,1]范围内均匀间隔的 的值生成的,n = 1,…N ,根据sin(2π)计算出相应的值,在加上一些随机的高斯噪声.通过以这种方式生成数据,我们捕获了许多实际数据集的属性 ,即它们具有潜在的规律性,这是我们想要了解的,但是个体的观察被随机噪声所破坏.这种噪声可能来自于本质上随机的过程,如放射性衰变,但更典型的是由于存在变异源,而这些变异源本身是无法观测到的。
我们的目标是利用这个训练集来预测给定新的计算出.我们稍后会看到,这涉及到隐式地试图发现底层函数sin(2πx) .这在本质上是一个难题,因为我们必须从有限的数据集中进行推广。 此外,观测数据被噪声破坏, 对于给定的 x,对于合适的值t存在不确定性 .概率论为以精确和定量的方式表达这种不确定性提供了框架和理论, 允许我们利用这种概率表示,以便根据适当的标准做出最优的预测。
然而,就目前而言,我们将进行相当非正式的讨论,并考虑一种基于曲线拟合的简单方法。特别地,我们将使用这种形式的多项式函数来拟合数据 :
其中M是多项式的阶数, 表示x的j次方。 多项式的系数 用向量w表示 .注意,虽然多项式函数y(x, w)是x的非线性函数,但它是系数w的线性函数。 函数,如多项式,在未知参数下是线性的,具有重要的性质,称为线性模型,将在第3章和第4章进行广泛的讨论。
通过对训练数据进行多项式拟合,确定各系数的取值。 这可以通过对于任意给定的w值,和训练集数据点 最小化测量函数y(x, w)之间不匹配的误差函数来实现,一个应用广泛的误差函数的简单选择是将每个数据点xn的预测值y(xn, w)与相应的目标值tn之间的误差平方和,从而使误差最小化
其中1/2的因数包含在内,方便以后求导使用。 我们将在本章后面讨论选择误差函数的动机。 平方和误差函数的几何解释如图1.3所示。
我们可以通过选择w的值来解决曲线拟合问题 ,误差函数是系数w的二次函数 ,求导后系数是线性的,所以误差函数的最小化有一个唯一解,写作 .所得多项式由该函数给出 y(x, ).
选择多项式的M阶仍然是一个问题 ,们将会看到这是一个重要概念的例子叫做模型比较或者模型选择。 在图1.4中,我们给出了四个例子,分别是M = 0,1,3,9阶多项式对数据集的拟合结果.
import numpy as np import matplotlib.pyplot as plt from prml.preprocess import PolynomialFeature from prml.linear import ( LinearRegression, RidgeRegression, BayesianRegression ) np.random.seed(1234) #创建随机数据 def create_toy_data(func, sample_size, std): #生成数据在0-1之间,sample_size个数据,包括1 x = np.linspace(0, 1, sample_size) #生成数据加上随机高斯噪声 t = func(x) + np.random.normal(scale=std, size=x.shape) #把x和t的值返回 return x, t #sin(2*π*x) def func(x): return np.sin(2 * np.pi * x) #产生训练数据和测试数据,标准差是0.25 x_train, y_train = create_toy_data(func, 30, 0.25) #测试数据:从0到1一共100个数据 x_test = np.linspace(0, 1, 100) #计算标准的测试数据的值 y_test = func(x_test) #不同次数的拟合 for i, degree in enumerate([0, 1, 3, 9]): #四张图,两行两列 plt.subplot(2, 2, i + 1) #转换具有多项式特征的输入数组 #[1,x,x^2...] feature = PolynomialFeature(degree) #分别求对应的多少次方 #[x_train^0,x_train^1,x_train^2,...] X_train = feature.transform(x_train) # 转换具有多项式特征的输入数组 X_test = feature.transform(x_test) #线性回归模型 model = LinearRegression() #最小二乘拟合 model.fit(X_train, y_train) #预测X_test y = model.predict(X_test) #绘制训练的点,蓝色 plt.scatter(x_train, y_train, facecolor="none", edgecolor="b", s=50, label="training data") #绘制测试的真实数据,绿色 plt.plot(x_test, y_test, c="g", label="$\sin(2\pi x)$") #绘制预测的数据,红色 plt.plot(x_test, y, c="r", label="fitting") #y轴范围 plt.ylim(-1.5, 1.5) #添加标注 plt.annotate("M={}".format(degree), xy=(0.5, 1)) #添加注释 plt.legend(bbox_to_anchor=(1.05, 0.64), loc=2, borderaxespad=0.) plt.show()
我们注意到常数(M = 0)和一阶多项式(M = 1),对数据的拟合程度非常差。 三阶多项式(M = 3)似乎给最适合的函数sin(2πx)的例子,当我们得到一个高阶多项式(M = 9)时,我们得到了对训练数据的良好拟合。 事实上,多项式精确地通过每个数据点 ,并且E( )=0,然而,拟合曲线振荡的疯狂,对于sin(πx)的拟合极差。这个就叫做过拟合.
如前所述,我们的目标是通过对新数据作出准确的预测来实现良好的泛化。我们可以定量考察模型的泛化性与M的关系。考察的⽅式为:考虑⼀个额外的测试集,这个测试集由100个数据 点组成,这100个数据点的⽣成⽅式与训练集的⽣成⽅式完全相同,但是在⽬标值中包含的随机 噪声的值不同。对于每个M的选择,我们之后可以⽤公式(1.2)计算训练集的E(w∗),也可以 计算测试集的E(w∗)。有时候使⽤均⽅根(RMS)误差更⽅便。这个误差由下式定义:
在这种情况下,除以N可以让我们平等地比较不同大小的数据集.图1.5显示了不同M值的训练集和测试集RMS错误图。
M是多项式的次数.
测试集误差是一种衡量我们在预测x的新数据观测值时t值的准确性的方法。 我们从图1.5中注意到,M的较小会导致较大的测试集误差,而M值较大,也会导致较大的测试集误差.
这似乎是矛盾的,因为一个给定阶的多项式包含所有的低阶多项式的大部分情况。 因此,M = 9多项式至少能够产生与M = 3多项式一样好的结果,但是为什么结果会更坏呢?我们知道一个函数的幂级数展开的sin(2πx)包含的所有序列,我们可能期望在增加M的次数之后,相应的误差会减小。
通过检查系数的值,我们可以对这个问题有一些了解,w*由不同阶的多项式得到,如在表1.1:
我们可以看到,当M不断增加的时候,系数的绝对值大小通常会变大。 特别是对于M = 9多项式, 通过产生较大的正值和负值,这些系数已经与数据很好地协调 使得多项式函数精确匹配每一个数据点, 但是在数据点之间(特别是在范围的两端),函数表现出图1.4中观察到的大振荡。直观地说,所发生的事情是,M值越大的多项式越灵活,它们对目标值上的随机噪声也就越敏感。
当数据集的大小不同时,研究给定模型的行为也很有趣 ,如在下图中所示:
我们看到, 对于给定的模型复杂度, 随着数据集的增大,过拟合问题变得不那么严重。 换句话说,数据集越大,我们能够适应的模型就越复杂(换句话说,就越灵活)。 有时提倡的一种粗略的启发式是,数据点的数量应该不少于模型中自适应参数数量的若干倍(例如5或10)。 然而,正如我们将在第3章中看到的,参数的数量不一定是模型复杂性的最合适度量。
此外,必须根据可用训练集的大小限制模型中的参数数量,这也有一些不太令人满意的地方。 根据所解决问题的复杂性来选择模型的复杂性似乎更为合理。 我们将看到,寻找模型参数的最小二乘方法代表了最大可能性的特定情况,过拟合问题可以理解为最大似然的一般性质。采用贝叶斯方法 可以避免过拟合问题。 我们将看到,从贝叶斯的角度来看,使用参数数量大大超过数据点数量的模型并不困难.在贝叶斯模型中,有效参数的数量自动适应数据集的大小。
然而,就目前而言,继续使用当前的方法并考虑如何在实践中将其应用于有限大小的数据集具有指导意义.在这种情况下,通常用来控制过拟合现象的一种技术是正则化, 这包括在误差函数(1.2)中添加一个惩罚项,以阻止系数达到较大的值。 最简单的这种惩罚项的形式是所有系数的平方和,从而得到该形式的修正误差函数 :
和系数λ控制正则化项的相对重要性与平方和误差项。 注意,系数w0经常在正则化器中被省略,因为它的包含导致结果依赖于目标变量的原点选择,或者它可以包含但是要有自己的正则化系数。同时,误差函数(1.4)可以精确地以闭合形式最小化。这样的技术在统计文献中称为收缩法,因为它们降低了系数的值。 二次正则化器的特殊情况称为岭回归。 在神经网络的背景下,这种方法被称为重量衰减。
图1.7给出了用(1.4)给出的正则化误差函数将M = 9阶多项式拟合到相同数据集的结果
我们看到,lnλ=−18时,过拟合被抑制了,我们现在获得一个更近的底层函数sin(2πx)的拟合。然而,如果我们把λ选择的过大,然后我们再次获得一个欠拟合线条,如图所示.拟合的多项式的对应的系数在表1.2中给出,表明正则 化在减⼩系数的值⽅⾯产⽣了预期的效果。
正则项的影响可以通过绘制均方根误差体现,可以很好地用于训练集和测试集 , 如图1.8所示。 我们可以看到,实际上λ可以的有效地控制模型的复杂性,因此决定了过拟合程度。
模型复杂性是一个重要的问题,将在1.3节中详细讨论。 这里我们只是注意到,如果我们试图用这种最小化误差函数的方法来解决实际应用,我们必须找到一种方法来确定模型复杂度的合适值。 上述结果提出了一种简单的方法来实现这一点,即把可用的数据分成一个训练集一个测试集, 训练集用于确定系数w,测试集用于优化模型的复杂度 .然而在许多情况下 ,将浪费很多宝贵的训练数据 ,而且我们也必须寻求更复杂的方法。
到目前为止,我们对多项式曲线拟合的讨论主要依靠直觉。 我们现在通过讨论概率论来寻求一种更有原则的方法来解决模式识别中的问题。 同时也为本书后来几乎所有的描述奠定了基础,这也将给我们一些重要的见解,我们已经介绍了在多项式曲线拟合的背景下的概念,并将允许我们扩展到更复杂的情况。