预测分析:R语言实现1.1 模型

1.1 模型

模型是预测分析学的核心,因此,本书一开始会讨论各种模型及其形式。简而言之,模型是我们要理解和分析的状态、流程或系统的一种表现形式。我们创建模型的目的是根据它得出推论以及(在本书中对我们更为重要的一点)对世界进行预测。模型的格式和风格有很多种,我们在本书中会探讨这种多样性中的一部分。模型可以是和我们能够观察或测量的数量值相关的一些方程,也可以是一套规则。我们大部分人在学校都熟悉的一个简单模型是牛顿第二运动定律。该定律表明,一个物体受到的合力会使之在合力作用的方向加速,加速度和合力大小成正比,和物体的质量成反比。

我们通常会用一个以字母F、m和a代表模型包含的量的方程总结这个规则。我们还利用大写希腊字母sigma (Σ)来表示要对受力求和,用字母上的箭头表示它们是向量(就是既有大小也有方向的量):

 

这个简单却强大的模型让我们能够对世界进行某些预测。例如,如果对已知质量的物体施加已知的作用力,我们就可以利用这个模型来预测它的加速度。如同大部分模型一样,该模型也会作出某些假设和概括。例如,它会假设物体的颜色、它所处环境的温度,以及它所处空间的准确坐标都和模型中列出的三个数值的相互影响无关。这样,模型就可以把待分析的流程或系统中的特定实例(在这个示例中,就是我们对其运动状况感兴趣的物体)的各种细节进行抽象化,从而把我们的关注点限制在重要的性质上。

牛顿第二运动定律并不是描述物体运动的唯一模型。物理学专业的学生很快会发现其他更复杂的模型,例如那些把相对论质量考虑进去的模型。总体而言,如果模型需要考虑更多数量的数值或具有更复杂的结构,它们往往就会更复杂。例如,非线性模型一般会比线性模型更复杂。在实际工作中,要决定采用哪个模型,并不仅仅是选择更复杂的模型而不是相对简单的模型那么简单。实际上,我们在本书中逐步讲解很多不同模型的过程中,会把这个问题作为核心主题反复进行讨论。为了直观地理解其中的道理,可以考虑一下这个案例:我们用来测量物体质量和施加作用力的设备是非常粗糙的。在这样的情况下,寄希望于采用更复杂的模型也许就没有什么意义,因为我们知道,由于输入中的这种噪声,这样的预测所额外增加的精确度对结果产生不了什么差别。我们需要采用更简单模型的另一种情况是,在应用中我们根本不需要更高的精确度。第三种情况是更复杂的模型涉及我们无法测量的数值。最后,如果因为复杂度的关系,模型会需要太长时间进行训练或预测,我们也不会使用更复杂的模型。

1.1.1 从数据中学习

在本书中,我们要学习的模型具有两种重要和本质的特征。第一个特征是我们不会用数学推理或逻辑归纳的手段从已知事实产生模型,也不会根据技术规范或商业规则来构建模型;相反,预测分析学领域是根据数据来构建模型的。更具体地说,我们会假设,对于要完成的任何具体预测任务,我们会把该任务以某种方式关联或以衍生出来的某些数据作为起点。例如,如果要创建一个预测某国各地全年降雨量的模型,我们也许已经收集了(或具备了收集的手段)关于不同地点降雨量的数据,同时会测量一些我们会关心的数值(例如海拔高度、经度和纬度)。我们创建的这个模型之所以有能力执行预测任务,是因为我们可以利用一组有限地点的降雨量测量数据的样例来预测我们没有收集过任何数据的地点的降雨量。

我们建立模型时所针对的问题的第二个重要特征是,在根据某些数据创建模型来描述特定现象的过程中,我们必然会遇到某些随机性的来源。我们称之为模型的随机成分(stochastic)或不确定成分(nondeterministic component)。有时候,我们要尝试建模的系统本身并不具有任何内在的随机性,而是数据包含了随机成分。数据中的随机来源的一个范例是在测量时对温度之类的数量进行读取时所产生的误差。不包含内在随机成分的模型称为确定型模型(deterministic model),比如牛顿第二定律就是这类模型的一个范例。随机模型则是假设在建模的过程中含有内在的随机源的模型。有时候,这种随机性的来源是来自这样一个事实:对最有可能影响系统的所有变量都进行测量是不可能的,因而我们只能利用概率来对其进行建模。纯粹随机模型的一个著名示例是扔一个六面无偏误的骰子。回顾一下,在概率中,我们使用随机变量(random variable)这个术语来描述某个实验或随机过程的特定结果值。在扔骰子示例中,我们可以定义随机变量Y作为每次扔骰子之后朝上的那一面的点数,由此产生了下面的模型:

 

