1. 关注

  2. 订阅

    订阅到:

面向开发人员的机器学习指南 机器学习的整体框架 实例 结论

李嚄   发布在 2017-01-10   

现如今,大多数的开发人员都听说过机器学习,但是当他们试图寻找捷径来学习这些技术时,却有很多人都对机器学习中的一些抽象概念望而却步,诸如回归监督学习概率密度函数其他许多定义。如果诉诸于书本,代表著作有《An Introduction to Statistical Learning with Applications in R》与《Machine Learning for Hackers》,其中的实例是用 R 语言实现的。

然而,R 实际上跟 Java、C#、Scala 等用于开发日常应用的编程语言不同。这也是本文采用 Smile 来介绍机器学习的原因,Smile 是关于机器学习的一个库,它可以在 Java 与 Scala 中使用,而这两种语言对大多数开发者来说至少是不陌生的。

第一部分“机器学习的整体框架”包含了学习下文应用实例要用到的所有重要概念。“应用实例”这一部分参考了《Machine Learning for Hackers》这本书的例子。另外,《Machine Learning in Action》这本书将用于验证。

第二部分“应用实例”包含了各种机器学习 (ML) 应用实例,以 Smile 作为 ML 库。

注意在本文中,“新”定义会添加超链接,以备读者了解该主题的更多相关内容,但是完成这些实例,并不需要阅读全部的内容。

最后,我想感谢以下这些人:

  • Haifeng Li : 感谢他给予的支持,还写了那么出色、且能免费使用的 Smile 库。
  • Erik Meijer: 感谢在我写这篇博文的时候他给予的建议与指导。
  • Richard van Heest 、Lars Willems: 感谢他们审阅了这篇博文并做了反馈。

机器学习的整体框架

也许你曾听说过机器学习这个概念。然而,如果要你向另一个人解释什么是机器学习,你要怎么做呢?在继续阅读之前,请先考虑一下这个问题。

机器学习有很多不同的定义方式,其中一些更加精确,然而,在这些定义中也有许多不一致之处。有些定义认为机器学习就是根据历史数据建立一个静态的模型,然后可以用于预测未来的数据。另一些则认为随着数据的增加,它是一个随时间不断变化的动态模型。

我是比较支持动态说的,但是由于某些限制,我们的实例只用来阐释静态的模型方法。不过,在动态机器学习这一节中,我们也对动态原则怎样运作做了解释。

接下来的这一部分给出了机器学习中常用的定义和概念。我们建议读者在进入应用实例的学习之前先通读这部分。

特征

一个特征就是用来训练模型的一种性质。例如,基于文字“买”和“钱”出现的频率可以把邮件分类为垃圾邮件和正常邮件。这些用来分类的单词就是特征,如果把它们与其他单词组合在一起,那它们就是特征的一部分。如果你想用机器学习来预测一个人是否是你的朋友,那么“共同的朋友”可以作为一个特征。注意,在这个领域中,特征有时也指属性

模型

一提到机器学习,模型是经常会碰到的一个术语。模型就是一种机器学习方法的结果以及该方法采用的算法。这个模型可以在监督学习中用来做预测,或者在监督学习中用来检索聚类。在这个领域中,在线训练离线训练这两个术语也有很大机会见到。在线训练指的是往一个已经存在的模型中添加训练数据,而离线训练指的是从头开始建立一个新模型。由于性能原因,在线训练方法是最可取的。然而,对某些算法来说,也有例外。

学习方法

在机器学习领域中,有两种前沿的的学习方式,也就是监督学习和监督学习,简要地介绍一下还是很有必要的,因为在机器学习的应用中,选择合适的机器学习方法和算法是一个重要而有时又有点乏味的过程。

监督学习

在监督学习中,你可以明确地定义要使用的特征,以及你预期的输出结果。例如,通过身高和体重预测性别,这是一个分类的问题。此外,你还可以通过回归分析预测绝对值。用同样的数据做回归分析的一个例子是通过性别和体重预测一个人的身高。某些监督算法只能用来解决分类问题和回归分析中的一种,例如 K-NN。不过也有一些算法如 Support Vector Machines 在两种情况下都适用。