该模型告诉我们,扔到一个特定数字(比如3)的概率是六分之一。注意,我们没有对具体扔骰子的结果进行明确的预测,相反,我们表明的是,每种结果出现的可能性是均等的。

概率是在日常交流中经常会用到,但有时也导致其准确含义产生混淆的一个术语。其实,对概率有很多不同的理解方式。两种常常被援引的解释方式是频率论概率(Frequentist probability)和贝叶斯概率(Bayesian probability)。频率论概率是和重复试验相关的,例如扔单面骰子。在这种情况下,如果该实验重复了无穷次,那么看到数字3的概率就是数字3出现的相对比例。贝叶斯概率则是和在看到特定结果时主观上置信或意外的程度相关的,因此可以用于对一次性事件赋予含义,例如某位总统候选人赢得大选的概率。在我们的扔骰子试验里,我们看到数字3时的意外程度和看到其他数字时是一样的。注意,在这两种情况下,我们讨论的仍然是同一个数字概率(1/6),而只是解释不同而已。

在扔骰子模型的情况下,我们没有任何变量需要测量。不过,在大部分情况下,我们会看到包含了一批需要测量的自变量的模型,而这些模型会用来对某个因变量进行预测。预测性建模依赖于很多不同的领域,因此,根据你所学习的具体学科,你会发现它关联了不同的一些领域。在展开讲解这个问题之前,让我们把一个数据集加载到R语言里。R语言预装了很多常被引用的数据集,我们要挑出其中可能最著名的一个,即鸢尾花数据集(iris data set)。

要查看R还绑定了哪些其他的数据集,我们可以利用data()命令获取一个数据集清单及每个数据集的简短描述。如果要修改一个数据集里的数据,我们可以把待分析的数据集名作为输入参数提供给data()命令,例如,data(iris)会重载iris数据集。

 

iris数据集由鸢尾花的3个不同品种的共150个样本的测量数据组成。在前面的代码中,我们可以看到对每个样本产生了4种测量值,分别是花瓣(petal)和萼片(sepal)的长度和宽度。iris数据集常被用来作为一个典型的标杆,用于评估根据前文中4种测量数据来预测鸢尾花样本品种的不同模型。花瓣长、花瓣宽、萼片长、萼片宽合在一起,在文献中会被称为特征(feature)、属性(attribute)、预测因子(predictor)、维度(dimension)或自变量(independent variable)。在本书中,我们会优先使用特征这个词,但其他术语也同样是可以用的。类似地,该数据框中的品种(species)列是我们要利用模型来进行预测的,因此它被称为因变量(dependent variable)、输出(output)或目标(target)。同理,为了保持一致性,在本书中我们会优先使用其中之一,即输出。该数据框的每一行对应单个数据点,被称为一条观测数据(observation),不过它通常会包括对一组特征的观测值。

由于我们将要用到一些数据集(比如前面讲解的iris数据集)来构建预测模型,因此设定一些符号惯例会大有帮助。这里要讲解的惯例在大部分文献里很常见。我们会用大写字母Y来代表输出变量,带下标的大写字母Xi来表示第i个特征。例如,在我们的iris数据集里,我们有4个特征,分别表示为X1到X4。我们会用小写字母表示单条观测数据,因此x1就对应第一条观测数据。注意,x1本身是由特征分量xij组成的一个向量,因此x12就代表第一条观测数据中的第二个特征值。为简单起见,我们会尽量谨慎使用双后缀,也不会使用箭头或其他向量标记的形式。通常情况下,我们会讨论观测数据或特征两者之一,因此变量的大小写就能让读者明确到底它指的是这两种情况中的哪一个。

在考虑对应某个数据集的预测模型时,我们通常会假设,对于具有n个特征的模型,有一个真实或理想的函数f可以把特征映射到输出:

 

我们会把这个函数称为目标函数(target function)。在实践中,我们只能用可以获得的数据来训练我们的模型,这就需要创建我们自己的函数,寄希望于它对于目标函数是个良好的评估。我们可以通过在符号f上插入符号“^”来表示我们的预测函数,对于输出Y也同样是如此表示的,因为我们的预测函数的输出就是预测的输出。不幸的是,对于所有(我们数据中的或一般情况下的)观测数据而言,我们的预测输出并不总是和实际输出相符:

 