分类

在监督学习的范围内,分类问题是相对简单的。考虑一组标签以及一些已经打上正确标签的数据,我们想要做的就是为新数据预测标签。然而,在把数据考虑为分类问题之前,你应该分析一下数据的特点。如果数据的结构明显可以让你轻松地画出一条回归线,那么应用回归算法反而会更好。如果数据法拟合出一条回归线,或者当算法的性能不理想时,那么分类就是一个很好的选择。

分类问题的一个例子是,根据邮件的内容把邮件分为正常或垃圾邮件。考虑一个训练组,其中的邮件被标为正常或垃圾,可以应用一个分类算法来训练模型。这个模型就可以用来预测未来的邮件是正常或是垃圾。分类算法的一个典型的例子是 K-NN 算法,分类问题的常用实例是将邮件分为垃圾邮件或正常邮件,这也是本文当中使用到的例子之一。

回归

回归要比分类要强大很多。这是因为,回归分析预测的是实际值而不是标签。一个简单的例子可以说明这一点。考虑一个表格,其中包含体重、身高和性别等数据,当给定一个体重和身高数据时,你可以应用 K-NN 算法来预测某人的性别。对这个同样的数据集使用回归分析,如果是给定性别以及其他各个缺失的参数,反过来,你可以预测某人的体重或身高。

能力越大,责任就越大,所以在用回归分析建立模型时必须格外小心。常见的陷阱是过拟合、欠拟合以及对模型如何控制外推法与内插法欠缺考虑。

监督学习

相比监督学习,监督学习不需要你事先确切地了解输出结果。应用监督学习的中心思想是发掘出一个数据集内在的结构。PCA 就是一个例子,它通过组合特征从而减小特征数。 组合过程基于这些特征之间可能隐含的关联。另一个监督学习的例子是 K-均值聚类。K-均值聚类就是要找出一个数据集中的分组,之后这些分组可以用于其他目的,例如用于监督学习中。

主成分分析(PCA)

主成分分析是统计学中的一种技术,它用于将一组相关列转化为较小的一组关列,以化简一个问题的特征数。这组较小的列就叫做主成分。这种技术主要用于探索性数据分析中,因为它揭示了数据中的内部结构,这样的结构法直观地看出来。

PCA 一个最大弱点就是数据中的异常值。这些异常值严重地影响了结果,所以,事先观察数据,排除较大的异常值能够极大地提高这种方法的性能。

为了清楚 PCA 到底是做什么用的,我们将一组二维点数据的图与同样数据经 PCA 处理后的图作了对比。

原始数据表示在左图中,其中每个颜色表示不同的类别。显然,这些数据可以从二维约化到一维之后,仍然能够恰当的分类。这就是 PCA 被提出的缘故了。根据每个数据点的原始维度,通过 PCA 可以计算出一个新的值来。

右图是对这些数据点应用了 PCA 后的结果。注意,这些数据有一个y值,但这纯粹是为了能够将数作图展示出来。所有这些数据点的Y值都是0,因为 PCA 算法只返回 X 值。同时注意,右图数据点中的 X 值并不对应左图中各点的X值,这表明 PCA 并不仅仅是“丢掉”一个维度。

验证技术

在这部分中我们会介绍一些用于模型验证的技术方法,以及一些与机器学习验证方法相关的专业术语。

交叉验证

交叉验证法是机器学习领域中最常用的验证方法之一。它的基本思想是,将原始数据分为训练集和验证集,先用训练集对模型进行训练,然后再用模型来预测验证集的数据。将预测值与实际值进行对比,以此来评价模型的性能和训练数据的质量。

这种交叉验证法最重要的环节是分割数据。应用这种方法时,应该始终使用整个数据集。换言之,你不可以随机选取 X 个数据点作为训练集然后随机选取X个数据点作为验证集,这样的话,在两个数据集中可能就有些点是重复的,而另一些点又没有被利用到。

2-折交叉验证

在2-折交叉验证中,每一“折”(所以要执行两次)都要将数据分割为验证集和训练集,用训练集训练模型,再用验证集做验证。这样做就可以在验证模型时计算两次误差。这些误差值不应该相差太大。万一差太大,那么不是你的数据有问题,就是你选来建立模型的特征有问题。论是哪种情况,你都应该再看看数据,找出具体的问题,因为以数据为基础来训练一个模型有可能因为错误数据而出现模型过度拟合的情况。

正则化

正则化的基本思想是,通过简化一个模型而防止它过度拟合。假设你的数据满足一个三次多项式函数,但是数据中有噪声,这会使模型函数的次数加高一级。于是,尽管模型刚开始好像不错,但碰到新的数据就表现不理想了。正则化通过一个特定的 λ 值来简化模型,有利于防止这种情况的发生。然而,要找到一个合适的 λ 值却不易,因为你不知道模型什么时候才会过度拟合。这也是交叉验证法经常被用来寻找适合模型的最佳 λ 值的原因。

精确率

计算机科学中,我们用精确率这个术语来描述相关的选中条目的数量。因此,当你计算一个文档搜索算法的精确率时,那个算法的精确率就定义为在设定的结果中有多少个文档是确实相关的。

这个值由下式算出:

掌握这个内容可能会有点难,所以我举个例子:

假设有一个完备的文档集 {aa,ab,BC,bd,ee},我们要查找名字带有 a 的文档。如果算法返回的文档集是 {aa,ab},那么直觉告诉我们精确率是100%。我们可以代入公式验证一下:

事实上就是100%。如果我们再查找一次,除了{aa,ab}这个结果,我们还得到{BC,de}这个结果,精确率就会受到影响如下:

这里,结果中包含了相关的结果,也包含了两个不相关的结果,导致精确率降低了。然而,如果给这个例子计算召回率,那它将是100%,这就是精确率与召回率之间的不同之处。

召回率

召回率是指,给定查找条件和一个数据集,算法检索到的相关条目的数量。因此,给定一组文档以及能够返回一个文档子集的查找条件,召回率就表示相关的文档中有多少被实际返回。召回率由下式计算:

我们举个例子看看如何应用该公式:

假设有一个完备的文档集 { aa, ab, BC, bd, ee },我们要查找名字带有a的文档。如果算法返回{aa,ab},那么召回率显然就是100%。我们可以代入公式验证一下:

事实上就是100%。下面我们看看如果算法只返回部分相关结果会怎么样:

这里,结果只包含一半的相关结果,导致召回率降低了。然而,如果计算这种情况下的精确率,结果是会100%,因为所有返回结果都是相关的。

先验

给定一个数据点,一个分类器的先验值代表了这个数据点属于该分类器的可能性大小。在实践中,这意味着当你在一个数据点处得到一个预测值时,先验值就表示模型对那个数据点的分类的确信度有多高。

均方根误差(RMSE)

均方根误差(RMSE 或 RMSD,D 代表 deviation,即偏差)是指对实际值与预测值之差先平方,再求均值,然后开方。我举个例子来解释一下好帮助理解。假设我们有以下数据:

Capture

模型的平方差的均值是 4.33333,该值的平方根是 2.081666. 因此,该模型的预测值的平均误差为 2.08。RMSE 值越低,模型的预测效果越好。这就是为什么在选择特征时,人们会分别计算包含和不包含某个特征的 RMSE 值,以判断那个特征是如何影响模型的性能的。通过这些信息,人们就可以确定,和模型的效率提升比起来,由于该特征值增加的额外的计算时间是否值得。

此外,因为 RMSE 值是一个绝对值,所以它可以归一化以进行模型之间的比较。这就是归一化均方根误差 (NRMSE)。然而,要计算这个值,首先要知道系统所包含的最小值与最大值。假设我们有一个最小值为 5 度、最大值为 25 度的温度范围,那么可用下式来计算 NRMSE 值:

若代入实际值,可得到如下结果:

那这个 10.4 表示什么呢?这是模型对数据点进行预测的平均误差百分数。