有了这些背景,我们基本上就可以把预测建模的过程总结为:创建一个函数来预测数量值,并使它产生的相对目标函数的误差最小化。到这里我们能问的一个好问题就是,误差是从何而来?换句话说,为什么我们通常无法通过分析一个数据集,准确地重现它背后的目标函数?

这个问题的答案是:在现实情况下,有几种潜在的误差源是我们必须面对的。记住,数据集里的每条观测数据包含了n个特征的值,因此我们可以把观测数据看作几何学中n维特征空间里的点。在这个空间里,根据目标函数的确切定义,我们的目标函数必须经过这些点。如果现在思考用一个函数来拟合有限个点的一般性问题,我们会很快发现,实际上有无限个函数可以通过这些点的集合。预测建模的过程会涉及我们用于数据的模型类型的选择,因而会限定我们用于拟合数据的目标函数的范围。同时,无论我们选择什么模型,数据内在的随机性都无法消除。这些思想就引出了建模过程中会遇到的误差类型的重要差别,具体而言,它们可以分为可化简误差(reducible error)和不可化简误差(irreducible error)。

可化简误差本质上是预测建模者能够通过选择模型结构使之最小化的误差,选择的模型应该能对要建模的过程作出有效的假设,且其预测函数和基础目标函数的形式相同。例如,我们在下一章会看到,线性模型会给特征值之间加入一个线性关系来产生输出。这个约束性的假设意味着无论我们采用什么训练方法,拥有多少数据,投入多少计算能力,如果在现实世界里的特征并非线性相关,那么我们的模型就必然对某些观测数据产生误差。反过来,一个不可化简误差的示例是当我们尝试根据不充分的特征集来创建模型时产生的。这种误差通常是普遍的而不是异常情况下的。通常,发现要采用哪些特征是创建精确模型的工作中最耗时的活动。

有时候,我们知道的重要特征不一定能直接测量。其他时候,要收集太多特征的数据也许就是不现实的或者成本太高了。此外,这类问题的解决办法也不仅仅是尽可能增加特征的问题。给模型增加更多特征会让它变得更复杂,而且还存在因为引入和输出无关的特征而给模型里加入噪声的风险。这样还意味着我们的模型函数会有更多的输入,因而变成在更高维空间里的函数。给一个模型加入更多特征的一些潜在的实际后果包括:增加训练模型所需的时间,增大收敛到最终解决方案的难度,以及在特定情况下(例如特征值是高度相关的)实际上会降低模型的精确度。最后,另一个我们必须接受的不可化简误差来源是测量特征产生的误差,即数据本身可能就是有噪声的。

为了使可化简误差最小化,不仅要选择合适的模型,也要确保模型的训练是正确的。因此,可化简误差也可能源于没有找到适用于模型假设的特定函数。例如,即使我们准确地选择了对一个线性模型进行训练,我们可以使用的特征也会有无限多的线性组合。正确地选择模型的参数(在该示例中就是线性模型的系数)也是使可化简误差最小化的一个方面。当然,准确训练模型的一个重要部分是利用良好的优化过程来对模型进行拟合。在本书中,我们对要学习的每个模型的训练方式至少会给出一个总体性的直观讲解。总体上,我们会避免深入钻研优化过程的数学原理,但是会为感兴趣的读者提供相关文献作为参考资料。

1.1.2 模型的核心组成部分

到目前为止,我们已经明确了模型背后的一些核心概念,以及讨论数据的通用语言。在本节,我们要了解统计学模型的核心组成部分有哪些。这些主要组成部分通常是:

带有需要调优参数的一组方程

代表我们建模所针对系统或过程的一些数据

描述该模型拟合优度的一个概念

更新参数以改善该模型拟合优度的一种方法

正如我们会在本书中看到的,像神经网络、线性回归和支持向量机这样的大部分模型都有描述它们的特定参数化方程。让我们来观察一个要根据3个我们称为X1、X2和X3的输入特征来预测输出Y的线性模型:

 

该模型正好是用一个方程描述的,并且该方程提供了模型的线性结构。该方程由4个参数(在本例中也称为系数)进行了参数化。在下一章,我们会看到这些参数扮演的确切角色,但是对于目前的讨论,重要的是注意到线性模型是参数化模型的一种样例。参数集合通常会比可用的数据量小得多。