最后,我们可以利用 RMSE 值来计算拟合度 (R Squared)。拟合度反映的是,与各个值的平均值作比较(不考虑模型的情况),模型的预测效果有多好。我们首先要计算出平均法的 RMSE 值。对上文的表格最后一列值的取平均,结果是 4.22222,其平方根是 2.054805。首先注意到这个值比模型的值要小。这不是个好现象,因为这表明模型的预测效果比单单取平均值要差。然而,我们主要是演示怎么计算拟合度,所以我们继续计算过程。

现在,模型与平均法的 RSME 值都求出来了,接着用下式计算拟合度:

Formula2

代入实际值得到以下结果:

Formula3

那么,-1.307229 代表什么呢?它就是表示模型每次对一个值的预测效果比平均法差约 1.31%。换言之,在这个具体情况中,用平均法来做预测比用模型的效果要好。

常见陷阱

这部分要介绍的是在应用机器学习技术的过程中经常会碰到的问题,主要内容是向读者解析这些陷阱以帮助读者避开它们。

过度拟合

对数据进行拟合时,数据本身可能会包含噪声(例如有测量误差)。如果你精确地把每一个数据点都拟合进一个函数中,那你会把噪声也耦合到模型中去。这虽然能使模型在预测测试数据时表现良好,但在预测新数据时会相对较差。

把数据点和拟合函数画在图表中,下列左图反映过度拟合的情况,右图表示一条穿过数据点的回归曲线,它对数据点能够适当拟合

应用回归分析时容易产生过度拟合,也很容易出现在朴素贝叶斯分类算法中。在回归分析中,产生过度拟合的途径有舍入操作、测量不良和噪声数据。在朴素贝叶斯分类算法中,选定的特征可能导致过度拟合。例如,对垃圾和正常邮件的分类问题保留所有停用词。

通过运用验证技术、观察数据的统计特征以及检测和剔除异常值,可以检测出过度拟合。

欠拟合

当你对数据进行建模时,把很多统计数据都遗漏掉了,这叫做欠拟合。有很多原因可以导致欠拟合,例如,对数据应用不合适的回归类型。如果数据中包含了非线性结构,而你却运用线性回归,这就产生了一个欠拟合模型。下列左图代表了一条欠拟合的回归线,右图右图表示一条合适的回归线。

为了防止欠拟合,你可以画出数据点从而了解数据的内在结构,以及应用验证技术,例如交叉验证。

维度灾难

对于已知的数据量存在一个最大的特征数(维数),当实际用于建立机器模型的特征数超过这个最大值时,就产生维度灾难问题。矩阵秩亏就是这样的一种问题。普通最小二乘 (OLS) 算法通过解一个线性系统来建立模型。然而,如果矩阵的列数多于行数,那这个系统不可能有唯一解。最好的解决办法是获取更多数据点或者减小特征数。

如果读者想了解更多关于维度灾难的内容,可以参考一个关于这方面的研究。在这个研究中,研究人员 Haifeng Li,Keshu Zhang 和 Tao Jiang 发展一种用少量数据点改善肿瘤分类的算法。他们还将其与支持向量机和随机森林算法做了比较。

动态机器学习

在几乎所有你能找到的机器学习文献中,静态模型就是首先通过建立、验证流程,然后作预测或建议用途。然而在实践中,仅仅这样做还不足以应用好机器学习。所以,我们在这部分中将要介绍怎么样把一个静态模型改造成一个动态模型。因为(最佳的)实现是依赖于你所使用的算法的,所以我们将只作概念介绍而不给出实例了。鉴于文本解释不够清晰,我们首先用一个图表展示整个体系,然后用这个图表介绍机器学习以及如何做成一个动态系统。

机器学习的基本流程如下:

1、搜集数据

2、把数据分割为测试集和训练集

3、训练一个模型(应用某种机器学习算法

4、验证模型,验证方法需要使用模型和测试数据

5、基于模型作出预测。

在该领域的实际应用中,以上的流程是不完整的,有些步骤并未包含进去。在我看来,这些步骤对于一个智能学习系统来说至关重要。

所谓的动态机器学习,其基本思路如下:模型作出预测后,将预测信息连同用户反馈一起返回给系统,以改善数据集和模型。那么,这些用户反馈是怎么获得的呢?我们以为 Facebook 的朋友推荐为例。用户面临两种选择:“添加朋友”或“移除”。基于用户的决定,对于那个预测你就得到了用户的直接反馈。

因此,假设你获得了这些用户反馈,那么你可以对模型应用机器学习来学习这些用户反馈。听起来可能有点奇怪,我们会更详细地解释这一过程。然而在那之前,我们要做一个免责声明:我们关于脸书朋友推荐系统的解释是一个100%的假说,并且绝对没有经过脸书本身的证实。就我们所知,他们的系统对外是不公开的。

假设该系统基于以下特征进行预测:

1、共同朋友的数量
2、相同的户籍
3、相同的年龄

然后你可以为脸书上的每一个人计算出一个先验值,这个先验值描述了他/她是你的朋友的概率有多大。假设你把一段时间内所有的预测信息都存储下来,就可以用机器学习分析这些数据来改善你的系统。更详细地说,假设大多数的“移除好友”推荐在特征 2 上具有较高评级,但在特征 1 上评级相对较低,那么我们可以给预测系统加入权重系数,让特征 1 比特征 2 更重要。这样就可以为我们改善推荐系统。

此外,数据集随时间而增大,所以我们要不断更新模型,加入新数据,使预测更准确。不过,在这个过程中,数据的量级及其突变率起着决定性作用。

实例

在这部分中,我们结合实际环境介绍了一些机器学习算法。这些实例主要为了方便读者入门之用,因此我们不对其内在的算法作深入讲解。讨论的重点完全集中在这些算法的功能方面、如何验证算法实现以及让读者了解常见的陷阱。

我们讨论了如下例子:

基于下载/上传速度的互联网服务提供商标记法 (K-NN)
正常/垃圾邮件分类(朴素贝叶斯法)
基于内容的邮件排序(推荐系统)
基于身高预测体重(线性回归:普通最小二乘法)
尝试预测最畅销书排行(文本回归)
应用监督学习合并特征(主成分分析)
应用支持向量机(支持向量机)

我们在这些实例中都使用了 Smile 机器学习库,包括 smile-core 和 smile-plot 这两个库。这些库在 Maven, Gradle, Ivy, SBT 和 Leiningen 等工具上都是可用的。如何把这些库添加到这些工具中去,对于 core 库,参考这里,对于 plot 库,参考这里。

所以,在开始做这些实例之前,我假定你在自己最喜欢的 IDE 上建立了一个新项目,并把 smile-core 库和 smile-plot 库添加到了你的项目中。其他需要用到的库以及如何获取实例的数据会在每个例子中分别予以说明。

基于下载/上传速度的互联网服务供应商标记法(使用 K-NN 算法、Smile 库、Scala 语言)

这一部分的主要目标是运用 K 最近邻算法,根据下载/上传速度对将互联网服务供应商 (ISP) 分为 Alpha 类(由 0 代表)或 Beta 类(由 1 代表)。K-NN 算法的思路如下:给定一组已经分好类的点,那么,对新点的分类可以通过判别它的 K 个最近邻点的类别(K 是一个正整数)。K 个最近邻点可以通过计算新点与其周围点之间的欧氏距离来查找。找出这些邻近点,你就得到了最具代表性的类别,并将新点分到这一类别中。

做这一案例需要先下载示例数据。此外,还要把代码段中的路径改为你存储示例数据的地方。

首先要加载 CSV 数据文件。这没什么难的,所以我直接给代码,不做进一步解释:

(有话说)我的个性宣言

  懒于思索,不愿意钻研和深入理解,自满或满足于微不足道的知识,都是智力贫乏的原因。这种贫乏通常用一个字来称呼,这就是愚蠢。

社交评论

您好,请登录后进行评论。点击 登录注册新账号
您好!
    五色云科技