有了一组方程和一些数据,我们就可以来讨论模型的训练了。它涉及为模型的参数赋值,从而让模型更精确地描述这些数据。我们通常会运用特定的标准衡量指标来表示模型对数据的拟合优度,也就是模型描述训练数据的精确程度。训练过程通常是一个涉及对数据进行计算的迭代程序,通过它可以为参数计算新值,从而增加该模型的拟合优度。例如,一个模型可能有一个目标或误差函数。通过对它求微分并设置微分为零,我们就可以找到产生最小误差的参数组合。一旦我们完成这个过程,就称该模型为完成训练的模型,并称该模型根据数据进行了学习。这些术语是从机器学习学科派生出来的,虽然通常在统计学学科也有类似的说法,而统计学对于该过程也有自己的术语。在本书里主要会采用来自机器学习领域的术语。

1.1.3 我们的第一个模型:k近邻

为了正确地理解本章的某些思想,我们会讲解本书的第一个模型,即k近邻模型,它通常简称为kNN。简而言之,这种简单的方法实际上会避免构建一个明确的模型来表示数据中的特征如何组合从而产生一个目标函数。相反,它依赖于一个概念,也就是如果我们要对之前没有见过的数据点进行预测,就要在原始训练数据中查找k个和新数据点最相似的观测数据。然后就可以针对已知的这k个邻居的目标函数值,利用某种求均值的技术来计算出一个预测值。让我们利用iris数据集,通过示例的方式来理解这个思路。假设我们收集了一份未识别的新鸢尾花样本,它具有如下测量值:

 

我们打算采用kNN算法来预测应该用鸢尾花的哪个品种来标识新样本。运用kNN算法的第一步,是确定新样本的k个最邻近样本。为此,我们要给出关于两条观测数据之间相似性的更准确定义。常用的方法是计算特征空间里两条观测数据之间的数量化距离。直觉上,两个相似的观测数据会在特征空间里相互接近,因此它们之间的距离会比较小。要在特征空间里计算两条观测数据之间的距离,我们经常利用欧几里得距离(Euclidean distance),它是两点之间直线的长度。两条观测数据x1和x2之间的欧几里得距离的计算方法如下:

 

回想一下,在前面的公式里的第二个下标j对应的是第j个特征。因此,这个公式实质上是告诉我们,对于每个特征,取两条观测数据之差的平方,并把所有这些平方差叠加,然后对结果取平方根。距离还会有其他的很多种定义,但这一种是在kNN领域最常见到的。我们会在第11章里看到更多的距离衡量指标。

为了给鸢尾花新样本找到最邻近样本,我们就必须计算它到iris数据集里每个点的距离,然后对结果进行排序。首先,对鸢尾花数据构造子集,让它只包含我们需要的特征,这样就排除了品种(species)列,而这一列正是我们想要预测的。然后,要自定义一个函数来计算欧几里得距离。下一步,调用apply()函数,运用自定义函数来对数据框里的每个鸢尾花观测数据进行计算。最后,调用R语言的sort()函数,并设定其index.return参数为TRUE,这样就可以把每个计算的距离和它在鸢尾花数据框里的行号索引对应起来。

 

 

$x属性包含了鸢尾花新样本和鸢尾花数据框里的观测数据之间计算距离的实际值。$ix属性则包含了对应观测数据的行号。如果要找出距离最近的5个邻居,我们就可以把$ix属性中的前5个数据项作为行号,对原始的鸢尾花数据框划分子集:

 

 

正如我们所见,5个最邻近的新样本中有4个属于versicolor品种,而另一种是virginica品种。对于这类要挑出一个类别标签的问题,可以把多数票作为计算均值的技术,从而得出我们的最终预测。因此,我们会把新样本标记为属于versicolor品种。注意,设定k的值为奇数是一个好的思路,因为这样需要应付票数平局问题的可能性更小(在输出的标签数为2时,则完全消除了平局)。对于票数平局的情况,惯例上的解决办法是在票数平局的标签中进行随机抽取。注意,在该过程中,我们根本没有尝试去说明这4个特征是如何与输出相关联的。因此,我们经常把kNN模型称为一种惰性学习方法(lazy learner),因为实际上它只是记住了训练数据,并在预测过程中直接使用它。对于kNN模型,还有更多内容可以讨论,但首先我们要回到关于模型的一般性讨论,并讲解对模型进行分类的不同方式。

上一篇:微信小程序[电商]-Tabbar 实现底部导航栏


下一篇:《Splunk智能运维实战》——2.12 小结