1 人工智能简介
在本章中,我们将讨论人工智能(AI)的概念及其在现实世界中的应用。 我们在日常生活中花费了大量时间与智能系统进行交互。 这可以采取以下形式:在互联网上搜索某些内容,进行生物特征识别的人脸识别或将口语单词转换为文本。 人工智能是这一切的核心,它正在成为我们现代生活方式的重要组成部分。 所有这些系统都是复杂的实际应用,而 AI 通过数学和算法解决了这些问题。 在整本书中,我们将学习可用于构建此类应用的基本原理。 我们的总体目标是使您能够应对日常生活中可能遇到的具有挑战性的新 AI 问题。
到本章末,您将了解:
- 什么是人工智能,为什么我们需要学习它?
- 人工智能有哪些应用?
- 人工智能分支的分类
- 机器学习的五个流派
- 什么是图灵测试?
- 什么是理性智能体?
- 什么是一般问题解决器?
- 如何建立智能体
- 如何安装 Python3 和相关包
什么是 AI?
如何定义 AI 可能会有很大差异。 从哲学上讲,什么是“智能”? 一个人如何感知智能又定义了它的人为对应物。 对 AI 领域的广泛而乐观的定义可能是:“计算机科学领域,它研究机器如何执行通常需要有知觉的智能体的任务。” 从这样的定义可以说,像计算机乘以两个数字这样简单的东西就是“人工智能”。 这是因为我们设计了一种能够接受输入并独立产生逻辑输出的机器,而该逻辑输出通常需要有生命的实体进行处理。
更具怀疑性的定义可能更狭窄,例如:“研究机器如何紧密模仿人类智能的计算机科学领域”。 根据这样的定义,怀疑论者可能会认为我们今天所拥有的不是人工智能。 到目前为止,他们已经能够指出计算机无法执行的任务的示例,因此声称如果计算机不能令人满意地执行这些功能,它们将无法“思考”或展现人工智能。
本书倾向于更乐观的 AI 观,我们更喜欢惊叹于计算机当前可以执行的任务数量。
在我们前面提到的乘法任务中,如果两个数字足够大,那么计算机肯定会比人类更快,更准确。 目前在其他领域,人类可以比计算机表现更好。 例如,人类可以通过几个示例来识别,标记和分类对象,而当前计算机可能需要数千个示例才能以相同的准确率执行。 研究和改进工作一直在不懈地进行,我们将继续看到计算机能够解决越来越多的问题,而几年前,我们只能梦想着解决它们。 随着本书的发展,我们将探索许多这些用例并提供大量示例。
考虑人工智能领域的一种有趣方式是,从某种意义上讲,人工智能是科学的又一分支,正在研究我们所知道的最迷人的计算机:大脑。 借助 AI,我们试图在计算中反映大脑的某些系统和机制,从而发现自己从诸如神经科学的领域中借鉴并与之互动。
为什么我们需要学习 AI?
人工智能可以影响我们生活的各个方面。 AI 领域试图了解实体的模式和行为。 借助 AI,我们希望构建智能系统并理解智能的概念。 我们构建的智能系统对于理解像我们的大脑这样的智能系统如何构建另一个智能系统非常有用。
让我们看一下我们的大脑如何处理信息:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zeHE5INH-1681568559562)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_01_01.png)]
图 1:基本的大脑成分
与已经存在了数百年的数学或物理学等其他领域相比,人工智能还处于起步阶段。 在过去的几十年中,人工智能生产了一些引人注目的产品,例如自动驾驶汽车和可以行走的智能机器人。 根据我们前进的方向,很明显,获得智能将在未来几年对我们的生活产生重大影响。
我们不禁要问,人类的大脑如何如此轻松地做到这一点。 我们可以用大脑识别物体,理解语言,学习新事物并执行许多更复杂的任务。 人脑如何做到这一点? 对于这个问题,我们还没有很多答案。 当您尝试使用机器复制大脑执行的任务时,您会发现它落后了! 在许多方面,我们自己的大脑比机器复杂得多,能力也更强。
当我们尝试寻找诸如外星生命或时空旅行之类的事物时,我们不知道这些事物是否存在; 我们不确定这些追求是否值得。 关于 AI 的好处是它已经存在理想化的模型:我们的大脑是智能系统的圣杯! 我们要做的就是模仿它的功能,以创建一个智能系统,该系统可以执行与我们的大脑相似或更好的事情。
让我们看看如何通过各种处理级别将原始数据转换为智能:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KmTttMAg-1681568559563)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_01_02.png)]
图 2:将数据转换为智能
我们想学习 AI 的主要原因之一是使许多事情自动化。 我们生活在一个世界:
- 我们处理海量且无法克服的数据。 人脑无法跟踪这么多数据。
- 数据同时来自多个来源。 数据是杂乱无章的。
- 从这些数据中获得的知识必须不断更新,因为数据本身一直在变化。
- 传感和驱动必须实时,高精度地运转。
即使人脑擅长分析我们周围的事物,也无法跟上上述条件。 因此,我们需要设计和开发可以做到这一点的智能机器。 我们需要可以实现以下目的的 AI 系统:
- 以有效的方式处理大量数据。 随着云计算的出现,我们现在能够存储大量数据。
- 同时从多个源提取数据,没有任何滞后。 对数据进行索引和组织,以使我们能够获得见解。
- 从新数据中学习,并使用正确的学习算法不断进行更新。 根据情况实时思考和应对情况。
- 继续执行任务,而不会感到疲劳或需要休息。
人工智能技术正在积极地用于使现有机器更智能,以便它们可以更快,更高效地执行 。
AI 的分支
了解 AI 的各个研究领域非常重要,这样我们才能选择正确的框架来解决给定的现实世界问题。 有几种方法可以对 AI 的不同分支进行分类:
- 监督学习与无监督学习与强化学习
- 人工智能与狭义智能
- 按人体功能:
- 机器视觉
- 机器学习
- 自然语言处理
- 自然语言生成
接下来,我们介绍一个常见的分类:
- 机器学习和模式识别:这也许是目前最流行的 AI 形式。 我们设计和开发可以从数据中学习的软件。 基于这些学习模型,我们对未知数据进行预测。 这里的主要限制之一是这些程序仅限于数据的特征。 如果数据集很小,那么学习模型也将受到限制。 让我们看看典型的机器学习系统是什么样的:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yaPEv0Ou-1681568559564)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_01_03.png)]
图 3:典型的计算机系统
当系统接收到以前看不见的数据点时,它将使用先前看过的数据(训练数据)中的模式来推断该新数据点。 例如,在人脸识别系统中,该软件将尝试匹配眼睛,鼻子,嘴唇,眉毛等的图案,以便在现有用户数据库中找到人脸。
- 基于逻辑的 AI :数学逻辑用于在基于逻辑的 AI 中执行计算机程序。 用基于逻辑的 AI 编写的程序基本上是一组逻辑形式的语句,用于表达有关问题域的事实和规则。 它广泛用于模式匹配,语言解析,语义分析等。
- 搜索:AI 技术中广泛使用搜索技术。 这些程序检查了许多可能性,然后选择了最佳路径。 例如,在策略游戏中,例如国际象棋,网络,资源分配,调度等,经常使用它。
- 知识表示:必须以某种方式表示关于我们周围世界的事实,以便系统能够理解它们。 这里经常使用数学逻辑语言。 如果有效地表示知识,则系统可以变得越来越智能。 本体论是一个紧密相关的研究领域,涉及存在的各种对象。 它是域中存在的实体的属性和关系的正式定义。 通常使用分类法或的层次结构完成此操作。 下图显示了信息和知识之间的区别:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kdmZVjjk-1681568559564)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_01_04.png)]
图 4:信息与知识
- 计划:此字段用于优化计划,从而以最小的成本为我们带来最大的回报。 这些软件程序从有关情况的事实和目标说明开始。 这些程序还了解世界的事实,因此他们知道规则是什么。 他们从这些信息中得出实现目标的最佳方案。
- 启发式:启发式是用于解决给定问题的技术,该技术在短期内解决该问题是实用且有用的,但不能保证是最优的。 这更像是对应该采用何种方法解决问题的有根据的猜测。 在 AI 中,我们经常遇到无法检查所有可能性以选择最佳选项的情况。 因此,我们需要使用启发式方法来实现目标。 它们在机器人,搜索引擎等领域的 AI 中得到了广泛使用。
- 遗传编程:遗传编程是一种通过使程序配对并选择最适合的条件来获取程序来解决任务的方法。 程序被编码为一组基因,使用一种算法来获得可以很好地执行给定任务的程序。
机器学习的五个流派
机器学习可以通过各种方式进一步分类。 我们最喜欢的分类之一是 Pedro Domingos 在他的书主算法中提供的分类。 在他的书中,他根据萌芽了思想的科学领域对机器学习进行了分类。 例如,遗传算法起源于生物学概念。 以下是完整的分类,Domingos 为流派使用的名称,每个流派使用的主要算法以及值得注意的支持者:
流派 | 来源 | 主导算法 | 支持者 |
---|---|---|---|
符号主义者 | 逻辑与哲学 | 反演 | Tom Mitchell、Steve Muggleton、Ross Quinlan |
连接主义者 | 神经科学 | 反向传播 | Yan LeCun、Geoffrey Hinton、Yoshua Bengio |
进化论者 | 生物学 | 基因编程 | John Koza、John Holland、Hod Lipson |
贝叶斯 | 统计 | 概率推断 | David Heckerman、Judea Pearl、Michael Jordan |
模拟器 | 心理学 | 内核机器 | Peter Hart、Vladimir Vapnik、Douglas Hofstadter |
符号主义者:符号主义者使用归纳或反演的概念作为主要工具。 当使用归纳法时,逆推演不是从前提和结论开始,而是从一系列前提和结论开始,然后反向进行以填补缺失的部分。
推论的一个例子:
苏格拉底是人类 所有人类都是凡人=可以推断出什么? (苏格拉底是凡人)
归纳示例:
苏格拉底是人类 ?? =苏格拉底是凡人(人类是凡人?)
连接主义者:连接主义者使用大脑,或者至少是我们对大脑的粗略了解,作为主要工具-主要是神经网络。 神经网络是一种算法,可以在大脑之后粗略地建模,旨在识别模式。 他们可以识别向量中包含的数字模式。 为了使用它们,需要将所有输入(例如图像,声音,文本或时间序列)转换为这些数字向量。 很难打开杂志或新闻网站,而不阅读“深度学习”示例。 深度学习是神经网络的一种特殊类型。
进化论者:进化论者专注于使用进化,自然选择,基因组和 DNA 突变的概念,并将其应用于数据处理。 进化算法将不断变异,进化并适应未知条件和过程。
贝叶斯:贝叶斯将集中在使用概率推断来处理不确定性上。 视觉学习和垃圾邮件过滤是贝叶斯方法解决的一些问题。 通常,贝叶斯模型将采用假设并应用一种“先验”推理,假设某些结果更有可能出现。 然后,他们在看到更多数据时会更新假设。
模拟器:模拟器着重于发现示例之间相似之处的技术。 最著名的模拟器模型是 K 最近邻算法。
使用图灵测试定义智能
传说中的计算机科学家和数学家阿兰·图灵提出了图灵测试以提供智能的定义。 这是测试计算机是否可以学习模仿人类行为的测试。 他将聪明的行为定义为在对话中达到人类智能的能力。 这种表现应该足以诱使询问者认为答案来自人。
为了查看机器是否可以做到这一点,他提出了一个测试设置:他提议人类应该通过文本界面来询问机器。 另一个限制是,人不能知道谁在询问的另一端,这意味着它可以是机器,也可以是人。 为了启用此设置,人员将通过文本界面与两个实体进行交互。 这两个实体称为受访者。 其中一个将是人类,另一个将是机器。
如果询问机无法告诉答案是来自机器还是人,则应答机通过测试。 下图显示了图灵测试的设置:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FoNYYagp-1681568559564)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_01_05.png)]
图 5:图灵测试
可以想像,对于响应方的机器而言,这是一项艰巨的任务。 对话期间发生了很多事情。 至少,机器必须精通以下内容:
- 自然语言处理:机器需要此语言才能与询问器通信。 机器需要解析句子,提取上下文并给出适当的答案。
- 知识表示:机器需要存储在询问之前提供的信息。 它还需要跟踪在对话过程中提供的信息,以便它再次出现时可以做出适当的响应。
- 推理:对于机器来说,了解如何解释所存储信息的很重要。 人们倾向于自动执行此操作,以便实时得出结论。
- 机器学习:这是所必需的,以便机器可以实时适应新条件。 机器需要分析和检测模式,以便得出推断。
您一定想知道为什么人类要与文本界面进行通信。 根据图灵的说法,人的物理模拟对于智能是不必要的。 这就是图灵测试避免人与机器之间直接进行物理交互的原因。
还有另一种叫做总图灵测试的东西,它涉及视觉和运动。 要通过此测试,机器需要使用计算机视觉并使用机器人在周围移动来查看物体。
使机器像人一样思考
数十年来,我们一直在尝试让机器更像人类那样思考。 为了实现这一目标,我们首先需要了解人类的想法。 我们如何理解人类思维的本质? 做到这一点的一种方法是记下我们对事情的反应。 但这很快就变得棘手,因为有太多事情需要注意。 这样做的另一种方法是根据预定义的格式进行实验。 我们提出了一定数量的问题,以涵盖各种各样的人类主题,然后看看人们如何回应。
一旦收集了足够的数据,我们就可以创建一个模型来模拟人类过程。 该模型可用于创建可以像人类一样思考的软件。 当然,这说起来容易做起来难! 我们关心的只是给定输入的程序输出。 如果程序的行为与人类行为相匹配,那么我们可以说人类具有类似的思考机制。
下图显示了不同层次的思维以及我们的大脑如何对事物进行优先排序:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yAIFBPZ0-1681568559565)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_01_06.png)]
图 6:思想水平
在计算机科学内部,有一个名为认知模型的研究领域,该领域致力于模拟人类的思维过程。 它试图了解人类如何解决问题。 它需要进入解决问题过程的思维过程,并将其转变为软件模型。 然后可以使用此模型来模拟人类行为。
认知建模用于各种 AI 应用,例如深度学习,专家系统,自然语言处理,机器人等。
建立理性智能体
人工智能的许多研究都集中在构建理性主体上。 什么是理性智能体? 在此之前,让我们在 AI 的上下文中定义合理性一词。 合理性是指遵守一组规则并遵循其逻辑含义以实现理想的结果。 这需要以使执行该操作的实体获得最大利益的方式执行。 因此,如果在给定的一组规则下采取行动以实现其目标,则该行动者被称为理性行动。 它只是根据可用信息感知并采取行动。 当将机器人发送到未知地形时,该系统在 AI 中被大量用于设计机器人。
我们如何定义理想的是什么? 答案是,这取决于智能体的目标。 该智能体应该是智能且独立的。 我们希望赋予适应新情况的能力。 它应该了解其环境,然后采取相应行动,以实现符合其最大利益的结果。 最大的利益取决于它要实现的总体目标。 让我们看看如何将输入转换为动作:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mg8DB2ts-1681568559565)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_01_07.png)]
图 7:将输入转化为行动
我们如何定义理性智能体的表现指标? 也许有人会说它与成功的程度成正比。 设置智能体以完成任务,因此表现度量取决于该任务完成的百分比。 但是我们必须考虑什么构成了整体的合理性。 如果只是结果,我们不考虑导致结果的行动。
做出正确的推断是理性的一部分,因为主体必须理性地行动以实现其目标。 这将有助于它得出可以连续使用的结论。
但是,在没有可证明的正确事情要做的情况下呢? 在某些情况下,智能体不知道要做什么,但它仍然必须做一些事情。
让我们设置一个方案,使最后一点更加清楚。 想象一下,一辆无人驾驶汽车以每小时 60 英里的速度行驶,突然有人越过它。 对于本示例,假设给定汽车行驶的速度,则只有两种选择。 汽车要么撞向护栏,要么就知道会杀死汽车乘员,要么撞向行人并杀死他们。 正确的决定是什么? 该算法如何知道该怎么做? 如果您在开车,您会做什么吗?
现在,我们将学习理性智能体的最早示例之一-通用问题解决器。 就像我们将看到的那样,尽管它的名称很高大,但它确实无法解决任何问题,但是由于它,它在计算机科学领域是一个巨大的飞跃。
通用问题解决器
通用问题解决器(GPS)是由 Herbert Simon,J.C. Shaw 和 Allen Newell 提出的 AI 程序。 它是 AI 世界中第一个有用的计算机程序。 目的是使其能够作为通用的问题解决机器。 当然,以前有很多软件程序,但是这些程序执行特定的任务。 GPS 是第一个旨在解决任何一般问题的程序。 GPS 应该针对每个问题使用相同的基本算法来解决所有问题。
您一定已经意识到,这是艰巨的战斗! 为了对 GPS 进行编程,作者创建了一种新语言,称为信息处理语言(IPL)。 基本前提是使用一组格式正确的公式来表达任何问题。 这些公式将成为有多个源和汇的有向图的一部分。 在图中,源是指起始节点,宿是指终止节点。 对于 GPS,源是公理,汇是结论。
即使 GPS 只是通用的,它也只能解决明确定义的问题,例如证明几何和逻辑上的数学定理。 它还可以解决单词拼图和下棋。 原因是这些问题可以在合理范围内形式化。 但是在现实世界中,由于您可以采取多种可能的途径,因此这很快变得很棘手。 如果它试图通过计算图中的步数来强行解决问题,则完全无法计算 。
使用 GPS 解决问题
让我们看看如何构造一个给定的问题以使用 GPS 解决它:
- 第一步是定义目标。 假设我们的目标是从杂货店里买些牛奶。
- 下一步是定义前提条件。 这些前提条件与目标有关。 要从杂货店获取牛奶,我们需要有一种运输方式,杂货店应该有牛奶。
- 此后,我们需要定义运算符。 如果我的交通工具是汽车,并且汽车的燃油不足,那么我们需要确保可以向加油站付款。 我们需要确保您可以在商店购买牛奶。
运算符要注意条件以及影响条件的一切。 它由行动,前提条件和采取行动引起的变化组成。 在这种情况下,操作就是向杂货店捐款。 当然,这首先要取决于您有钱,这是前提。 通过给他们钱,您正在改变您的金钱状况,这将导致您得到牛奶。
如果您可以像我们刚才那样解决问题,GPS 将会起作用。 限制在于它使用搜索过程来执行其工作,这对于任何有意义的现实应用而言都过于复杂且耗时。
在本节中,我们了解了什么是理性主体。 现在,让我们学习如何使这些理性主体更加智能和有用。
建立智能体
有很多方法可以将智能传递给智能体。 最常用的技术包括机器学习,存储的知识,规则等。 在本节中,我们将重点关注机器学习。 在这种方法中,我们通过数据和训练来向智能体赋予情报。
让我们看看智能体如何与环境交互:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QTDDKP5d-1681568559566)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_01_08.png)]
图 8:智能体与其环境的交互
通过机器学习,有时我们希望对机器进行编程以使用标记的数据来解决给定的问题。 通过浏览数据和相关标签,机器学习了如何提取模式和关系。
在前面的示例中,智能体依赖于学习模型来运行推理引擎。 传感器感知到输入后,会将其发送到特征提取模块。 一旦提取了相关特征,训练有素的推理引擎将基于学习模型执行预测。 该学习模型是使用机器学习构建的。 然后,推理引擎做出决定并将其发送给执行器,执行器随后在现实世界中采取所需的操作。
今天存在许多机器学习的应用。 它用于图像识别,机器人技术,语音识别,预测股市行为等。 为了理解机器学习并构建完整的解决方案,您将必须熟悉来自不同领域的许多技术,例如模式识别,人工神经网络,数据挖掘, 统计等。 上。
模型类型
AI 世界中有两种类型的模型:分析模型和学习模型。 在我们拥有可以计算的机器之前,人们曾经依靠分析模型。
使用数学公式得出分析模型,这基本上是遵循一系列步骤以得出最终方程式的步骤。 这种方法的问题在于它是基于人类的判断。 因此,这些模型很简单,而且往往不准确,仅带有几个参数。 想想牛顿和其他古老的科学家在拥有计算机之前是如何进行计算的。 在得出工作公式之前,此类模型通常涉及长时间推导和长时间的反复试验。
然后,我们进入了计算机的世界。 这些计算机擅长分析数据。 因此,人们越来越多地使用学习的模型。 这些模型是通过训练过程获得的。 在训练期间,机器会查看许多输入和输出示例,以得出方程式。 这些学习的模型通常是复杂且准确的,具有数千个参数。 这产生了一个非常复杂的数学方程式,该方程式控制着可以帮助进行预测的数据。
机器学习使我们可以获得可以在推理引擎中使用的学习模型。 最好的事情之一是,我们不需要导出基本的数学公式。 您不需要了解复杂的数学,因为机器会根据数据得出公式。 我们需要做的就是创建输入列表和相应的输出。 我们得到的的学习模型只是标记的输入与与所需输出之间的关系。
安装 Python3
在本书中,我们将使用 Python3。 确保在计算机上安装了最新版本的 Python3。 键入以下命令进行检查:
代码语言:javascript复制$ python3 --version
如果看到打印出类似Python3.x.x
(其中x.x
是版本号)的内容,那很好。 如果不是,则直接安装。
在 Ubuntu 上安装
在 Ubuntu 14.xx 及更高版本上,Python3 已默认安装。 如果没有,您可以使用以下命令来安装:
代码语言:javascript复制$ sudo apt-get install python3
像我们在操纵器中一样执行检查命令:
代码语言:javascript复制$ python3 --version
您应该看到版本号作为输出。
在 Mac OS X 上安装
如果您使用的是 Mac OS X,建议使用 Homebrew 来安装 Python3。它是 Mac OS X 的出色包安装程序,非常易于使用。 如果没有 Homebrew,则可以使用以下命令进行安装:
代码语言:javascript复制$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
让我们更新包管理器:
代码语言:javascript复制$ brew update
让我们安装 Python3:
代码语言:javascript复制$ brew install python3
像之前一样运行检查命令:
代码语言:javascript复制$ python3 --version
您应该看到在输出上打印的数字为 。
在 Windows 上安装
如果使用 Windows,建议您使用 Python3 的SciPy-stack
兼容发行版。Anaconda 非常流行并且易于使用。 您可以在以下位置找到安装说明。
如果要检查 Python3 的其他SciPy-stack
兼容发行版,可以在这个页面中找到它们。 这些发行版的好处是它们附带了所有必需的包。 如果使用这些版本之一,则无需单独安装包。
安装后,请像前面一样运行检查命令:
代码语言:javascript复制$ python3 --version
您应该看到已输出的版本号。
安装包
在本书中,我们将使用各种包,例如 NumPy,SciPy,scikit-learn 和 matplotlib。 在继续之前,请确保安装这些包。
如果您使用 Ubuntu 或 Mac OS X,则安装这些包非常简单。 所有这些包都可以使用单行命令安装。 这是与相关的安装链接:
- NumPy
- SciPy
- scikit-learn
- matplotlib
如果您使用的是 Windows,则应该已安装 Python3 的SciPy-stack
兼容版本。
加载数据
为了构建学习模型,我们需要代表世界的数据。 现在我们已经安装了必要的 Python 包,让我们看看如何使用这些包与数据进行交互。 通过键入以下命令,输入 Python 命令提示符:
代码语言:javascript复制$ python3
让我们导入包含所有数据集的包:
代码语言:javascript复制>>> from sklearn import datasets
让我们加载房价数据集:
代码语言:javascript复制>>> house_prices = datasets.load_boston()
打印数据:
代码语言:javascript复制>>> print(house_prices.data)
您将看到类似于以下内容的输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0FwnXLw7-1681568559566)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_01_09.png)]
图 9:输入房屋价格的输出
我们来看看标签。
您将看到以下输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-McIEqgci-1681568559566)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_01_10.png)]
图 10:预测房价的输出
实际的数组较大,因此图像表示该数组中的前几个值。
scikit-learn 包中还有可用的图像数据集。 每个图像的形状均为8×8
。 让我们加载它:
>>> digits = datasets.load_digits()
打印数字图像:
代码语言:javascript复制>>> print(digits.images[4])
您将看到此输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-woXaI7D8-1681568559567)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_01_11.png)]
图 11:scikit-learn 图像数组的输出
如您所见,它具有八行八列。
总结
在本章中,我们讨论了:
- 人工智能的意义何在?为什么我们需要研究它
- 人工智能的各种应用和分支
- 图灵测试是什么以及如何进行
- 如何使机器像人一样思考
- 理性主体的概念及其应如何设计
- 通用问题解决器(GPS)以及如何使用 GPS 解决问题
- 如何使用机器学习开发智能体
- 不同类型的机器学习模型
我们还介绍了如何在各种操作系统上安装 Python3,以及如何安装构建 AI 应用所需的必要包。 我们讨论了如何使用这些包来加载 scikit-learn 中可用的数据。
在下一章中,我们将学习监督学习以及如何建立分类和回归模型。
2 人工智能的基本用例
在本章中,我们将讨论人工智能(AI)的一些用例。 这绝不是详尽的清单。 许多行业已受到 AI 的影响,但尚未受影响的那些行业的清单每天都在缩短。 具有讽刺意味的是,机器人,自动化和 AI 无法接手的某些工作是薪水较低,需要较少“大脑”力量的工作。 例如,在我们能够代替发型师和水管工之前还需要一段时间。 这两项工作都需要机器人还需要掌握很多技巧和细节。 我知道,我的妻子要花很长时间才能将她的头发信任除当前发型师以外的任何人,更不用说机器人了。
本章将讨论:
- 一些具有代表性的 AI 用例
- 最长的工作将由自动化取代
- 受 AI 影响最大的行业
代表性 AI 用例
从金融到医学,很难找到一个不受人工智能干扰的行业。 我们将重点关注日常生活中最流行的 AI 应用的真实示例。 我们将探索当前的技术水平以及即将发生的事情。 最重要的是,也许这本书会激发您的想象力,并且您会提出一些对社会产生积极影响的新想法,我们可以将其添加到本书的下一版中。
人工智能,认知计算,机器学习和深度学习只是当今促成快速变化的一些破坏性技术。 由于云计算,物联网(IoT)和边缘计算的进步,可以更快地采用这些技术。 通过将所有这些技术整合在一起,组织正在重塑开展业务的方式。 这仅仅是个开始; 我们甚至不在第一局,甚至还没有记录过第一击!
到此为止,让我们开始看一下 AI 的一些当代应用。
数字个人助理和聊天机器人
不幸的是,对于某些呼叫中心来说,仍然普遍无法传统的交互式语音响应(IVR)系统,使得打电话给他们是一种耐心的练习。 但是,我们在自然语言处理领域取得了巨大的进步:聊天机器人。 一些最受欢迎的示例是:
- Google 助手:Google 助手于 2016 年启动,是目前可用的最高级聊天机器人之一。 可以在各种设备中找到它,例如电话,耳机,扬声器,洗衣机,电视和冰箱。 如今,大多数 Android 手机都包含 Google Assistant。 Google Home 和 Nest Home Hub 也支持 Google Assistant。
- Amazon Alexa :Alexa 是由 Amazon 开发和销售的虚拟助手。 它可以通过语音和执行命令(例如播放音乐,创建待办事项,设置警报,播放有声读物和回答基本问题)与用户互动。 它甚至可以按需告诉您一个笑话或故事。 Alexa 还可以用于控制兼容的智能设备。 开发人员可以通过安装技能来扩展 Alexa 的功能。 Alexa 技能是第三方供应商开发的其他功能。
- Apple Siri :Siri 可以接受用户语音命令和自然语言用户界面,以通过解析这些语音命令并将这些请求委派给一组互联网服务来回答问题,提出建议并执行操作。 该软件可以适应用户的个别语言使用,他们的搜索和偏好。 使用得越多,它就会学得越多,就会越好。
- Microsoft Cortana :Cortana 是由 Microsoft 设计和创建的另一种数字虚拟助手。 Cortana 可以设置提醒和警报,识别自然的语音命令,并使用信息回答问题。
所有这些助手都将允许您执行全部或至少大部分以下任务:
- 家里的控制设备
- 根据命令播放音乐和显示视频
- 设置计时器和提醒
- 预约
- 发送短信和电子邮件
- 拨打电话
- 公开申请
- 阅读通知
- 执行翻译
- 从电子商务网站订购
可能不支持但将变得越来越普遍的一些任务是:
- 登机
- 预订酒店
- 预订餐厅
所有这些平台还支持第三方开发人员来开发自己的应用或被 Amazon 称为的“技能”。 因此,可能性是无限的。
现有 Alexa 技能的一些示例:
- MySomm :推荐某些肉配哪种葡萄酒
- 调酒师:提供有关如何制作酒精饮料的说明
- 7 分钟锻炼:将指导您进行艰难的 7 分钟锻炼
- Uber :允许通过 Alexa 订购 Uber 游乐设施
前面列出的所有服务都在不断改善。 他们不断从与客户的互动中学习。 服务的开发人员以及利用服务用户每天创建的新数据点的系统都对它们进行了改进。
大多数云提供商都非常容易创建聊天机器人,对于某些基本示例,无需使用编程语言。 此外,将这些聊天机器人部署到 Slack,Facebook Messenger,Skype 和 WhatsApp 等服务并不难。
个人司机
无人驾驶或无人驾驶汽车是无需人工协助即可沿着预先建立的路线行驶的车辆。 如今,大多数自动驾驶汽车都不再依赖单一传感器和导航方法,而是使用多种技术,例如雷达,声纳,激光雷达,计算机视觉和 GPS。
随着技术的出现,行业开始创建标准以实现和衡量其进度。 无人驾驶技术也是如此。 SAE International 已创建标准 J3016,该标准定义了汽车的六个自动化级别,以便汽车制造商,供应商和策略制定者可以使用相同的语言来对汽车的复杂程度进行分类:
0 级(无自动化)
该车没有自动驾驶功能。 驾驶员充分参与并负责。 驾驶员操纵,制动,加速和协商交通。 这描述了当今道路上最新的汽车。
1 级(驾驶员辅助)
系统功能:在某些情况下,汽车可以控制转向或车辆速度,但不能同时控制两者。
驾驶员参与:驾驶员执行驾驶的所有其他方面,并全权负责监视道路并在辅助系统无法正常工作时接管汽车。 例如,自适应巡航控制。
2 级(部分自动化)
在某些情况下,汽车可以转向,加速和制动。 驾驶员仍然执行许多操作,例如解释和响应交通信号或改变车道。 控制车辆的责任主要落在驾驶员身上。 制造商仍然要求驾驶员充分参与。 此级别的示例包括:
- 奥迪交通堵塞辅助
- 凯迪拉克超级巡航
- 梅赛德斯-奔驰驾驶员辅助系统
- 特斯拉自动驾驶仪
- 沃尔沃飞行员辅助
3 级(有条件的自动化)
2 级和 3 级之间的枢轴点很关键。 在这个级别上,控制和监视汽车的责任开始从驾驶员变为计算机。 在适当的条件下,计算机可以控制汽车,包括监视环境。 如果汽车遇到无法处理的情况,它将要求驾驶员进行干预并采取控制措施。 驾驶员通常不控制汽车,但必须随时可以接管。 奥迪交通堵塞飞行员就是一个例子。
4 级(高度自动化)
在大多数情况下,汽车不需要人为干预,但在某些道路,天气或地理条件下,仍需要人工协助。 在仅限于定义区域的共享汽车模型下,可能不会有人参与。 但是对于私人拥有的汽车,驾驶员可以管理地面街道上的所有驾驶职责,并且系统可以接管高速公路。 Google 现已淘汰的 Firefly 吊车就是这一级别的一个例子。 它没有踏板或方向盘。 它被限制为最高时速 25 英里/小时,并且没有在公共街道上使用。
5 级(全自动)
无人驾驶系统可以控制并在人类可以应付的任何道路上和任何条件下操作汽车。 汽车的“驾驶员”只需输入目的地。 目前尚无此级别的产品,但是有几家公司已经关闭,到本书出版时可能已经存在。
现在,我们将回顾在该领域工作的一些领先公司:
Google 的 Waymo
截至 2018 年,Waymo 的自动驾驶汽车在公共道路上行驶了 800 万英里,在模拟环境中行驶了 50 亿英里。 在接下来的几年中,几乎可以肯定,我们将能够购买能够完全自动驾驶的汽车。 特斯拉(Tesla)等人已经通过其自动驾驶功能提供了驾驶员协助,并且可能将成为第一家提供完整自动驾驶功能的公司。 想象一个世界,今天出生的孩子将永远不必获得驾照! 仅凭人工智能的进步,对我们社会的破坏将是巨大的。 不再需要送货司机,出租车司机和卡车司机。 即使在无人驾驶的未来仍然发生交通事故,由于我们将消除分心驾驶和酒后驾驶,因此将挽救数百万生命。
Waymo 于 2018 年在美国亚利桑那州推出了首项商业无人驾驶服务,并计划在全国和全球范围内进行扩展。
Uber ATG
Uber 的先进技术小组(ATG)是 Uber 的子公司,致力于开发自动驾驶技术。 2016 年,Uber 在匹兹堡的街道上推出了一项实验性汽车服务。 优步计划购买多达 24,000 辆沃尔沃 XC90,并为其配备自动驾驶技术,并于 2021 年开始以一定容量实现商业化。
可悲的是,2018 年 3 月,伊莱恩·赫兹伯格(Elaine Herzberg)参与了一辆 Uber 无人驾驶汽车的事故并死亡。 根据警方的报道,她在试图通过手机观看视频时,试图过马路时被 Uber 车辆撞倒。 赫兹伯格女士成为涉及无人驾驶汽车的事故中首批死亡的人之一。 理想情况下,我们希望这种技术不会发生任何事故,但是我们需要根据当前交通事故带来的危机来调整我们要求的安全水平。 就背景而言,2017 年美国有 40,100 个汽车死亡事件; 即使我们继续看到无人驾驶汽车发生事故,如果将死亡人数削减一半,每年也可以挽救数千人的生命。
当然,可以设想一种无人驾驶汽车,其外观比起我们现有汽车的内部更像一个客厅。 不需要方向盘,踏板或任何种类的手动控制。 汽车唯一需要的输入就是您的目的地,可以在旅行开始时通过对您的汽车“说话”来输入。 由于汽车将能够感知何时需要维修或汽车功能出现问题,因此无需跟踪维护时间表。
车祸的责任将从车辆的驾驶员转移到车辆的制造商,而不再需要购买汽车保险。 最后一点可能是汽车制造商部署该技术的速度缓慢的原因之一。 甚至汽车拥有量也可能被颠覆,因为我们可以在需要时而不是一直需要时召唤一辆车。
货运和仓库管理
亚马逊的分拣设施是在人类,计算机和机器人之间形成的共生关系的最好例子之一。 计算机接受客户订单并决定将商品路由到何处,机器人充当搬运工,在仓库中搬运托盘和库存。 人们通过手动挑选进入每个订单的物品来解决“最后一英里”问题。 机器人熟练地无意识地重复执行多次任务,只要涉及到某种模式并且要进行一定程度的预训练就可以做到。 但是,让机器人捡起 20 磅重的包装,然后立即能够抓鸡蛋而不破鸡蛋,这是机器人技术难题之一。
机器人在处理不同大小,重量,形状和易碎性的物体时会遇到困难。 许多人可以轻松完成的任务。 因此,人们要处理机器人遇到的困难的任务。 这三种类型的不同演员之间的相互作用转化为一个经过微调的乐团,该乐团每天可以交付数百万个包而几乎没有错误。
甚至亚马逊机器人实现总监斯科特·安德森(Scott Anderson)在 2019 年 5 月都承认,距离全自动仓库至少有 10 年的路程。 因此,我们将继续在世界各地的仓库中看到这种配置一段时间。
人类健康
在健康科学中应用 AI 的方法几乎是无限的。 我们将在这里讨论其中的一些,但这绝不是详尽的清单。
药物发现
AI 可以协助生成候选药物(即要在医学上测试的分子),然后使用约束满足或实验模拟快速消除其中的一些候选药物。 在后面的章节中,我们将学习有关约束满足编程的更多信息。 简而言之,这种方法使我们能够通过快速生成数百万种可能的候选药物来加快药物发现,并且在候选药物不满足某些预定约束条件时也可以迅速拒绝它们。
此外,在某些情况下,我们可以在计算机中模拟实验,否则在现实生活中执行该实验会更加昂贵。
此外,在某些情况下,研究人员仍在进行真实世界的实验,但依靠机器人进行实验并加快处理过程。 这些新兴领域被称为高通量筛选(HTS)和虚拟高通量筛选(VHTS)。
机器学习已开始越来越多地用于增强临床试验。 埃森哲咨询公司开发了一种称为智能临床试验(ITP)的工具。 它用于预测临床试验的时间。
可以令人惊讶地使用的另一种方法是应用于药物发现的方法是自然语言处理(NLP)。 可以使用一串字母来表示基因组数据,并且可以使用 NLP 技术来处理或“理解”基因组序列的含义。
保险定价
机器学习算法可用于通过更准确地预测在患者身上花费多少,驾驶员的健康状况或寿命长短来更好地为保险定价。
例如,Insilico Medicine 的 young.ai 项目可以准确地预测血液样本和照片中某人的寿命。 血液样本提供 21 种生物标志物,例如胆固醇水平,炎症标志物,血红蛋白计数和白蛋白水平,用作机器学习模型的输入。 模型的其他输入是种族和年龄,以及该人的照片。
有趣的是,到目前为止,任何人都可以通过访问 young.ai 并提供所需信息来免费使用此服务。
患者诊断
通过使用复杂的规则引擎和机器学习,医生可以对患者进行更好的诊断,并在实践中提高生产力。 例如,在张刚[1]在加利福尼亚大学圣地亚哥分校的一项最新研究中,一种系统可以比初级儿科医生更准确地诊断儿童疾病。 该系统能够以 90% 至 97% 的准确率诊断以下疾病:
- 腺热
- 罗索拉
- 流感
- 水痘
- 手足口病
输入数据集包含 2016 年至 2017 年间来自中国广州地区的 130 万儿童就医的医疗记录。
医学影像学解释
医学成像数据是有关患者的复杂而丰富的信息来源。 CAT 扫描,MRI 和 X 射线包含原本无法获得的信息。 放射科医生和临床医生不足以解释它们。 从这些图像获得结果有时可能需要几天时间,有时可能会被误解。 最近的研究发现,机器学习模型的表现甚至可以比人类模型好。
数据科学家开发了支持 AI 的平台,与传统方法相比,该平台可以在几分钟(而不是几天)内解释 MRI 扫描和放射图像,并且准确率更高。
令人惊讶的是,美国放射学院的领导者们对此并不感到担心,而是将 AI 的出现视为对医生有价值的工具。 为了促进该领域的进一步发展,美国放射学院数据研究所(ACR DSI)发布了医学成像中的多个 AI 用例,并计划继续发布更多。
精神病学分析
与精神科医生进行一个小时的会议可能需要花费数百美元。 我们正处于能够使用 AI 聊天机器人模拟行为的风口浪尖。 至少,这些漫游器将能够在与精神科医生的会谈中提供后续护理,并在医生就诊之间为患者提供护理。
自动化顾问的一个早期例子是 Eliza。 它是由 Joseph Weizenbaum 在 1966 年开发的。 它允许用户与模仿罗杰式心理治疗师的计算机进行“对话”。 值得注意的是,Eliza 感觉很自然,但是它的代码只有几百行,并且其核心并没有真正使用太多的 AI。
最近和更先进的示例是 Ellie。 Ellie 由南加州大学创意技术研究所创建。 它有助于治疗抑郁症或创伤后应激障碍患者。 埃莉(Ellie)是位虚拟的治疗师(她出现在屏幕上),对情感暗示做出反应,在适当的时候肯定地点头,并转移座位。 她可以感知一个人的脸上的 66 个点,并使用这些输入来读取一个人的情感状态。 艾莉(Ellie)的秘密之一是,她显然不是人,这使人们对她的判断力降低了,对她的开放更自在。
智能健康记录
众所周知,医学落后于电子记录。 数据科学提供了多种方法来简化对患者数据的捕获,包括 OCR,手写识别,语音到文本捕获以及实时读取和分析患者生命体征。 不难想象不久的将来,由于迫在眉睫的健康问题,人工智能引擎可以实时分析这些信息,从而做出诸如调整人体葡萄糖水平,服用药物或寻求医疗帮助等决策。
疾病检测与预测
人类基因组是的最终数据集。 在不久的某个时候,我们将能够使用人类基因组作为机器学习模型的输入,并能够使用此庞大的数据集检测和预测各种各样的疾病和状况。
使用基因组数据集作为机器学习的输入是一个令人兴奋的领域,它正在迅速发展,并将彻底改变医学和卫生保健。
人类基因组包含超过 30 亿个碱基对。 我们在两个方面将取得进展,这将加快进度:
- 对基因组生物学的理解不断进步
- 大数据计算的进步,可以更快地处理大量数据
有很多研究将深度学习应用于基因组学领域。 尽管基因组学的深度学习仍处于早期阶段,但它有可能为以下领域提供信息:
- 功能基因组学
- 肿瘤学
- 人口遗传学
- 临床遗传学
- 作物单产提高
- 流行病学与公共卫生
- 进化和系统演化分析
知识搜索
我们到了的地步,在某些情况下,甚至都没有意识到我们正在使用人工智能。 一个技术或产品是好的标志是当我们不必停止思考它是如何做的时。 Google 搜索就是一个很好的例子。 该产品已经在我们的生活中无处不在,我们还没有意识到它在多大程度上依赖人工智能来产生惊人的结果。 从其谷歌建议技术到其结果相关性的不断提高,人工智能已深深地嵌入其搜索过程中。
据彭博社报道,2015 年初,Google 开始使用名为 RankBrain 的深度学习系统来协助生成搜索查询响应。 彭博社的文章对 RankBrain 的描述如下:
“RankBrain 使用人工智能将大量书面语言嵌入计算机可以理解的数学实体(称为向量)中。如果 RankBrain 看到了自己不熟悉的单词或短语,则机器可以猜测是哪个单词或短语。 短语可能具有相似的含义并相应地过滤结果,从而使其更有效地处理了前所未有的搜索查询。”
-克拉克,杰克[2]
在上一份报告中,Ranrainbrain 在数十亿个 Google 搜索查询中扮演着重要角色。 可以想像,该公司对 RankBrain 的工作原理 tight 之以鼻,而且甚至 Google 都可能很难解释它的工作方式。 您知道,这是深度学习的难题之一。 在许多情况下,它可以提供高度准确的结果,但是就为什么给出单个答案而言,深度学习算法通常很难理解。 基于规则的系统,甚至其他机器学习模型(例如随机森林)都更容易解释。
深度学习算法缺乏可解释性会产生重大影响,包括法律影响。 最近,Google 和 Facebook 等人发现自己处于显微镜下,以确定他们的结果是否有偏见。 将来,立法者和监管者可能会要求这些技术巨头为某种结果提供理由。 如果深度学习算法不能提供可解释性,则可能会迫使他们使用其他精度较低的算法来提供解释性。
最初,RankBrain 仅协助约 15% 的 Google 查询,但现在几乎涉及所有用户查询。
但是,如果查询是普通查询或算法可以理解的查询,则 RankBrain 排名得分的权重很小。 如果查询是该算法之前未曾查看过的查询,或者它不知道其含义,则 RankBrain 得分更为相关。
推荐系统
建议系统是已融入我们日常生活的 AI 技术的另一个示例。 亚马逊,YouTube,Netflix,LinkedIn 和 Facebook 都依赖推荐技术,我们甚至没有意识到我们正在使用它。 推荐系统严重依赖数据,并且可用数据越多,它们将变得越强大。 这些公司拥有世界上最大的市值,这并非巧合,它们的力量来自能够利用客户数据中隐藏的力量。 希望这种趋势将来会继续。
什么是建议? 让我们首先探索什么不是答案。 这不是一个明确的答案。 某些问题,例如“二加二是什么?” 或“土星有多少颗卫星?” 有明确的答案,没有主观性的余地。 其他问题,例如“您最喜欢的电影是什么?” 或“你喜欢萝卜吗?” 是完全主观的,答案将取决于回答问题的人。 一些机器学习算法因这种“模糊性”而蓬勃发展。 同样,这些建议可能会产生巨大的影响。
考虑一下亚马逊不断推荐某产品而不是另一产品的后果。 如果没有找到其他分销和销售产品的方法,那么制作推荐产品的公司将会蓬勃发展,制作不推荐产品的公司可能会倒闭。
推荐系统可以改进的方法之一是通过从系统用户那里进行先前的选择。 如果您是第一次访问电子商务网站,但是没有订单历史记录,那么该网站将很难为您量身定制建议。 如果您购买运动鞋,则该网站现在有一个数据点,可以作为起点使用。 根据系统的复杂程度,可能会建议使用另一双运动鞋,一双运动袜甚至篮球(如果鞋子是高帮鞋)。
良好推荐系统的重要组成部分是随机因素,该因素偶尔会“四肢走动”,并提出可能与初始用户选择无关的奇怪建议。 推荐系统不仅从历史中学习来找到相似的建议,而且还尝试提出可能乍一看并不相关的新建议。 例如,Netflix 用户可能会观看“教父”,而 Netflix 可能会开始推荐 Al Pacino 电影或流氓电影。 但它可能会建议您使用“伯恩身份”(Bourne Identity)。 如果用户不接受推荐或不观看电影,则算法将从中学习并避免使用其他电影,例如“伯恩身份”(例如,以杰森·伯恩为主要角色的任何电影)。
随着推荐系统变得越来越好,可能性是令人兴奋的。 他们将能够为个人数字助理提供支持,并成为您的私人管家,该管家对您的好恶有深刻的了解,并可以提出您可能没有想到的好建议。 建议可以从这些系统中受益的领域包括:
- 餐厅
- 电影
- 音乐
- 潜在合作伙伴(在线会议)
- 书籍和文章
- 搜索结果
- 金融服务(机器人顾问)
推荐系统的一些值得注意的特定示例如下:
Netflix 奖
Netflix 奖是在推荐器系统社区中引起大量嗡嗡声的竞赛。 从 2006 年到 2009 年,Netflix 赞助了比赛,奖金为一百万美元。 Netflix 提供了超过 1 亿个收视率的数据集。
Netflix 愿意向推荐最准确的团队支付奖金,并且比 Netflix 现有推荐系统的推荐准确率高 10%。 这项竞赛激发了人们对新的,更准确的算法的研究。 2009 年 9 月,大奖授予了 BellKor 的 Pragmatic Chaos 团队。
Pandora
Pandora 是领先的音乐服务之一。 与 Apple 和 Amazon 等其他公司不同,Pandora 的唯一重点是音乐服务。 Pandora 显着的服务功能之一就是定制广播电台的概念。 这些“电台”允许用户按流派播放音乐。 您可以想象,推荐系统是此功能的核心。
Pandora 的推荐器基于多个层次:
- 首先,他们的音乐专家团队会根据流派,节奏和进度来标注歌曲。
- 这些标注被转换为用于比较歌曲相似度的向量。 这种方法促进了来自未知艺术家的“长尾巴”或晦涩音乐的呈现,尽管如此,它仍然可能适合个人听众。
- 该服务也高度依赖用户反馈,并使用它不断增强服务。 Pandora 收集了超过 750 亿个关于收听者偏好的反馈数据点。
- 然后,潘多拉(Pandora)推荐引擎可以使用收听者的先前选择,地理位置和其他人口统计数据,根据收听者的偏好执行个性化过滤。
总体而言,潘多拉(Pandora)的推荐器使用大约 70 种不同的算法,其中包括 10 种用于分析内容的算法,40 种用于处理集体智慧的算法以及大约 30 种用于进行个性化过滤的算法。
Betterment
机器人顾问是推荐引擎,可在最少人参与的情况下提供投资或财务建议和管理。 这些服务使用机器学习来自动分配,管理和优化客户的资产组合。 他们可以以比传统顾问更低的成本提供这些服务,因为它们的开销更低,并且其方法更具可扩展性。
现在,在这个领域竞争激烈,有超过 100 家公司提供此类服务。 机器人顾问被认为是一个巨大的突破。 以前,财富管理服务是专为高净值人士提供的专有且昂贵的服务。 与传统的人工服务相比,机器人顾问承诺以更低的成本向更广泛的受众提供类似的服务。 机器人顾问可以潜在地将投资分配到各种各样的投资产品中,例如股票,债券,期货,商品,房地产以及其他外来投资。 但是,为了简单起见,投资通常限于交易所交易基金(ETF)。
正如我们提到的,有许多公司提供机器人咨询。 例如,您可能需要研究 Betterment 以了解有关此主题的更多信息。 填写风险调查表后,Betterment 将为用户提供定制的,多样化的产品组合。 通常,Betterment 将推荐低收费股票和债券指数基金的组合。 Betterment 收取管理费(占产品组合的百分比),但低于大多数人力服务。 请注意,我们不认可这项服务,我们仅将其作为金融行业推荐引擎的示例。
智能家居
每当您在大街上向普通百姓提出 AI 的话题时,他们通常都会对替代人类工人的时间表示怀疑。 他们可以正确地指出我们仍然需要在房子周围做很多家务活的事实。 人工智能不仅需要在技术上成为可能,而且还需要在经济上可行才能被广泛采用。 家政服务通常是一种低薪职业,因此,取代它的自动化需要价格相同或更便宜。 此外,家务劳动需要很多技巧,而且其中包括不一定要重复的任务。 让我们列出该自动机需要熟练执行的一些任务:
- 洗衣服
- 叠衣服
- 煮晚餐
- 铺床
- 捡起地板上的物品
- 拖地,扫地和吸尘
- 洗碗
- 监控房屋
众所周知,其中一些任务很容易在机器上执行(即使没有 AI),而其中一些则非常困难。 因此,出于经济考虑,房屋可能成为最后一个完全自动化的地方之一。 尽管如此,让我们看一下在这一领域取得的一些惊人进步。
家庭监控
家庭监视是领域,通常已经可以找到很好的解决方案。 亚马逊提供的 Ring 视频门铃和 Google Nest 温控器是两种价格低廉的选择,已广泛使用和流行。 这是今天可以购买的智能家居设备的两个简单示例。
环形视频门铃是连接到互联网的智能家居设备,可以通过智能手机通知房主家中的活动,例如访客。 该系统不会连续记录,而是在按下门铃或激活移动探测器时激活。 然后,环形门铃可以让房主观看活动或使用内置的麦克风和扬声器与访客交流。 有些型号还允许房主通过智能锁远程打开门,并让访客进入房屋。
Nest Learning Thermostat 是一款智能家用设备,最初由 Nest Labs 开发,该公司后来被 Google 收购。 它是由 Tony Fadell,Ben Filson 和 Fred Bould 设计的。 它是可编程的,支持 Wi-Fi 且具有自学习功能。 它使用人工智能来优化房屋的温度,同时节省能源。
在使用的最初几周中,将恒温器设置为首选设置,这将作为基准。 温控器将了解您的日程安排和您的首选温度。 使用内置传感器和手机的位置,当没人在家时,恒温器将转换为节能模式。
自 2011 年以来,Nest 温控器已为全球数百万个家庭节省了数十亿千瓦时的能源。 独立研究表明,它可以为人们节省平均 10% 至 12% 的取暖费用和 15% 的冷却费用,因此大约 2 年内它可以收回成本。
吸尘和拖地
吸尘和拖地是流行的移交给机器人的两个任务。 机器人吸尘器是使用 AI 吸尘表面的自主机器人吸尘器。 根据设计的不同,其中一些机器使用旋转刷达到狭窄的角落,某些机型除了具有吸尘功能外还包括其他一些功能,例如拖地和紫外线杀菌。 推广这项技术的大部分功劳归于公司(而非电影) iRobot。
iRobot 于 1990 年由 Rodney Brooks,Colin Angle 和 Helen Greiner 在麻省理工学院的人工智能实验室工作后相识而创立。 iRobot 以其吸尘机器人(Roomba)而闻名,但很长一段时间以来,他们还拥有一个专门从事军事机器人开发的部门。 Roomba 于 2002 年开始销售。截至 2012 年,iRobot 已售出超过 800 万台家用机器人,并制造了 5,000 多台国防和安全机器人。 该公司的 PackBot 是美军使用的炸弹处理机器人,已在伊拉克和阿富汗广泛使用。 PackBots 还被用于在福岛第一核电站的危险条件下收集信息。 在墨西哥湾的 Deepwater Horizon 溢油事故发生之后,iRobot 的 Seaglider 被用来探测水下的油藏。
另一款 iRobot 产品是 Braava 系列清洁剂。 Braava 是一款小型机器人,可以拖地和扫地。 它适用于浴室和厨房等狭小空间。 它喷水并使用各种不同的垫来有效,安静地清洁。 某些 Braava 型号具有内置的导航系统。 Braava 没有足够的能力去除深层的污渍,因此它不是完整的人类替代品,但确实具有广泛的接受度和很高的评价。 我们希望他们继续受欢迎。
家庭智能设备的潜在市场是巨大的,几乎可以肯定的是,我们将继续看到成熟的公司和初创公司都试图利用这个尚未开发的市场。
收拾烂摊子
正如我们在运输用途案例中了解到的一样,挑选具有不同重量,大小和形状的物体是最困难的自动化任务之一。 机器人可以在均匀的条件下(例如工厂车间,某些机器人专门从事某些任务)高效地执行任务。 然而,在拾起椅子之后拾起一双鞋可能是巨大的挑战,而且代价昂贵。 因此,不要指望机器很快就会以具有成本效益的方式普及这种家庭杂务。
私人厨师
就像从地板上捡起物品一样,烹饪需要捡起不同的物品。 然而,有两个原因可以使我们期望“自动烹饪”会更快发生:
- 某些餐馆可能会收取数百美元的食物费用,并为熟练的厨师付出高昂的代价。 因此,如果这样做可以提高利润,他们可能会愿意使用技术来替换高价员工。 一个五星级的寿司餐厅就是一个例子。
- 厨房中的某些任务是重复性的,因此适合自动化。 想想快餐店,汉堡和炸薯条可能要成百上千。 因此,不是由一个机器来处理整个不同的烹饪过程,而是一系列机器可以处理该过程的各个重复阶段。
智能假肢是人工智能增强人类而不是替代人类的典范。 有不止几名厨师在事故中失去了手臂或出生时没有肢体。
一个例子是厨师迈克尔凯恩斯(Michael Caines),他经营一家米其林两星级餐厅,并在一场可怕的车祸中失去了手臂。 凯恩斯厨师一直担任英格兰德文郡吉德利公园的主厨,直到 2016 年 1 月。[3] 他目前是埃克塞特和埃克斯茅斯之间的林普斯通庄园酒店的行政总厨。 他现在用假肢做饭,但考虑到他的食物质量,您永远不会知道。
另一个例子是运动员和厨师 Eduardo Garcia –世界上最先进的仿生手使这一切成为可能。
2011 年 10 月,猎弓麋鹿在蒙大拿州偏僻地区被电死。 爱德华多(Eduardo)于 2011 年 10 月独自打猎。当他看到一只死去的小黑熊时,他正在乡下。 他停下来检查一下,跪下来,用刀刺了一下。
这样做时,他的身体承受了 2400 伏的电压-熊宝宝被一根埋在地下的带电电线杀死。 他幸免于难,但在事件中失去了手臂。
2013 年 9 月,Advanced Arm Dynamics 为 Garcia 配备了 Touch Bionics 设计的仿生手。 仿生手由加西亚的前臂肌肉控制,可以用 25 种不同的方式抓握。 用他的新手,加西亚可以执行通常需要非常敏捷的任务。 他的新手仍然有一些局限性。 例如,加西亚(Garcia)无法举重。 但是,他现在可以执行某些以前无法执行的操作。 例如,他可以从烤箱中拿出东西,而不会被灼伤,并且不可能割伤手指。
相反,机器人可以代替厨房中的人类来代替人类,而不是。 一个例子就是机器人厨房 Moley。 Moley 目前尚未投入生产,但 Moley 机器人厨房的最先进原型由两个机械臂组成,这些机械臂的手配有触觉传感器,炉灶,烤箱,洗碗机和触摸屏单元。 这些人造手可以举起,抓住并与大多数厨房设备互动,包括刀具,打蛋器,汤匙和搅拌器。
使用 3D 相机和手套,它可以记录人类厨师做饭的情况,然后将详细的步骤和说明上载到存储库中。 然后使用手势识别模型将厨师的动作转换为机器人动作。 这些模型是与斯坦福大学和卡内基梅隆大学合作创建的。 之后,Moley 可以重复相同的步骤,并从头开始烹饪完全相同的餐点。
在当前的原型中,用户可以使用触摸屏或智能手机应用对其进行操作,并预先准备好配料并将其放置在预设位置。 该公司的长期目标是允许用户从 2000 多种食谱中轻松选择一个选项,Moley 会在几分钟内准备好餐点。
游戏
可能没有例子比在游戏领域取得的进步更好的例子来证明人工智能的惊人发展。 人类具有天生的竞争能力,在我们自己的游戏中让机器击败我们是衡量该领域突破的有趣标准。 长期以来,计算机一直能够在一些更基础,更确定性,计算量更少的游戏(例如说跳棋)中击败我们。 直到最近几年,机器才能够始终击败某些较难游戏的主人。 在本节中,我们将介绍其中的三个示例。
星际争霸 2
电子游戏被用作测试 AI 系统表现的基准已有数十年。 随着功能的增强,研究人员可以使用需要不同类型智能的更为复杂的游戏。 从此游戏中开发出来的策略和技术可以转移到解决实际问题上。 《星际争霸 2》的游戏被认为是最难的游戏之一,尽管按照视频游戏标准它是古老的游戏。
DeepMind 的团队引入了一个名为 AlphaStar 的程序,该程序可以玩《星际争霸 II》,并且首次击败了顶级职业玩家。 在 2018 年 12 月举行的比赛中,AlphaStar 击败了由 Grzegorz “MaNa” Komincz 组建的团队,Grzegorz “MaNa” Komincz 是全球最强的星际争霸职业选手之一,得分为 5-0。 游戏是在专业比赛条件下进行的,没有任何游戏限制。
与以前使用 AI 限制游戏的尝试相反,AlphaStar 可以不受限制地玩完整游戏。 它使用了深度神经网络,可以通过监督学习和强化学习直接从原始游戏数据中进行训练。
使《星际争霸 2》如此困难的一件事是需要平衡短期和长期目标并适应意外情况。 这通常对先前的系统提出了巨大的挑战。
尽管 StarCraft 只是一个游戏,尽管很困难,但是 AlphaStar 提出的概念和技术对于解决其他现实世界中的挑战很有用。 例如,AlphaStar 的架构能够根据不完善的信息来对很长的可能动作序列进行建模-游戏通常持续数小时,并进行成千上万次动作。 在许多实际问题中,可以找到对长序列进行复杂预测的主要概念,例如:
- 天气预报
- 气候模拟
- 自然语言理解
AlphaStar 在星际争霸中表现出的成功代表着现有最困难的视频游戏之一的重大科学突破。 这些突破代表了人工智能系统的巨大飞跃,该系统可以转让并可以帮助解决基本的现实世界中的实际问题。
Watson
IBM 和 Watson 团队在 2011 年创造了历史,当时他们设计了系统,该系统能够击败两个最成功的 Jeopardy 冠军。
肯·詹宁斯(Ken Jennings)连续 74 次出场,是该演出历史上最长的不败战绩。 布拉德·拉特(Brad Rutter)赢得了最大的奖金,奖金总额为 325 万美元。
两位选手都同意与沃森进行一场比赛。
Watson 是一个问答系统,可以回答以自然语言提出的问题。 它最初由主要研究人员 David Ferrucci 领导的 IBM DeepQA 研究团队创建。
Watson 使用的问题解答技术与常规搜索(例如 Google 搜索)之间的主要区别在于,常规搜索将关键字作为输入,并根据与查询的相关性对文档列表进行排名。 像 Watson 所使用的一样,问答技术采用自然语言表达一个问题,试图更深入地理解该问题,并试图为该问题提供准确的答案。
Watson 的软件架构使用:
- IBM 的 DeepQA 软件
- Apache UIMA(非结构化信息管理架构)
- 多种语言,包括 Java,C 和 Prolog
- SUSE Linux 企业服务器
- 适用于分布式计算的 Apache Hadoop
国际象棋
我们许多人都记得 1996 年 Deep Blue 击败国际象棋大师 Gary Kasparov 时的新闻。Deep Blue 是 IBM 创建的国际象棋应用。
在第一轮比赛中,深蓝赢得了对阵加里·卡斯帕罗夫的第一场比赛。 但是,他们原定要打六场比赛。 卡斯帕罗夫(Kasparov)在接下来的五场比赛中赢得了三场胜利,并赢得了其中的两场,从而以 4–2 的比分击败了深蓝。
Deep Blue 团队回到进行了制图,对该软件进行了很多增强,并在 1997 年再次使用了 Kasparov。Deep Blue 在第二轮击败 Kasparov 的比赛中赢得了第二轮比赛,以 3½的比分赢得了六局比赛 2½。 然后,它成为第一个在标准国际象棋锦标赛规则和时间控制下击败比赛的世界冠军的计算机系统。
一个鲜为人知的例子是 AlphaZero 团队在国际象棋领域的成就,这是一种机器击败人类的迹象。
Google 的 AlphaZero 研究团队的科学家在 2017 年创建了一个系统,该系统只花了四个小时就学会了象棋规则,然后粉碎了当时最先进的世界冠军象棋程序 Stockfish。 到现在为止,有关计算机还是人类在国际象棋方面更胜一筹的问题已得到解决。
让我们暂停片刻,然后考虑一下。 该系统超越了人类对古代象棋的所有知识,如果该系统在早晨开始学习,那么它将在午餐时间完成。
该系统已获得国际象棋规则,但未获得任何策略或进一步的知识。 然后,在几个小时内,AlphaZero 达到了足以击败 Stockfish 的程度。
在与 Stockfish 的一系列 100 场比赛中,AlphaZero 以白色打赢了 25 场比赛(白色具有优势,因为它排名第一)。 它还赢得了三场黑色比赛。 其余的比赛是平局。 Stockfish 没有获得任何胜利。
AlphaGo
围棋像象棋一样困难,难度与古代围棋相比没有。
不仅(19 x 19
)棋盘位置比可见宇宙中的原子还多,而且可能的国际象棋棋盘位置与棋盘位置的数量可以忽略不计。 但是围棋至少比象棋游戏复杂几个数量级,因为围棋的发展有很多可能的方式,使每种棋子都朝着另一条发展路线发展。 使用围棋,单块石头可以影响和影响整个棋盘状况的移动次数也比带棋的单块移动大很多数量级。
有一个强大的程序示例,它可以玩由 DeepMind 开发的名为 AlphaGo 的 Go 游戏。 AlphaGo 还有三个功能更强大的继任者,分别称为 AlphaGo Master,AlphaGo Zero 和 AlphaZero。
2015 年 10 月,原始的 AlphaGo 成为第一个在全大小 19 x 19 板上击败无障碍职业人类围棋选手的计算机围棋程序。 2016 年 3 月,它在五场比赛中击败了李·塞多尔。 这成为围棋程序第一次击败没有障碍的 9 杆专业运动员。 尽管 AlphaGo 在第四局中输给 Lee Sedol,但 Lee 在最后一场比赛中辞职,最终比分是 4 比 1。
在 2017 年未来围棋峰会上,AlphaGo 的继任者 AlphaGo Master 在三场比赛中击败了大师 Kejie。 柯洁当时被评为世界排名第一的选手。 此后,AlphaGo 被中国围棋协会授予专业 9 段。
AlphaGo 及其继任者使用蒙特卡洛树搜索算法,基于先前通过机器学习“学习”的知识来找到他们的动作,特别是使用深度学习和训练,既可以与人类玩耍,也可以与人类玩耍。 该模型经过训练可以预测 AlphaGo 自己的举动以及获胜者的游戏。 这种神经网络提高了树形搜索的强度,从而在后续游戏中提供了更好的动作和更强的玩法。
电影制作
几乎可以肯定的是在接下来的几十年内可以制作出 100% 计算机生成的电影。 构想一个系统,其中输入是一个书面剧本,而输出是一个完整的故事片,这是不容置疑的。 此外,天然生成器已经取得了一些进步。 因此,最终甚至不需要脚本。 让我们进一步探讨。
Deepfake
Deepfake 是术语“深度学习”和fake
的混合。 这是一种合并视频图像的 AI 技术。 常见的应用是将某人的脸重叠到另一张上。 它的一个邪恶版本被用来与著名人物合并色情场景或创建复仇色情片。 Deepfake 还可以用于创建虚假新闻或恶作剧。 可以想象,如果滥用该技术,将会对社会产生严重影响。
中国一家名为 Momo 的公司开发了类似软件的最新版本,后者开发了一个名为 Zao 的应用。 它使您可以将某人的脸重叠在诸如 Titanic 之类的短片上,效果令人印象深刻。 此应用和其他类似应用毫无争议。 隐私团体抱怨说,按照用户协议条款提交给网站的照片将成为 Momo 的财产,然后可用于其他应用。
有趣的是,技术在该领域将如何继续发展。
电影脚本生成
他们不会很快获得的奥斯卡金像奖,但是有两个项目致力于制作电影剧本。 最著名的例子之一是 Sunspring。
《Sunspring》是一部实验科幻短片,于 2016 年发行。它完全是使用深度学习技术编写的。 这部电影的剧本是使用名为本杰明(Benjamin)的长短期记忆(LSTM)模型创建的。 它的创作者是由 BAFTA 提名的电影人奥斯卡·夏普(Oscar Sharp)和纽约大学 AI 研究人员罗斯·古德温(Ross Goodwin)。 电影中的演员是托马斯·米德迪奇,伊丽莎白·格雷和汉弗莱·克尔。 它们的字符名称分别是 H,H2 和 C,它们将保留在未来。 他们最终相互联系,形成了三角恋。
最初在伦敦科幻电影节的 48 小时挑战赛上放映,并于 2016 年 6 月由技术新闻网站 Ars Technica 在线发布。
承保和交易分析
什么是承保? 简而言之,承保是过程,机构通过该过程确定机构是否要承担财务风险以换取保费。 需要承保的交易示例如下:
- 签发保险单
- 健康
- 生活
- 家庭
- 驾驶
- 贷款额
- 分期贷款
- 信用卡
- 按揭
- 商业信贷
- 证券承销和首次公开募股(IPO)
可以预见,确定是否应该签发保险单或贷款,如果做出错误的决定,以什么价格会付出很高的代价。 例如,如果一家银行发行了一笔贷款,但贷款违约,则将需要数十笔其他表现良好的贷款来弥补这一损失。 相反,如果银行在借款人将要偿还全部贷款的情况下放弃贷款,这也将损害银行的财务状况。 因此,银行花费大量时间分析或“承销”贷款,以确定借款人的信用价值以及担保该贷款的抵押品的价值。
即使进行了所有这些检查,承销商仍然会出错并发行拖欠或绕过应得的借款人的贷款。 当前的承保过程遵循必须满足的一组标准,但是特别是对于较小的银行,在此过程中仍然存在一定程度的人为主观性。 这不一定是一件坏事。 让我们来看一个场景,以进一步探索它:
最近,一位高净值人士从环球旅行中回来。 三个月前,他们在一家著名的医疗机构找到了一份工作,其信用评分超过 800。
你会借钱给这个人吗? 有了这些特征,它们似乎是一个很好的信用风险。 但是,正常的承保规则可能会使他们失去资格,因为最近两年没有使用这些规则。 手动承保会审视整个情况,并可能会批准它们。
同样,机器学习模型可能能够将其标记为有价值的帐户并发放贷款。 机器学习模型没有严格的规则,而是“通过示例学习”。
许多贷方已经在其承销中使用机器学习。 Zest Finance 是一家专门从事这一领域的公司的有趣示例。 Zest Finance 使用 AI 技术来协助贷方进行承销。 人工智能可以帮助增加收入并降低风险。 最重要的是,一般而言应用良好的 AI,尤其是 Zest Finance 可以帮助公司确保所使用的 AI 模型符合某个国家/地区的法规。 一些 AI 模型可能是一个“黑匣子”,很难解释为什么一个借款人被拒绝而另一个借款人被接受。 Zest Finance 可以全面解释数据建模结果,衡量业务影响并遵守法规要求。 Zest Finance 的秘密武器之一是使用非传统数据,包括贷方可能拥有的内部数据,例如:
- 客户支持数据
- 付款历史
- 购买交易
他们还可能考虑非传统信用变量,例如:
- 客户填写表格的方式
- 客户用来到达站点的方法或他们导航站点的方式
- 填写申请所需的时间
数据清理和转换
正如汽油为汽车提供动力一样,数据是 AI 的命脉。 古老的格言“垃圾进,垃圾出”仍然令人痛苦。 因此,拥有干净准确的数据对于生成一致,可重现和准确的 AI 模型至关重要。 其中一些数据清理需要艰苦的人类参与。 通过某种方法,据说数据科学家花费了大约 80% 的时间来清理,准备和转换输入数据,而花费了 20% 的时间运行并优化模型。 例如 ImageNet 和 MS-COCO 图像数据集。 两者都包含超过一百万个带有标签的各种对象和类别的图像。 这些数据集用于训练模型,该模型可以区分不同类别和对象类型。 最初,这些数据集是由人类艰苦而耐心地标记的。 随着这些系统的普及,我们可以使用 AI 进行标记。 此外,还有许多支持 AI 的工具可帮助进行清理和重复数据删除过程。
亚马逊湖形成就是一个很好的例子。 在 2019 年 8 月,亚马逊正式提供了 Lake Formation 的服务。 Amazon Lake Formation 自动执行创建数据湖通常涉及的一些步骤,包括数据的收集,清理,重复数据删除,编目和发布。 然后可以使数据可用于分析和构建机器模型。 要使用“湖泊形成”,用户可以使用预定义的模板将数据从一系列来源中引入湖泊。 然后,他们可以根据组织中各组所需的访问级别来定义用于控制数据访问的策略。
数据经过一些自动的准备,清理和分类,它们使用机器学习来自动执行这些任务。
Lake Formation 还提供了集中式仪表板,管理员可以在其中管理和监视跨多个分析引擎的数据访问策略,治理和审计。 用户还可以在结果目录中搜索数据集。 随着该工具在未来几个月和几年中的发展,它将使用他们最喜欢的分析和机器学习服务促进数据分析,其中包括:
- DataBricks
- Tableau
- 亚马逊 Redshift
- 亚马逊 Athena
- AWS Glue
- 亚马逊 EMR
- 亚马逊 QuickSight
- 亚马逊 SageMaker
总结
本章提供了一些 AI 应用的示例。 也就是说,这里的内容并没有开始刮擦表面! 我们试图将用例保留在广泛使用的技术上,或者至少将在不久之后变得可用的技术上。 不难推断该技术将如何继续改进,变得更便宜并得到更广泛的应用。 例如,当自动驾驶汽车开始流行时,这将非常令人兴奋。
但是,我们可以肯定的是,甚至还没有构思出 AI 的更大应用。 而且,人工智能的进步将对我们的社会产生广泛的影响,并且在某些时候,我们将不得不处理以下问题:
- 如果 AI 如此进化以至于变得有意识,会发生什么? 应该给它权利吗?
- 如果用机器人代替人类,是否应该要求公司继续为该流离失所者支付工资税?
- 我们是否可以做到计算机无所不能,如果这样做,我们将如何适应? 我们将如何度过时间?
- 更糟糕的是,该技术是否使少数人能够控制所有资源? 会否出现一个个人可以追求自己的利益的普遍收入社会? 还是流离失所的人民生活在贫困中?
比尔·盖茨和埃隆·马斯克警告说,人工智能要么疯狂地追求自己的目标就摧毁地球,要么是偶然地(或偶然地)破坏了人类。 我们将对 AI 的影响持更为乐观的“半满”看法,但是可以肯定的是,这将是一段有趣的旅程。
参考
Willingham, Emily, A Machine Gets High Marks for Diagnosing Sick Children, Scientific American, October 7th, 2019, https://www.scientificamerican.com/article/a-machine-gets-high-marks-for-diagnosing-sick-children/
Clark, Jack, Google Turning Its Lucrative Web Search Over to AI Machines, Bloomberg, October 26th, 2015, https://www.bloomberg.com/news/articles/2015-10-26/google-turning-its-lucrative-web-search-over-to-ai-machines
- https://www.michaelcaines.com/michael-caines/about-michael/
3 机器学习管道
模型训练只是机器学习过程中的一小部分。 数据科学家经常花费大量时间来清理,转换和准备数据,以使其准备好供机器学习模型使用。 由于数据准备是一项非常耗时的活动,因此,我们将介绍最先进的技术来促进该活动以及其他组成良好设计的生产机器学习管道的组件。
在本章中,我们将涵盖以下关键主题:
- 机器学习管道到底是什么?
- 生产质量的机器学习管道的组成部分是什么?
- 部署机器学习模型时的最佳实践是什么?
- 机器学习管道到位后,我们如何缩短部署周期?
什么是机器学习管道?
许多开始进行机器学习训练的年轻数据科学家都希望立即跳入模型构建和模型调整阶段。 他们没有意识到,创建成功的机器学习系统所涉及的不仅仅是在随机森林模型和支持向量机模型之间进行选择。
从选择适当的提取机制到数据清理再到特征工程,机器学习管道中的初始步骤与模型选择一样重要。 出色的结果和平庸的结果之间的区别还在于,能够正确地测量和监视模型在生产中的表现,并决定何时以及如何重新训练模型。 随着世界的变化,您的输入变量也会变化,并且您的模型也必须随之变化。
随着数据科学的发展,期望值越来越高。 数据源变得更加多样化,数量庞大(就大小而言)并且数量众多(就数量而言),并且管道和工作流变得更加复杂。 我们期望越来越多的数据本质上是实时的,这无济于事。 考虑一下网络日志,点击数据,电子商务交易和自动驾驶汽车输入。 这些系统中的数据来得太快了,我们必须拥有能够比接收到的信息更快处理信息的方法。
存在许多机器学习解决方案来实现这些管道。 当然,仅使用 Python 或 R 语言就可以建立基本的机器学习管道。 我们将通过布局使用 Python 的管道示例来开始建立我们的理解。 在本章中,我们将详细探讨一些利用当今最流行工具的架构。 数据管道通常利用的一些工具是:
- Hadoop
- Spark
- Spark Streaming
- Kafka
- Azure
- AWS
- Google Cloud Platform
- R
- SAS
- DataBricks
- Python
正如我们将看到的,其中一些更适合管道的某些阶段。 让我们快速概述一下设置机器学习管道所需的最少步骤。
要考虑的一个重要事项是,管道中的每个步骤都会产生输出,该输出将成为管道中下一步的输入。 术语管道有点误导,因为它暗示了单向数据流。 实际上,机器学习管道可以是循环的和迭代的。 可能会重复管道中的每个步骤,以获得更好的结果或更干净的数据。 最后,下一次执行管道循环时,可以将输出变量用作输入。
机器学习管道的主要步骤是:
- 问题定义:定义业务问题。
- 数据提取:识别并收集数据集。
- 数据准备:使用以下技术处理和准备数据:
- 估计缺失值
- 删除重复的记录
- 标准化值(更改数据集中的数值以使用通用刻度)
- 执行另一种类型的清理或映射
- 完整的特征提取
- 消除相关特征
- 执行特征工程
- 数据隔离:将数据拆分为训练集,验证集和测试集。
- 模型训练:针对训练数据集训练机器模型。 这是数据科学的核心。 在本章中,我们将仅涉及此步骤的表面以及后续步骤。 本书中还有其他章节将更详细地介绍模型训练。 在这里列出它主要是为了使读者完整了解整个管道。
- 候选模型评估:使用数据的测试和验证子集来测量模型的表现,以确定模型的准确率。
- 模型部署:一旦选择了模型,请将其部署到生产中以进行推断。
- 表现监视:连续监视模型表现,相应地进行重新训练和校准。 收集新数据以继续改进模型并防止其过时:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FgaTngF7-1681568559567)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_03_01.png)]
图 1:机器学习管道
让我们进一步探索并深入研究管道的组成部分。
问题定义
在设置管道时,此可能是最关键的步骤。 在此花费的时间可以在管道的后期阶段为您节省大量的时间。 这可能意味着技术突破或失败之间的差异,也可能意味着创业公司成功或破产之间的差异。 提出和提出正确的问题至关重要。 考虑以下警告故事:
“鲍勃花了数年时间计划,执行和优化如何征服山丘。不幸的是,结果证明那是错误的山丘。”
例如,假设您要创建一个管道来确定贷款违约预测。 您最初的问题可能是:
对于给定的贷款,它是否违约?
现在,这个问题不区分贷款第一个月或贷款二十年的违约。 显然,与发行终止后的贷款相比,在发行时出现违约的贷款的利润要低得多。因此,一个更好的问题可能是:
贷款何时会违约?
这是一个更有价值的问题。 我们可以做得更好吗? 有时借款人可能每月不会发送全额应付款。 有时,借款人可能会零星发送款项。 为了解决这个问题,我们可能会进一步完善问题:
给定的贷款将获得多少钱?
让我们进一步改善它。 今天的一美元比将来的一美元更值。 因此,财务分析师使用公式来计算货币的现值。 关于借款人偿还多少贷款同样重要的是他们何时偿还贷款的问题。 另外,您还有预付款的问题。 如果借款人预付了一笔贷款,这将使该笔贷款的利润减少,因为它将收取的利息减少。 让我们再次更改问题:
一笔给定贷款的利润是多少?
我们完成问题了吗? 也许。 让我们再考虑一件事。 根据法律,某些输入变量不允许用于确定默认利率。 例如,种族和性别是不能用来确定贷款资格的两个因素。 再尝试一次:
如果不使用不允许的输入特征,给定贷款的利润将是多少?
我们将其留给读者以进一步完善问题。 如您所见,机器学习管道中的第一步和关键步骤需要考虑很多问题。
数据提取
一旦达到您满意的程度,您就可以精心制作和完善问题了,现在该收集原始数据以帮助您回答问题了。 这并不意味着一旦继续进行下一步,就无法更改您的问题。 您应该不断完善问题陈述并根据需要进行调整。
为管道收集正确的数据可能是一项艰巨的任务。 根据您要解决的问题,获取相关数据集可能非常困难。
另一个重要的考虑因素是决定如何将数据来源,提取和存储:
- 我们应该使用什么数据提供者或供应商? 他们可以信任吗?
- 如何提取? Hadoop,Impala,Spark,仅 Python 等?
- 应该将其存储为文件还是数据库中?
- 什么类型的数据库? 传统的 RDBMS,NoSQL,图。
- 它甚至应该存储吗? 如果我们有实时输入管道,甚至可能没有必要或没有效率地存储输入。
- 输入应采用什么格式? HWF,JSON,CSV。
很多时候,我们甚至可能无法控制输入源来决定应采用的格式,我们应按原样进行处理,然后决定如何进行转换。 此外,我们可能没有唯一的数据源。 在我们可以将它们输入模型之前,可能需要合并,合并和合并多个源。
尽管我们长期以来都希望人工智能和能够取代人类智能,但是确定输入数据集中应包含哪些变量仍然需要人类智能,甚至可能有些古老的人类直觉。
如果您要预测股价,那么前一天的股价似乎是显而易见的输入。 其他输入(例如利率,公司收益,新闻标题等)可能不太明显。
对于餐厅的日常销售,前一天的销售可能也很重要。 其他可能包括:星期几,节假日或不节假日,下雨或不下雨,每天的人流量等等。
对于象棋和围棋这样的游戏系统,我们可能会提供以前的游戏或成功的策略。 例如,人类学习国际象棋的最佳方法之一是学习大师级玩家过去成功使用的开局和技巧以及观看过去锦标赛中完成的游戏。 通过使用此先前的知识和历史来决定将来的游戏方式,计算机可以以相同的方式学习。
到目前为止,选择相关的输入变量并建立成功的模型仍然需要数据科学家具有领域知识。 并在某些情况下具有深厚的领域知识。 让我们进一步探讨一个例子。
继续以贷款违约为例,让我们考虑一些最重要的特征,以便做出准确的预测。 这是该列表的第一个选项。 由于篇幅所限,我们将不列出所有通常使用的特征。 我们将从数据中学到的内容添加和删除项目:
特征名称 | 特征描述 | 为什么有用? |
---|---|---|
欠款帐户 | 借款人现在拖欠的帐户数。 | 如果借款人在支付账单方面遇到困难,他们可能会在支付新贷款方面遇到困难。 |
贸易账户 | 在过去 24 个月内开设的交易数量。 | 如果数量太少,这只是一个问题。 |
借款人地址 | 借款人在贷款申请中提供的地址。 | 丢掉它。地址是唯一的。 唯一变量不提供预测能力。 |
邮政编码 | 借款人在贷款申请中提供的邮政编码。 | 这不是唯一的,可以具有预测能力。 |
年收入 | 借款人在注册期间提供的自报年收入。 | 更多的收入使借款人可以更轻松地处理更大的付款。 |
当前余额 | 所有帐户的平均当前余额。 | 孤立地没有价值。 需要相对。 |
注销 | 12 个月内的注销次数。 | 指示借款人以前的违约行为。 |
逾期金额 | 借款人现在拖欠其帐户的逾期金额。 | 指示借款人以前的违约行为。 |
最早的帐户 | 自最早的循环帐户开设以来的月数。 | 表示借款人借钱的经历。 |
就业时间 | 就业年限。 | 表示借款人的稳定性。 |
贷款额度 | 在该时间点对该贷款的承诺总额。 | 孤立地没有价值。 需要相对。 |
查询数量 | 个人理财查询数量。 | 借款人寻找信用。 |
利率 | 贷款利率。 | 如果贷款的利率很高,则还款额将更多,并且可能难以偿还。 |
最大余额 | 所有循环帐户上的最大当前余额。 | 如果接近 100%,则可能表明借款人有财务困难。 |
自上次公开记录以来的月数 | 自上次公开记录以来的月数。 | 指示先前的财务困难 |
逾期帐户数 | 逾期 120 天或以上的帐户数 | 当前财务困难的指示 |
公开记录 | 贬损的公共记录数 | 指示先前的财务困难 |
项目 | 每月偿还贷款的次数。 | 贷款时间越长,潜在的违约可能性就越大。 |
当前总余额 | 所有帐户的当前总余额 | 孤立地没有价值。 需要相对。 |
正如我们所看到的,其中某些变量本身并没有提供含义,需要将它们组合起来以进行预测。 这将是特征工程的一个例子。 新变量的两个示例是:
特征名称 | 特征描述 | 为什么有用? |
---|---|---|
信贷比例 | 在所有交易中将平衡到信用额度。 当前余额与信用额度的比较。 | 较高的百分比表示借款人“已用光”,并且在获得新的信贷方面遇到困难。 |
债务收入比 | 使用每月总债务支付的总债务(不包括抵押和请求的贷款)除以借款人的自我报告的每月收入来计算。 | 较低的债务对收入比率表明借款人有足够的资源来偿还其债务,并且不应该有满足这些债务的问题。 |
数据准备
下一步是处理原始数据的数据转换层; 需要完成的一些转换是:
- 数据清理
- 过滤
- 聚合
- 扩充
- 合并
- 存储
云提供商已成为主要的数据科学平台。 一些最受欢迎的栈是围绕以下构建的:
- Azure ML 服务
- AWS SageMaker
- GCP Cloud ML 引擎
- SAS
- RapidMiner
- Knime
执行这些转换的最流行的工具之一是 Apache Spark,但它仍然需要数据存储。 对于持久性,最常见的解决方案是:
- Hadoop 分布式文件系统(HDFS)
- HBase
- Apache Cassandra
- 亚马逊 S3
- Azure Blob 存储
还可以在数据库内部原地处理数据以进行机器学习。 SQL Server 和 SQL Azure 等数据库正在添加特定的机器学习功能,以支持机器学习管道。 Spark 具有 Spark Streaming 内置的功能。 它可以从 HDFS,Kafka 和其他来源读取数据。
还有其他替代方法,例如 Apache Storm 和 Apache Heron。 不管管道中有什么其他内容,通常都在交互式 Jupyter 笔记本电脑或 R Studio 中完成数据的初始探索。
某些实时数据处理解决方案提供了容错,可伸缩,低延迟的数据提取。 一些最喜欢的是:
- Apache Kafka
- Azure 事件中心
- AWS Kinesis
现在,让我们探讨数据准备的关键操作之一-数据清理。 我们需要确保数据是干净的。 数据将很可能不是完美的,并且数据质量将不会达到最佳。 数据可能由于以下原因而不合适:
缺失值
我们的数据经常包含缺失值,或者缺失值被零或 N/A 代替。 我们该如何处理这个问题? 以下是处理缺失值的六种不同方法:
- 不执行任何操作:有时最好的操作是不执行任何操作。 根据所使用的算法,并非总是需要对缺失值进行任何操作。 XGBoost 是可以优雅处理缺失值的算法示例。
- 使用中值进行插补:当缺少值时,分配给缺失数据的合理值是该变量的所有其余非缺失值的中值。 此替代方案易于计算,并且快速,并且适用于小型数据集。 但是,它没有提供太多的准确率,也没有考虑与其他变量的相关性。
- 使用最频繁的值或常量进行插补:另一种选择是分配最频繁的值或常量(如零)。 这种方法的一个优势是它适用于非数值变量。 像以前的方法一样,它不考虑与其他变量的相关性,并且根据空值的频率,它可以在数据集中引入偏差。
重复的记录或值
如果两个值确实相同,则很容易创建可以查找重复值的查询或程序。 如果应该假设两个记录或值标识相同的实体,但是两个值之间存在细微差异,那么麻烦就开始了。 传统的重复数据库查询可能找不到拼写错误,缺少值,地址更改或遗漏中间名的人。 有些人使用别名。
直到最近,查找和修复重复记录一直是一个手动过程,该过程耗时且耗费资源。 但是,一些使用 AI 查找重复项的技术和研究开始兴起。 除非所有详细信息完全匹配,否则很难确定不同的记录是否引用同一实体。 另外,通常大多数重复项都是假阳性。 两个人可能具有相同的姓名,地址和出生日期,但仍然是不同的人。
识别重复项的解决方案是使用模糊匹配而不是精确匹配。 模糊匹配是一种计算机辅助技术,可对数据相似性进行评分。 它广泛用于执行模糊匹配。 讨论模糊匹配不在本书讨论范围之内,但对读者进一步研究该主题可能很有用。
特征缩放
数据集通常包含大小不等的特征。 特征大小的这种变化通常会对预测的准确率产生不利影响(但并非总是如此;例如,随机森林不需要特征缩放)。 许多机器学习算法使用数据点之间的欧几里得距离进行计算。 如果不进行此调整,则数量级高的特征将对结果产生过重的影响。
用于特征缩放的最常用的方法是:
- 重新缩放(最小-最大归一化)
- 平均归一化
- 标准化(Z 分数标准化)
- 缩放到单位长度
不一致的值
数据可能经常包含不一致的值。 此外,数据可能以多种方式不一致。 数据不一致的一个示例是街道地址修饰符。 考虑以下数据点:
Fifth Avenue
Fifth Ave
Fifth Av
Fifth Av.
作为人类,我们可以快速确定所有这些示例确实具有相同的值。 计算机很难得出这个结论。
解决此问题的两种方法是基于规则的和基于示例的。 当数据中的可变性较小且不会快速更改时,基于规则的系统会更好地工作。 当我们拥有快速移动的数据时,基于规则的方法就会中断。
考虑一个垃圾邮件过滤器。 我们可以创建一个规则,将带有Viagra
一词的任何内容标记为垃圾邮件,但是垃圾邮件发送者可能会变得很聪明,并开始更改数据以绕过该规则(Vi@gra
)。 在这种情况下,基于机器学习示例的清洁器会更好地工作。
有时,我们可能想考虑混合方法并同时使用这两种方法。 例如,一个人的身高应始终为正值。 因此,我们可以为此编写一条规则。 对于具有更多可变性的其他值,我们可以使用机器学习方法。
不一致的日期格式
- 11/1/2016
- 11/01/2016
- 11/1/16
- 16 年 11 月 1 日
- 2016 年 11 月 1 日
这些都是相同的值。 因此,我们需要标准化日期。
这不是完整的数据准备清单,而是旨在让您了解需要进行的不同转换才能清理和准备数据以使其有用。
数据隔离
按照的顺序使用已处理的数据训练模型,建议将数据分为两个子集:
- 训练数据
- 测试数据
有时分为三个:
- 训练数据
- 验证数据
- 测试数据
然后,您可以在训练数据上训练模型,以便以后对测试数据进行预测。 训练集对于模型是可见的,并根据此数据进行训练。 训练会创建一个推理引擎,以后可以将其应用于模型之前未看到的新数据点。 测试数据集(或子集)表示该看不见的数据,现在可以将其用于对该先前看不见的数据进行预测。
模型训练
一旦我们拆分了数据,现在就可以通过一系列模型来运行训练和测试数据,并评估各种模型的表现并确定每个候选模型的准确率。 这是一个反复的过程,可能需要测试各种算法,直到您拥有一个可以充分回答您问题的模型为止。
在后面的章节中,我们将深入研究此步骤。 本书的其余部分提供了大量的模型选择材料。
候选模型评估和选择
用训练模型后,各种算法又迈出了关键的一步。 现在是时候选择哪种模型最适合当前的问题。 我们并不总是选择表现最好的模型。 对训练数据执行良好的算法在生产中可能无法很好地执行,因为它可能过拟合了训练数据。 在这个时间点上,模型选择更多的是一门艺术,而不是一门科学,但是有一些技术需要进一步探索以确定哪种模型最好。
模型部署
一旦选择了模型并确定了模型,即可将其用于进行预测。 它通常通过 API 公开,并作为分析解决方案的一部分嵌入到决策框架中。
如何公开和部署它应由业务需求决定。 选择部署时要考虑的一些问题:
- 系统是否需要能够进行实时预测(如果是,预测速度如何:以毫秒,秒,分钟,小时为单位?)
- 需要多久更新一次模型?
- 预计会有多少数量或流量?
- 数据集的大小是多少?
- 是否有需要遵循和遵守的法规,策略和其他约束条件?
确认要求之后,我们现在可以考虑用于模型部署的高级架构。 以下是多种选择。 无论如何,这并不是一个详尽的清单,但它确实包含了一些较流行的架构:
RESTful API 架构 | 共享数据库架构 | 流架构 | 移动应用架构 | |
---|---|---|---|---|
训练方法 | 批量 | 批量 | 流式 | 流式 |
预测方法 | 即时 | 批量 | 流式 | 即时 |
结果交付 | 通过 RESTful API | 通过共享数据库 | 通过消息队列流式传输 | 通过移动设备上的进程内 API |
预测延迟 | 低 | 高 | 非常低 | 低 |
系统可维护性 | 中 | 简单 | 困难 | 中 |
如表中所总结,这四个选项各有利弊。 当我们深入研究架构的细节时,还需要考虑更多的考虑因素。 作为示例,可以使用模块化微服务架构或以整体方式来实现这些架构中的每一个。 同样,选择应该由业务需求决定。 例如,可以选择整体方法,因为我们的用例非常有限,需要极低的延迟。
无论为模型部署选择哪种架构,使用以下原则都是一个好主意:
- 可再现性:存储所有模型输入和输出,以及所有相关元数据,例如配置,依赖项,地理位置和时区。 需要解释过去的预测。 确保每个部署捆绑包的最新版本均可用,其中还应包含训练数据。 例如,这对于受到严格监管的领域尤其重要。
- 自动化:尽可能早地自动化训练和模型发布。
- 可扩展性:如果需要定期更新模型,则需要从头开始制定计划。
- 模块化:尽可能地对代码进行模块化,并确保已放置控件以忠实地再现跨环境的管道(DEV,QA,TEST)。
- 测试:分配时间表的重要部分以测试机器学习管道。 尽可能使自动化,并从一开始就将其集成到您的过程中。 探索测试驱动开发(TDD)和行为驱动开发(BDD)。
表现监控
一旦模型制作成,我们的工作就不会完成。 将模型投入生产可能并不容易,但是一旦部署了模型,就必须对其进行严格监控,以确保模型运行令人满意。 使模型投入生产需要涉及多个步骤。 对该模型进行连续监控,以观察其在现实世界中的行为并进行相应的校准。 收集新数据以逐步改进它。 同样,监视部署的机器学习模型需要从各个角度进行关注,以确保模型正在运行。 让我们分析一下在监视机器学习模型时需要考虑的这些不同指标,以及为什么每个指标都很重要:
模型表现
数据科学环境中的表现并不意味着模型运行的速度如何,而是预测的准确率。 监视机器学习模型的数据科学家主要关注一个指标:漂移。 当数据不再是模型的相关输入或有用输入时,就会发生漂移。 数据可能会更改并失去其预测价值。 数据科学家和工程师必须不断监控模型,以确保模型特征继续与模型训练期间使用的数据点相似。 如果数据漂移,则预测结果将变得不太准确,因为输入特征已过时或不再相关。 例如,考虑一下股票市场数据。 30 年前,市场大为不同。 它与众不同的一些方式包括:
- 证券交易所的交易量大大低于今天
- 高频交易甚至不是一个主意
- 被动指数基金不那么受欢迎
可以想象,这些特征使股票表现显着不同。 如果我们使用具有 30 年历史的数据来训练模型,则很可能无法使用当今的数据来执行模型。
运营表现
最终,机器学习管道仍然是软件系统。 因此,监视资源消耗仍然很重要,包括:
- CPU 利用率:识别峰值以及是否可以解释峰值。
- 内存使用情况:正在消耗多少内存。
- 磁盘使用率:我们的应用消耗了多少磁盘空间。
- 网络 I/O 流量:如果我们的应用跨越实例,则衡量网络流量非常重要。
- 延迟:数据传输所花费的时间。
- 吞吐量:成功传输的数据量。
如果这些指标发生变化,则需要对其进行分析以了解为什么会发生这些变化。
总拥有成本(TCO)
数据科学家需要根据每秒记录的数量来监视其模型的表现。 尽管这可以使您更深入地了解模型的效率,但公司还应将重点放在从模型中获得的收益与成本之间。 建议监视机器学习管道的所有步骤的成本。 如果密切跟踪此信息,则企业可以就如何降低成本以及如何把握新机遇,或者某些管道是否不能提供足够的价值而做出明智的决定,而需要进行更改或关闭。
服务表现
不在业务问题的上下文中的技术是没有用的。 企业经常与技术部门签订服务级别协议(SLA),或至少应该拥有。 SLA 的示例:
- 在一天内修复所有关键错误
- 确保 API 在 100 毫秒内响应
- 每小时至少处理一百万个预测
- 复杂的模型必须在 3 个月内设计,开发和部署
为了使业务最佳运行,重要的是建立,监视和满足先前商定的 SLA。
机器学习模型对于企业而言可能至关重要。 确保它们不会成为瓶颈的关键是正确监视已部署的模型。 作为您的机器学习管道的一部分,请确保监视部署的机器学习模型并与 SLA 进行比较,以确保获得令人满意的业务成果。
总结
本章详细列出了创建机器学习管道所涉及的不同步骤。 此游览应被视为所涉及步骤的初步概述。 随着本书的发展,您将学习如何改善自己的管道,但是我们确实学习了一些当今用于建立管道的最佳实践和最受欢迎的工具。 在审查中,成功管道的步骤如下:
- 问题定义
- 数据提取
- 数据准备
- 数据隔离
- 候选模型选择
- 模型部署
- 表现监控
在下一章中,我们将更深入地研究机器学习管道的步骤之一。 我们将学习如何执行特征选择,并学习什么是特征工程。 这两种技术对于提高模型表现至关重要。
4 特征选择和特征工程
特征选择(也称为变量选择,属性选择或变量子集选择)是一种用于从初始数据集中选择特征子集(变量,大小)的方法。 特征选择是构建机器学习模型过程中的关键步骤,并且可能对模型的表现产生巨大影响。 使用正确且相关的特征作为模型的输入还可以减少过拟合的机会,因为拥有更多相关的特征会减少模型使用不添加信号作为输入的嘈杂特征的机会。 最后,减少输入特征会减少训练模型所需的时间。 学习选择哪些特征是数据科学家开发的一项技能,通常仅来自数月和数年的经验,并且可以说是一门艺术,而不是一门科学。 特征选择很重要,因为它可以:
- 缩短训练时间
- 简化模型并使它们更易于解释
- 通过减少过拟合来增强测试集表现
删除特征的一个重要原因是输入变量之间的高度相关性和冗余性,或者某些特征的不相关性。 因此,可以删除这些输入变量,而不会造成很多信息丢失。 冗余和无关是两个截然不同的概念,因为一个相关特征在存在与之高度相关的另一个相关特征的情况下可能是多余的。
在某些方面,特征工程与特征选择相反。 使用特征选择,可以删除变量。 在特征工程中,您可以创建新变量来增强模型。 在许多情况下,您将使用领域知识进行增强。
特征选择和特征工程是机器学习管道中的重要组成部分,这就是为什么整章专门讨论该主题的原因。
到本章末,您将了解:
- 如何决定是否应从数据集中删除特征
- 了解共线性,相关性和因果关系的概念
- 了解特征工程的概念及其与特征选择的区别
- 了解手动特征工程和自动特征工程之间的区别。 什么时候适合使用每个?
特征选择
在上一章的中,我们探讨了机器学习管道的组件。 管道的关键组成部分是确定哪些特征将用作模型的输入。 对于许多模型,一小部分输入变量提供了大部分的预测能力。 在大多数数据集中,由少数几个特征负责大部分信息信号是很常见的,而其余的特征则主要是噪声。
出于多种原因,降低输入特征的数量很重要,包括:
- 减少输入特征的多重共线性将使机器学习模型参数更易于解释。 多重共线性(也共线性)是在数据集中的特征中观察到的现象,在该数据集中可以从另一个模型的特征中线性预测另一个预测器特征,并且准确率很高。
- 减少运行模型所需的时间和模型所需的存储空间,将使我们能够运行模型的更多变体,从而带来更快更好的结果。
- 模型需要的输入特征越少,说明它就越容易。 当特征数量增加时,模型的可解释性下降。 减少输入特征的数量还可以简化为较小大小(例如 2D 或 3D)时可视化数据的过程。
- 随着维数的增加,可能的配置呈指数增加,而观测值覆盖的配置数则减少。 随着您具有描述目标的更多特征,您也许可以更精确地描述数据,但是您的模型将不会使用新的数据点进行泛化-您的模型将过拟合数据。 这就是维度诅咒。
让我们通过一个例子直观地思考一下。 美国有一个房地产网站,允许房地产经纪人和房主列出出租房屋或出售房屋。 Zillow 因其 Zestimate 而闻名。 Zestimate 是使用机器学习的估计价格。 Zillow 估计,如果今天将其投放市场,房屋将要出售的价格。 Zestimates 会不断更新和重新计算。 Zillow 如何得出这个数字? 如果您想了解更多,可以在 Kaggle 上进行一场比赛,该比赛在 Zestimate 上有很多资源。 你可以在这里查询更多详情。
Zestimate 算法的确切细节是专有的,但是我们可以做一些假设。 现在,我们将开始探索如何提出自己的 Zestimate。 让我们为我们的机器学习模型列出潜在的输入变量,以及它们可能很有价值的原因:
- 平方英尺:直观上来说,房屋越大,价格就越高。
- 卧室数量:更多房间,更多费用。
- 浴室数量:卧室需要浴室。
- 抵押贷款利率:如果利率较低,则抵押贷款支付将降低,这意味着潜在的房主可以负担得起更昂贵的房屋。
- 建成年份:通常,较新的房屋比旧的房屋更贵。 老房子通常需要更多的维修。
- 财产税:如果财产税高,那将增加每月的还款额,房主将只能负担更便宜的房屋。
- 房屋颜色:乍看之下,这似乎并不是一个相关变量,但是如果房屋涂成石灰绿色怎么办?
- 邮政编码:位置,位置,位置。 在房地产中,房屋所在地是价格的重要决定因素。 在某些情况下,一个街区的房屋可能比下一个街区的房屋多几十万美元。 位置可能很重要。
- 可比较的销售额:评估师和房地产经纪人通常用来评估房屋价值的一种指标是寻找与最近出售或至少列出的“标的”房地产相似的房地产,以查看销售价格或当前的上市价格。
- 税收评估:财产税是根据县目前认为财产的价值来计算的。 这是可公开访问的信息。
这些都可能是具有较高预测能力的变量,但直觉上我们可以假设平方英尺,卧室数量和浴室数量高度相关。 同样,从直觉上讲,平方英尺比卧室或浴室的数量更精确。 因此,我们可以减少卧室和浴室的数量,并保持平方英尺,而不会损失太多精度。 确实,我们可以通过降低噪声来提高准确率。
此外,我们很可能会在不损失精度的情况下降低房屋的颜色。
在不影响模型精度的情况下可以删除的特征分为两类:
- 冗余:此特征与其他输入特征高度相关,因此不会在信号中添加太多新信息。
- 不相关:此特征与目标函数的相关性较低,因此提供的噪声大于信号。
找出我们的假设是否正确的一种方法是在有或没有我们的假设的情况下训练模型,并查看产生更好结果的方法。 我们可以对每个单个特征使用此方法,但是如果我们具有大量特征,则可能会迅速增加组合的数量。
正如我们之前提到的,探索性数据分析是获得直观了解和深入了解正在使用的数据集的好方法。 让我们分析通常用于获取这些见解的三种方法。 他们是:
- 特征重要性
- 单变量选择
- 具有热图的相关矩阵
特征重要性
可以使用此方法确定数据集每个特征的重要性。
特征重要性为数据集中的每个特征提供分数。 较高的分数意味着该特征相对于输出特征具有更高的重要性或相关性。
特征重要性通常是基于树的分类器随附的内置类。 在以下示例中,我们使用额外树分类器确定数据集中的前五项特征:
代码语言:javascript复制import pandas as pd
代码语言:javascript复制from sklearn.ensemble import ExtraTreesClassifier
import numpy as np
import matplotlib.pyplot as plt
代码语言:javascript复制data = pd.read_csv("train.csv")
X = data.iloc[:,0:20] #independent columns
y = data.iloc[:,-1] # pick last column for the target feature
代码语言:javascript复制model = ExtraTreesClassifier()
model.fit(X,y)
print(model.feature_importances_) #use inbuilt class
#feature_importances of tree based classifiers
#plot graph of feature importances for better visualization
feat_importances = pd.Series(model.feature_importances_, index=X.columns)
feat_importances.nlargest(5).plot(kind='barh')
plt.show()
您应该将视为输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RaovGV3T-1681568559568)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_01.png)]
图 1:特征重要性图
单变量选择
可以使用统计测试来确定哪些特征与输出变量具有最强的相关性。 scikit-learn 库具有一个名为SelectKBest
的类,该类提供一组统计测试以选择数据集中的K
“最佳”特征。
以下是一个示例,该示例对非负特征使用卡方(chi²)统计检验,以选择输入数据集中的五个最佳特征:
代码语言:javascript复制import pandas as pd
import numpy as np
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
data = pd.read_csv("train.csv")
X = data.iloc[:,0:20] #independent columns
y = data.iloc[:,-1] #pick last column for the target feature
#apply SelectKBest class to extract top 5 best features
bestfeatures = SelectKBest(score_func=chi2, k=5)
fit = bestfeatures.fit(X,y)
dfscores = pd.DataFrame(fit.scores_)
代码语言:javascript复制dfcolumns = pd.DataFrame(X.columns)
scores = pd.concat([dfcolumns,dfscores],axis=1)
scores.columns = ['specs','score']
print(scores.nlargest(5,'score')) #print the 5 best features
并且您应该看到这样的输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-szagXFTe-1681568559568)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_02.png)]
图 2:最佳特征映射
相关性热图
当特征的不同值之间存在关系时,两个特征之间存在相关性。 例如,如果房价随着平方英尺的增加而上涨,则这两个特征被认为是正相关的。 可能存在不同程度的相关性。 如果一个特征相对于另一个特征一致地改变,则这些特征被认为是高度相关的。
相关可以是正的(特征的一个值的增加会增加目标变量的值)或负的(特征的一个值的增加会降低目标变量的值)。
关联是 -1 和 1 之间的连续值。
- 如果两个变量之间的相关性为 1,则存在完美的直接相关性。
- 如果两个特征之间的相关性为 -1,则存在理想的逆相关性。
- 如果两个特征之间的相关性为 0,则两个特征之间没有相关性。
热图可轻松识别与目标变量最相关的特征。 我们将使用seaborn
库并使用以下代码来绘制相关特征的热图:
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
代码语言:javascript复制data = pd.read_csv("train.csv")
X = data.iloc[:,0:20] #independent columns
y = data.iloc[:,-1] # pick last column for the target feature
#get the correlations of each feature in the dataset
correlation_matrix = data.corr()
top_corr_features = correlation_matrix.index
plt.figure(figsize=(20,20))
#plot heat map
g=sns.heatmap(data[top_corr_features].corr(),annot=True,cmap="RdYlGn")
您应该获得与以下类似的输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qNhfwFlC-1681568559568)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_03.png)]
图 3:相关热图
存在更多形式化和较少的直观方法来自动选择特征。 存在许多这些方法,并且在 scikit-learn 包中实现了许多方法。 接下来提到对这些方法进行分类的一种方法。
基于包装器的方法
使用包装器方法时,使用以下步骤可将特征选择的问题实质上减少为搜索问题:
- 特征子集用于训练模型
- 根据每次迭代的结果,将特征添加到子集中或从子集中删除
包装方法通常在计算上很昂贵。 以下是一些示例:
- 正向选择:正向选择方法是一个迭代过程,其开始时数据集中没有特征。 在每次迭代过程中,都会添加特征以改善模型的表现。 如果表现得到改善,则保留特征。 无法改善结果的特征将被丢弃。 该过程一直持续到模型停止改进为止。
- 反向消除:当使用反向消除方法时,所有特征最初都在数据集中出现。 重要性最低的特征将在每次迭代过程中删除,然后该过程将检查模型的表现是否得到改善。 重复该过程,直到没有观察到明显的改善为止。
- 递归特征消除:递归特征消除方法是一种贪婪的优化算法,其目标是找到表现最佳的特征子集。 它迭代创建模型,并在每次迭代期间存储表现最佳或最差的特征。 它将使用其余特征构造下一个模型,直到所有特征用尽。 然后根据特征的消除顺序对其进行排序。
基于过滤器的方法
指定度量,并基于该度量特征过滤。 基于过滤器的方法的示例包括:
- 皮尔逊相关性:此算法用作量化两个连续变量
X
和Y
之间的线性相关性的度量。 它的值可以介于 -1 到 1 之间。 - 线性判别分析(LDA):LDA 可用于查找特征的线性组合,这些特征描述或分隔了分类变量的两个或更多个级别(或类)。
- 方差分析(ANOVA):ANOVA 类似于 LDA,不同之处在于它是使用一个或多个分类自变量和一个连续因变量计算的。 它提供了统计检验,以了解几组的平均值是否相等。
- 卡方:卡方是一种统计测试,应用于类别变量组,以使用它们的频率分布确定它们之间相关或关联的可能性。
要记住的一个问题是,基于过滤器的方法不会消除多重共线性。 因此,在根据输入数据创建模型之前,必须执行其他处理以处理特征多重共线性。
嵌入式方法
嵌入式方法使用具有内置特征选择方法的算法。 嵌入式方法结合了过滤器和包装器方法的优点。 通常使用带有内置特征选择方法的算法来实现它们。
两种流行的嵌入式方法实现如下:
- LASSO 回归:执行 L1 正则化,这会增加与系数的绝对值相等的惩罚
- Ridge 回归:执行 L2 正则化,这将增加与系数幅度的平方相等的惩罚
这些算法也很常用:
- 模因算法
- 随机多项式对数
- 正则化树
到此结束本章的第一部分。 您应该准备好应对自己的特征选择项目。 现在,准备好进入特征工程领域。 特征选择与我们如何减少变量数量以提高准确率有关。 特征工程则相反。 它问:我们如何创建新变量以使我们的模型更具表现?
特征工程
根据最近在《福布斯》杂志上进行的调查,数据科学家将其 80% 的时间用于数据准备:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jFRldltZ-1681568559569)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_04.png)]
图 4:数据科学家花费的时间细分(来源:《福布斯》)
该统计数据突显了数据准备和特征工程在数据科学中的重要性。
就像明智的和系统化的特征选择可以通过删除特征使模型更快,更高效一样,特征工程可以通过添加新特征来实现相同的目的。 乍看之下这似乎是矛盾的,但是要添加的特征不是由特征选择过程删除的特征。 要添加的特征是可能未包含在初始数据集中的特征。 您可能拥有世界上最强大,设计最完善的机器学习算法,但是如果您的输入特征不相关,您将永远无法产生有用的结果。 让我们分析几个简单的例子以获得一些直觉。
在上一章中,我们探讨了贷款违约问题。 凭直觉,可以推测,如果借款人的工资高,借款人的违约率就会降低。 同样,我们可以假设,与余额较低的人相比,信用卡余额较大的借款人可能很难偿还这些余额。
现在我们有了新知识,让我们尝试直观地确定谁将偿还贷款,谁不偿还贷款。 如果借款人A的信用卡余额为 10,000,而借款人B的余额为 20,000,您认为谁有更大的机会还清债务? 如果没有其他信息,我们可以说借款人A是更安全的选择。 现在,如果我告诉您借款人A年收入为 20,000 美元,借款人B年收入为 100,000 美元,该怎么办? 那改变了一切,不是吗? 我们如何定量捕捉两个特征之间的关系? 银行经常使用所谓的,债务收入比(DTI),该比率的计算方法如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vhAIvXzG-1681568559569)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_001.png)]
因此,借款人 A 的 DTI 为 0.50,借款人B
的债务收入比为 0.20。 换句话说,借款人A
的债务是其债务的两倍,借款人B
的债务是其债务的 5 倍。 借款人B
有更大的偿还债务空间。 我们当然可以在这些借款人的配置文件中添加其他特征,这将改变其配置文件的构成,但是希望这有助于说明特征工程的概念。
更正式地讲,特征工程是数据科学家或计算机生成可增强机器学习模型的预测能力的特征的过程。 特征工程是机器学习中的一个基本概念,可能既困难又昂贵。 许多数据科学家希望直接跳入模型选择,但是辨别哪些新特征将增强模型的能力是一项关键技能,可能需要花费数年才能掌握。
更好的特征工程算法的发展目前正在紧锣密鼓地进行,有一天,在特征工程决策方面,这些特征可能会比高级数据科学家更好,但是,在接下来的几年中,我们预测仍会需要优秀的数据科学家。
特征工程过程可以描述如下:
- 集体讨论哪些特征相关
- 确定哪些特征可以改善模型表现
- 创建新特征
- 确定新特征是否会增加模型表现; 如果没有,丢弃它们
- 返回“步骤 1”,直到模型的表现达到预期
正如我们在示例中看到的那样,拥有域知识并熟悉数据集对于特征工程很有用。 但是,也有一些通用的数据科学技术可应用于数据准备和特征工程步骤中,而不管其域是什么。 让我们花一些时间分析这些技术。
我们将探讨的技术是:
- 归因
- 离群值管理
- 单热编码
- 对数转换
- 缩放比例
- 日期操作
估计
数据集“肮脏”且不完美的情况并不少见。 缺少值的行是一个常见问题。 值丢失的原因可能有很多:
- 数据集不一致
- 笔误
- 隐私问题
不管出于何种原因,缺少值都会影响模型的表现,并且在某些情况下,由于某些算法不会善待缺失值,因此可能会导致模型停止运行。 有多种技术可以处理缺失值。 它们包括:
删除缺少值的行:此技术会降低模型的表现,因为它减少了模型必须训练的数据点的数量。
让我们看一个示例,该示例删除缺少 60% 以上数据的列:
代码语言:javascript复制threshold = 0.6
#Drop columns with a missing value rate higher than threshold
data = data[data.columns[data.isnull().mean() < threshold]]
代码语言:javascript复制#Drop rows with missing value rate higher than threshold
data = data.loc[data.isnull().mean(axis=1) < threshold]
threshold = 0.6
#Drop columns with a missing value rate higher than threshold
data = data[data.columns[data.isnull().mean() < threshold]]
代码语言:javascript复制#Drop rows with missing value rate higher than threshold
data = data.loc[data.isnull().mean(axis=1) < threshold]
print(data)
输出应如下所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i3Mkf75p-1681568559569)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_05.png)]
图 5:丢弃缺失值输出
数值插补:插补是处理缺失值的另一种方法。 归因只是将缺失的值替换为另一个“有意义的”值。
对于数字变量,这些是常见的替换:
- 将零用作替换值是一种选择
- 计算整个数据集的平均值,然后用平均值替换缺失值
- 计算整个数据集的中值,然后用中值替换缺失值
通常最好使用中值而不是平均值,因为平均值更容易受到异常值的影响。 让我们看一些替换示例:
代码语言:javascript复制#Filling all missing values with 0
data = data.fillna(0)
代码语言:javascript复制#Filling missing values with medians of the columns
data = data.fillna(data.median())
print(data)
您将能够滚动显示输出并查看更改的值:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FAJXXd18-1681568559569)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_06.png)]
图 5:丢弃缺失值输出
分类插补:分类变量不包含数字,而是包含类别。 例如,红色,绿色和黄色。 或香蕉,苹果和橙子。 因此,平均值和均值不能与分类变量一起使用。 常用的技术是用出现最多的值替换所有缺失值。
在存在许多类别或类别均匀分布的情况下,使用诸如“其他”之类的名称可能有意义。 让我们看一下 Python 中的示例,该示例将所有缺少的值替换为最常出现的值(Python 中的idxmax
返回整个特征中最常见的值):
#Max fill function for categorical columns
import pandas as pd
代码语言:javascript复制data = pd.read_csv("dataset.csv")
代码语言:javascript复制data['color'].fillna(data['color'].value_counts().idxmax(), inplace=True)
print(data)
输出应类似于以下内容:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6R8ihNj8-1681568559570)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_07.png)]
图 7:填充缺失值输出
离群值管理
房价是一个很好的领域,需要进行分析以了解为什么我们需要特别注意异常值。 无论您居住在世界的哪个区域,您附近的大多数房屋都将落入一定范围内,并且将具有某些特征。 也许是这样的:
- 1 至 4 间卧室
- 1 个厨房
- 500 至 3000 平方英尺
- 1 至 3 间浴室
2019 年美国的平均房价为 226,800 美元。 您可以猜测,这种房屋可能会具有上述某些特征。 但也可能有几所房子是异常值。 也许有 10 或 20 间卧室的房子。 其中一些房屋可能价值一百万或一千万美元,具体取决于这些房屋可能具有的疯狂定制数量。 正如您可能想象的那样,这些离群值将影响数据集中的均值,并且将对均值产生更大的影响。 因此,鉴于这些房屋的数量不多,最好删除这些离群值,以免影响其他较常见的数据点的预测。 让我们看一些房屋价值的图表,然后尝试画出两条最合适的线:一条去除所有数据,一条去除高价房屋离群值:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3ms4ghUs-1681568559570)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_08.png)]
图 8:最佳拟合图
如您所见,如果从最佳拟合线的计算中除去异常值,则该线将更准确地预测低价房屋。 因此,简单地删除异常值是处理异常值影响的简单而有效的方法。
那么,我们如何确定某个值是否为离群值并应将其删除? 一种常见的方法是删除落在数据集中某个特征值的标准差的某个倍数的离群值。 用于乘数的常量更多的是一门艺术,而不是一门科学,但是 2 到 4 之间的值很常见:
代码语言:javascript复制#Dropping the outlier rows with standard deviation
import pandas as pd
代码语言:javascript复制data = pd.read_csv("train.csv")
代码语言:javascript复制#Dropping the outlier rows with standard deviation
factor = 2
upper_lim = data['battery_power'].mean () data['battery_power'].std () * factor
lower_lim = data['battery_power'].mean () - data['battery_power'].std () * factor
代码语言:javascript复制data = data[(data['battery_power'] < upper_lim) & (data['battery_power'] > lower_lim)]
print(data)
输出应为,类似于:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mQI8PGqF-1681568559570)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_09.png)]
图 9:删除异常行输出
检测和消除异常值的另一种方法是使用百分位。 使用这种方法,我们仅假设特征值的一定百分比是离群值。 下降多少百分比值仍然是主观的,并且将取决于领域。
让我们看一个 Python 示例,在其中将最高和最低 1% 的部分删除:
代码语言:javascript复制#Dropping the outlier rows with Percentiles
upper_lim = data['battery_power'].quantile(.99)
lower_lim = data['battery_power'].quantile(.01)
代码语言:javascript复制data = data[(data['battery_power'] < upper_lim) & (data['battery_power'] > lower_lim)]
print(data)
预期的输出如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uQsu8ge0-1681568559576)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_10.png)]
图 10:输出异常值行
处理离群值的另一种方法是设置值上限而不是删除值。 封顶值而不是删除行允许您保留数据点,并有可能提高模型的表现。 但是,保留数据点但限制值的上限会使该数据点成为估计值而不是实际观察值,这也可能会影响结果。 决定使用哪种方法将取决于对特定数据集的分析。 这是一个使用上限值而不是删除行的示例:
代码语言:javascript复制#Capping the outlier rows with percentiles
upper_lim = data['battery_power'].quantile(.99)
lower_lim = data['battery_power'].quantile(.01)
代码语言:javascript复制data.loc[(data['battery_power'] > upper_lim), 'battery_power'] = upper_lim
data.loc[(data['battery_power'] < lower_lim), 'battery_power'] = lower_lim
print(data)
以下是应遵守的输出。 如果您应滚动浏览输出,则可能会注意到一些更改的值:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b4AUjQ6c-1681568559576)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_11.png)]
图 11:帽异常行输出
单热编码
单热编码是机器学习中用于特征工程的一种常用技术。 一些机器学习算法无法处理分类特征,因此单热编码是一种将这些分类特征转换为数值特征的方法。 假设您有一个标记为“状态”的特征,该特征可以采用三个值(红色,绿色或黄色)之一。 由于这些值是分类的,因此不存在哪个值是较高或较低的概念。 我们可以将这些值转换为数值,从而赋予它们这种特性。 例如:
黄色= 1
红色= 2
绿色= 3
但这似乎有些武断。 如果我们知道红色是不好的,绿色是好的,而黄色在中间,那么我们可以将映射更改为:
红色= -1
黄色= 0
绿色= 1
这样可能会产生更好的表现。 但是,现在让我们看看如何对这个示例进行单热编码。 为了实现此一个变量的一次性编码,我们为每个值创建了一个新特征。 在这种情况下,我们的一些数据(您可能会在野外遇到的东西)可能看起来像这样:
红色 | 黄色 | 绿色 | 状态 |
---|---|---|---|
1 | 0 | 0 | 红色 |
0 | 1 | 0 | 黄色 |
0 | 0 | 1 | 绿色 |
0 | 0 | 1 | 绿色 |
由于我们已经对数据进行了单热编码,因此状态特征现在变得多余,因此我们可以从数据集中消除它:
红色 | 黄色 | 绿色 |
---|---|---|
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 1 |
0 | 0 | 1 |
此外,我们可以从其他两个颜色特征中计算出任何颜色特征的值。 如果红色和黄色都为 0,则意味着绿色需要为 1,依此类推。 因此,在单热编码中,我们始终可以删除其中一项特征而不会丢失信息。 像这样:
红色 | 黄色 |
---|---|
1 | 0 |
0 | 1 |
0 | 0 |
0 | 0 |
现在让我们看一个示例,说明如何使用get_dummies
函数使用 Pandas 库对特征进行单热编码:
import pandas as pd
代码语言:javascript复制data = pd.read_csv("dataset.csv")
代码语言:javascript复制encoded_columns = pd.get_dummies(data['color'])
data = data.join(encoded_columns).drop('color', axis=1)
print(data)
输出应如下所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-adRpDkMa-1681568559576)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_12.png)]
图 12:单热编码输出
对数转换
对数转换(或对数转换)是常见的特征工程转换。 对数转换有助于展开高度偏斜的值。 应用对数转换后,数据分布将被标准化。
让我们再看一个例子,再次获得一些直觉。 请记住,当您 10 岁时,看着 15 岁的男孩和女孩时,他们在想:“他们比我大得多!” 现在想想一个 50 岁的人和另一个 55 岁的人。 在这种情况下,您可能会认为年龄差异并不大。 在这两种情况下,年龄差异均为 5 岁。 但是,在第一种情况下,15 岁的年龄比 10 岁的年龄大 50%,在第二种情况下,55 岁的年龄比 50 岁的年龄大 10%。
如果我们对所有这些数据点应用对数变换,则将这样的幅度差异归一化。
由于幅值差异的归一化,使用对数变换的模型也将减少异常值的影响,并且使用对数变换的模型将变得更加健壮。
使用此技术时要考虑的一个关键限制是,仅当所有数据点均为正值时才应应用对数转换。 另外,您可以在应用转换之前将 1 加到数据中。 因此,您确保转换的输出为正:
log(x 1)
这是在 Python 中执行对数转换的方法:
代码语言:javascript复制#Log Transform Example
data = pd.DataFrame({'value':[3,67, -17, 44, 37, 3, 31, -38]})
data['log 1'] = (data['value'] 1).transform(np.log)
代码语言:javascript复制#Negative Values Handling
#Note that the values are different
data['log'] = (data['value']-data['value'].min() 1) .transform(np.log)
print(data)
这是应产生的输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b8G2W6zg-1681568559576)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_13.png)]
图 13:对数变换输出
缩放
在许多情况下,数据集中的数字特征在规模上会与其他特征有很大差异。 例如,房屋的典型平方英尺数可能是 1000 到 3000 平方英尺之间的数字,而房屋中卧室数量的 2、3 或 4 可能是更典型的数字。 如果我们不理会这些值,则如果不放下比例较高的特征,则可能会赋予较高的权重。 如何解决此问题?
缩放可以解决此问题。 应用缩放后,连续特征在范围上变得可比。 并非所有算法都需要标定值(随机森林浮现在脑海),但是如果未事先对数据集进行标定,则其他算法将产生无意义的结果(例如 K 近邻或 K 均值)。 现在,我们将探讨两种最常见的缩放方法。
归一化(或 minmax 归一化)将的所有值缩放到介于 0 到 1 之间的固定范围内。更正式的说,可以使用以下公式对特征的每个值进行归一化:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vD0iaeV8-1681568559576)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_002.png)]
哪里:
X
- 特征的任何给定值X_min
– 数据集中所有数据点的最小值X_max
– 数据集中所有数据点的最大值X_norm
– 应用公式后的归一化值
规范化不会更改特征的分布,并且由于减少的标准差,离群值的影响会增加。 因此,建议在规范化之前处理离群值。 现在,让我们看一个 Python 示例:
代码语言:javascript复制data = pd.DataFrame({'value':[7,25, -47, 73, 8, 22, 53, -25]})
代码语言:javascript复制data['normalized'] = (data['value'] - data['value'].min()) / (data['value'].max() - data['value'].min())
print(data)
期望看到以下输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HvLZKUSR-1681568559577)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_14.png)]
图 14:标准化输出
标准化(或 z 分数标准化)是一种缩放方法,其中包括标准差作为其计算的一部分。 标准化最小化并平滑了缩放中异常值的影响。 让我们看看如何计算它:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f6uLVL99-1681568559577)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_003.png)]
哪里:
μ =
平均值σ =
标准差x =
数据点
并使用 Python 计算:
代码语言:javascript复制data = pd.DataFrame({'value':[7,25, -47, 73, 8, 22, 53, -25]})
代码语言:javascript复制data['standardized'] = (data['value'] - data['value'].mean()) / data['value'].std()
print(data)
您应该在控制台中看到以下内容:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MVqUqZqe-1681568559577)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_04_15.png)]
图 15:标准化输出
日期操作
对于某些数据科学问题,时间特征可能至关重要。 在时间序列分析中,日期显然至关重要。 如果您没有在预测中附加日期,则预测 S&P 500 将达到 3,000 将毫无意义。
没有进行任何处理的日期可能对大多数模型没有多大意义,并且这些值将太独特而无法提供任何预测能力。 为什么 10/21/2019 与 10/19/2019 不同? 如果我们使用某些领域知识,则可能能够极大地增加特征的信息价值。 例如,将日期转换为分类变量可能会有所帮助。 如果目标函数是您试图确定何时支付租金,则将日期转换为二进制值,其中可能的值为:
- 该月的前 5 天
= 1
- 当月的前 5 天之后
= 0
如果要求您预测餐厅的人流和销售情况,那么看每个月的 21 日可能没有任何流量模式,但是可以想象,如果日期是星期日与星期二,或者月是 10 月与 12 月(例如圣诞节)。 如果这是一家国际连锁餐厅,那么餐厅位置和月份可能就非常重要(美国的圣诞节与印度的排灯节)。
可以操纵日期的其他可能方式包括:
- 将日期分为不同的部分:年,月,日等
- 以年,月,日等方式计算当前日期与所讨论的值之间的时间段
- 从日期中提取特定的特征:
- 星期几(星期一,星期二,依此类推)
- 周末与否
- 是否休假
还有许多其他可能性。 我们将其留给读者集思广益或研究其他方法。
总结
在本章中,我们分析了机器学习流程中的两个重要步骤:
- 特征选择
- 特征工程
如我们所见,这两个过程目前既是一门艺术,又是一门科学。 与确定要删除的特征以及要生成的特征添加到模型中相比,选择一个模型在管道中使用可能是一件容易的事。 本章并不是要对特征选择和特征工程进行全面的分析,而只是一个小尝试,希望它激发您进一步探索该主题的兴趣。
在下一章中,我们将开始深入研究机器学习。 我们将从监督学习模型开始构建机器学习模型。
5 使用监督学习的分类和回归
在本章中,我们将使用监督学习技术来学习数据的分类和回归。 在本章的最后,您将对这些主题有更好的理解:
- 监督学习与无监督学习之间的差异
- 分类方法
- 数据预处理方法
- 标签编码
- 逻辑回归分类器
- 朴素贝叶斯分类器
- 混淆矩阵
- 支持向量机和 SVM 分类器
- 线性和多项式回归
- 单变量和多变量线性回归
- 使用支持向量回归器估计房价
无监督学习的优势
从流行的新闻界看到并不难,当今人工智能领域最热门的领域之一就是机器学习。 机器学习通常分为有监督的学习和无监督的学习。 还存在其他分类,但我们将在后面讨论。
在给出更正式的定义之前,让我们对监督学习与无监督学习有一些直观的了解。 假设您有一组人物肖像。 这一组中的人是一个非常多样化的男人和女人,您具有各种国籍,年龄,体重等。 最初,您将数据集通过无监督学习算法进行处理。 在这种情况下,在没有任何先验知识的情况下,无监督算法将根据其识别为相似的某些特征开始对这些照片进行分类。 例如,它可能独自开始认识到男人和女人是不同的,并且可能开始将男人归为一组,将女人归为另一组。 但是不能保证它将找到该模式。 由于某些肖像具有深色背景而另一些肖像具有浅色背景,因此它可能使图像聚类,这可能是无用的推断。
现在拍摄同一组照片,但是这次我们在每张照片上都有一个标签。 假设标签是性别。 因为我们现在有了数据的标签,所以我们可以将数据通过监督算法处理,并使用输入变量(在这种情况下,输入变量是照片像素)来计算目标变量(在这种情况下,性别)。 更正式的:
监督学习是指指的是基于标记的训练数据构建机器学习模型的过程。 在监督学习中,每个示例或行都是一个由输入变量和所需目标变量组成的元组。 例如,机器学习中使用的常见数据集是“泰坦尼克号”数据集。 该数据集包含描述著名船只 RMS Titanic 的乘客的特征。 一些输入特征是:
- 旅客姓名
- 性别
- 客舱等级
- 年龄
- 登船地点
在这种情况下,目标变量将是乘客是否幸存。
无监督学习是指指的是不依赖标记的训练数据来构建机器学习模型的过程。 从某种意义上说,这与监督学习相反。 由于没有可用的标签,因此您仅需要根据提供给您的数据来提取见解。 通过无监督学习,我们正在训练一个系统,其中单独的数据点可能会分成多个群集或组。 需要重点强调的一点是,我们并不确切地知道分离的标准是什么。 因此,无监督学习算法需要以可能的最佳方式将给定的数据集分为几组。
现在,我们已经描述了机器学习方法的主要分类方法之一,让我们开始研究如何分类数据。
什么是分类?
在本节中,我们将讨论监督分类技术。 分类过程是一种用于将数据排列成固定数量的类别,以便可以有效地使用它的技术。
在机器学习中,分类用于标识新数据点所属的类别。 基于包含数据点和相应标签的训练数据集建立分类模型。 例如,假设我们要确定给定的图像是否包含一个人的脸。 我们将构建一个训练数据集,其中包含与两个类别相对应的类别:人脸和无人脸。 然后将基于可用的训练样本来训练模型。 然后可以将训练后的模型用于推理。
良好的分类系统使查找和检索数据变得容易。 分类广泛用于人脸识别,垃圾邮件识别,推荐引擎等。 好的数据分类算法将自动生成正确的标准,以将给定的数据分为给定数量的类别。
为了进行分类以产生不错的结果,将需要足够数量的样本,以便可以概括这些标准。 如果样本数量不足,该算法将过度适合训练数据。 这意味着它将无法很好地处理未知数据,因为它对模型进行了微调,无法适应训练数据中观察到的模式。 这实际上是机器学习领域中常见的问题。 在构建各种机器学习机器时,考虑这个因素是一个好主意。
预处理数据
原始数据是机器学习算法的推动力。 但是就像我们不能将原油放进汽车中,而是必须使用汽油一样,机器学习算法希望在训练过程开始之前就可以以某种方式格式化数据。 为了准备通过机器学习算法提取的数据,必须对数据进行预处理并将其转换为正确的格式。 让我们看一下实现这一目标的一些方法。
对于我们将要分析工作的示例,我们将需要导入一些 Python 包:
代码语言:javascript复制import numpy as np
from sklearn import preprocessing
另外,让我们定义一些样本数据:
代码语言:javascript复制input_data = np.array([[5.1, -2.9, 3.3],
[-1.2, 7.8, -6.1],
[3.9, 0.4, 2.1],
[7.3, -9.9, -4.5]])
这些是我们将要分析的预处理技术:
- 二值化
- 均值去除
- 缩放比例
- 规范化
二值化
二值化用于将数值转换为布尔值。 让我们使用一种内置方法,以2.1
作为阈值 ld 值,对进行二值化。
将以下行添加到同一 Python 文件中:
代码语言:javascript复制# Binarize data
data_binarized = preprocessing.Binarizer(threshold=2.1).transform(input_data)
print("nBinarized data:n", data_binarized)
如果运行代码,将看到以下输出:
代码语言:javascript复制Binarized data:
[[ 1. 0. 1.]
[ 0. 1. 0.]
[ 1. 0. 0.]
[ 1. 0. 0.]]
如我们在这里看到的,2.1
以上的所有值都变为1
。 剩余值变为0
。
去除均值
去除均值是机器学习中常用的预处理技术。 通常,从特征向量中删除平均值非常有用,这样每个特征都以零为中心。 我们这样做是为了消除特征向量中的特征偏差。
将以下行添加到与上一节相同的 Python 文件中:
代码语言:javascript复制# Print mean and standard deviation
print("nBEFORE:")
print("Mean =", input_data.mean(axis=0))
print("Std deviation =", input_data.std(axis=0))
前一行显示输入数据的平均值和标准差。 让我们去除均值:
代码语言:javascript复制# Remove mean
data_scaled = preprocessing.scale(input_data)
print("nAFTER:")
print("Mean =", data_scaled.mean(axis=0))
print("Std deviation =", data_scaled.std(axis=0))
如果运行代码,将看到以下输出:
代码语言:javascript复制BEFORE:
Mean = [ 3.775 -1.15 -1.3 ]
Std deviation = [ 3.12039661 6.36651396 4.0620192 ] AFTER:
Mean = [ 1.11022302e-16 0.00000000e 00 2.77555756e-17]
Std deviation = [ 1. 1. 1.]
从获得的值可以看出,平均值非常接近0
,标准差是1
。
缩放
正如在上一节中所做的一样,让我们通过访问一个示例来直观了解什么是缩放。 假设您有一个包含与房屋相关的特征的数据集,并且您正在尝试预测这些房屋的价格。 这些特征的数值范围可能会大不相同。 例如,房屋的平方英尺通常为数千,而房间数通常少于 10。此外,其中一些特征可能包含一些异常值。 例如,我们的数据集中可能有一些大厦使其他数据集倾斜。
我们需要找到一种缩放这些特征的方法,以使赋予每个特征的权重大致相同,而离群值的重要性也不会太大。 一种方法是重新调整所有特征,使它们落入较小的范围内,例如0
和1
。 MinMaxScaler 算法可能是实现此目的的最有效方法。 该算法的公式为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HIOMUwIT-1681568559577)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_05_001.png)]
其中max(x)
是变量的最大值,min(x)
是最小值,并且x[i]
分别是个体的值。
在我们的特征向量中,每个特征的值可以在许多随机值之间变化。 因此,对这些特征进行缩放以具有一个公平的竞争环境以训练机器学习算法就变得很重要。 仅仅由于测量的性质,任何特征都不能人为地变大或变小。
要在 Python 中实现它,请在文件中添加以下几行:
代码语言:javascript复制# Min max scaling
data_scaler_minmax = preprocessing.MinMaxScaler(feature_range=(0, 1))
data_scaled_minmax = data_scaler_minmax.fit_transform(input_data)
print("nMin max scaled data:n", data_scaled_minmax)
如果运行代码,将看到以下输出:
代码语言:javascript复制Min max scaled data:
[[ 0.74117647 0.39548023 1. ]
[ 0. 1. 0. ]
[ 0.6 0.5819209 0.87234043]
[ 1. 0. 0.17021277]]
缩放每一行,以使最大值为1
,而所有其他值相对 e 为该值。
标准化
民间通常会混淆缩放和规范化。 术语经常被混淆的原因之一是因为它们实际上非常相似。 在这两种情况下,您都在转换数据以使数据更有用。 但是,在缩放时,您正在更改变量值的范围,而通过归一化,您正在更改数据分布的形状。 为了使机器学习模型更好地工作,希望特征的值呈正态分布。
但是现实是混乱的,有时情况并非如此。 例如,值的分布可能会偏斜。 规范化通常会分配数据。 以下是规范化之前和之后的数据图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dvt3deaL-1681568559578)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_05_01.png)]
图 1:标准化前后
我们使用规范化过程来修改特征向量中的值,以便可以在一个通用尺度上对其进行测量。 在机器学习中,我们使用许多不同形式的规范化。 某些最常见的规范化形式旨在修改值,使它们的总和为 1。 确保每行的绝对值之和为1
。 L2 归一化是指最小二乘,它通过确保平方和为1
来工作。
通常,L1 归一化技术被认为比 L2 归一化技术更健壮。 L1 归一化技术很强大,因为它可以抵抗数据中的异常值。 很多时候,数据倾向于包含离群值,而我们对此无能为力。 我们希望使用可以在计算过程中安全有效地忽略它们的技术。 如果我们要解决离群值很重要的问题,那么 L2 规范化可能会成为更好的选择。
将以下行添加到同一 Python 文件中:
代码语言:javascript复制# Normalize data
data_normalized_l1 = preprocessing.normalize(input_data, norm='l1')
data_normalized_l2 = preprocessing.normalize(input_data, norm='l2')
print("nL1 normalized data:n", data_normalized_l1)
print("nL2 normalized data:n", data_normalized_l2)
如果运行代码,将看到以下输出:
代码语言:javascript复制L1 normalized data:
[[ 0.45132743 -0.25663717 0.2920354 ]
[-0.0794702 0.51655629 -0.40397351]
[ 0.609375 0.0625 0.328125 ]
[ 0.33640553 -0.4562212 -0.20737327]]
L2 normalized data:
[[ 0.75765788 -0.43082507 0.49024922]
[-0.12030718 0.78199664 -0.61156148]
[ 0.87690281 0.08993875 0.47217844]
[ 0.55734935 -0.75585734 -0.34357152]]
data_preprocessor.py
文件中提供了整个部分的代码。
标签编码
当执行分类时,我们通常会处理很多标签。 这些标签可以是文字,数字或其他形式。 许多机器学习算法需要数字作为输入。 因此,如果它们已经是数字,则可以直接用于训练。 但这并非总是如此。
标签通常是单词,因为单词可以被人类理解。 训练数据用单词标记,以便可以跟踪映射。 要将单词标签转换为数字,可以使用标签编码器。 标签编码是指将单词标签转换为数字的过程。 这使算法能够处理数据。 让我们看一个例子:
创建一个新的 Python 文件并导入以下包:
代码语言:javascript复制import numpy as np
from sklearn import preprocessing
定义一些样本标签:
代码语言:javascript复制# Sample input labels
input_labels = ['red', 'black', 'red', 'green', 'black', 'yellow', 'white']
创建标签编码器对象并对其进行训练:
代码语言:javascript复制# Create label encoder and fit the labels
encoder = preprocessing.LabelEncoder()
encoder.fit(input_labels)
打印单词和数字之间的映射:
代码语言:javascript复制# Print the mapping
print("nLabel mapping:")
for i, item in enumerate(encoder.classes_):
print(item, '-->', i)
让我们对一组随机排序的标签进行编码,以查看其表现:
代码语言:javascript复制# Encode a set of labels using the encoder
test_labels = ['green', 'red', 'black']
encoded_values = encoder.transform(test_labels)
print("nLabels =", test_labels)
print("Encoded values =", list(encoded_values))
让我们解码一组随机数字:
代码语言:javascript复制# Decode a set of values using the encoder
encoded_values = [3, 0, 4, 1]
decoded_list = encoder.inverse_transform(encoded_values)
print("nEncoded values =", encoded_values)
print("Decoded labels =", list(decoded_list))
如果运行代码,将看到以下输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g7IvoIU1-1681568559578)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_05_02.png)]
图 2:编码和解码输出
您可以检查映射以查看编码和解码步骤是否正确。 该部分的代码在 label_encoder.py
文件中给出。
逻辑回归分类器
逻辑回归是的一种技术,用于解释输入变量和输出变量之间的关系。 回归可用于对连续值进行预测,但是对于离散预测,例如结果为真或假或红色,绿色或黄色作为另一个示例。
假定输入变量是独立的,输出变量称为因变量。 因变量只能采用一组固定的值。 这些值对应于分类问题的类别。
我们的目标是通过使用逻辑函数估计概率来确定独立变量和因变量之间的关系。 在这种情况下,此逻辑函数将是 S 型曲线,该曲线用于使用各种参数构建函数。 在逻辑回归模型中使用 Sigmoid 函数的一些原因是:
- 它的范围是 0 到 1
- 它的导数更容易计算
- 将非线性引入模型的简单方法
它与广义线性模型分析密切相关,在广义线性模型分析中,我们尝试将一条线拟合到一堆点以最小化误差。 代替线性回归,我们使用逻辑回归。 逻辑回归本身不是分类技术,但是以这种方式使用来促进分类。 由于其简单性,它通常在机器学习中使用。 让我们看看如何使用逻辑回归构建分类器。 在继续操作之前,请确保已安装包。 如果不是,则可以在这里找到。
创建一个新的 Python 文件并导入以下包:
代码语言:javascript复制import numpy as np
from sklearn import linear_model
import matplotlib.pyplot as plt
from utilities import visualize_classifier
使用二维向量和相应的标签定义样本输入数据:
代码语言:javascript复制# Define sample input data
X = np.array([[3.1, 7.2], [4, 6.7], [2.9, 8], [5.1, 4.5], [6, 5], [5.6, 5], [3.3, 0.4], [3.9, 0.9], [2.8, 1], [0.5, 3.4], [1, 4], [0.6, 4.9]])
y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3])
我们将使用此标记数据训练分类器。 现在创建逻辑回归分类器对象:
代码语言:javascript复制# Create the logistic regression classifier
classifier = linear_model.LogisticRegression(solver='liblinear', C=1)
使用之前定义的数据训练分类器:
代码语言:javascript复制# Train the classifier
classifier.fit(X, y)
通过查看类的边界来可视化分类器的表现:
代码语言:javascript复制# Visualize the performance of the classifier
visualize_classifier(classifier, X, y)
必须先定义函数,然后才能使用它。 在本章中,我们将多次使用此函数,因此最好在一个单独的文件中对其进行定义并导入该函数。 此函数在提供的utilities.py
文件中提供。
创建一个新的 Python 文件并导入以下包:
代码语言:javascript复制import numpy as np
import matplotlib.pyplot as plt
通过将classifier
对象,输入数据和标签作为输入参数来创建函数定义:
def visualize_classifier(classifier, X, y):
# Define the minimum and maximum values for X and Y
# that will be used in the mesh grid
min_x, max_x = X[:, 0].min() - 1.0, X[:, 0].max() 1.0
min_y, max_y = X[:, 1].min() - 1.0, X[:, 1].max() 1.0
我们还定义了将在网格网格中使用的X
和Y
方向的最小值和最大值。 该网格基本上是用于求值函数的一组值,以便我们可以可视化类的边界。 定义网格的步长并使用最小值和最大值创建它:
# Define the step size to use in plotting the mesh grid mesh_step_size = 0.01
# Define the mesh grid of X and Y values
x_vals, y_vals = np.meshgrid(np.arange(min_x, max_x, mesh_step_size), np.arange(min_y, max_y, mesh_step_size))
在网格上的所有点上运行分类器:
代码语言:javascript复制 # Run the classifier on the mesh grid
output = classifier.predict(np.c_[x_vals.ravel(), y_vals.ravel()])
# Reshape the output array
output = output.reshape(x_vals.shape)
创建图形,选择配色方案,然后覆盖所有点:
代码语言:javascript复制 # Create a plot
plt.figure()
代码语言:javascript复制 # Choose a color scheme for the plot
plt.pcolormesh(x_vals, y_vals, output, cmap=plt.cm.gray)
# Overlay the training points on the plot
plt.scatter(X[:, 0], X[:, 1], c=y, s=75, edgecolors='black', linewidth=1, cmap=plt.cm.Paired)
使用最小值和最大值指定图的边界,添加复选标记,并显示图形:
代码语言:javascript复制 # Specify the boundaries of the plot
plt.xlim(x_vals.min(), x_vals.max())
plt.ylim(y_vals.min(), y_vals.max())
代码语言:javascript复制 # Specify the ticks on the X and Y axes
plt.xticks((np.arange(int(X[:, 0].min() - 1), int(X[:, 0].max() 1), 1.0)))
plt.yticks((np.arange(int(X[:, 1].min() - 1), int(X[:, 1].max() 1), 1.0)))
plt.show()
如果代码已运行,您将看到以下屏幕截图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-en1etC6o-1681568559578)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_05_03.png)]
图 3:设置图的边界后显示的图
如果在下面的行中将C
的值更改为100
,您将看到边界变得更加准确:
classifier = linear_model.LogisticRegression(solver='liblinear', C=100)
原因是C
对分类错误施加了一定的惩罚,因此该算法针对训练数据进行了更多定制。 您应该谨慎使用此参数,因为如果将其大量增加,它将过度适合训练数据,并且不能很好地泛化。
如果在将C
设置为100
的情况下运行代码,则会看到以下屏幕截图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ka17SVvV-1681568559578)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_05_04.png)]
图 4:在将 C 设置为 100 的情况下运行代码时的结果
如果与之前的数字进行比较,您会发现边界现在更好了。 该部分的代码在logistic_regression.py
文件中给出。
朴素贝叶斯分类器
朴素贝叶斯是一种用于使用贝叶斯定理建立分类器的技术。 贝叶斯定理描述了基于与该事件相关的不同条件发生事件的概率。 通过为问题实例分配类标签,我们构建了朴素的贝叶斯分类器。 这些问题实例被表示为特征值的向量。 这里的假设是任何给定特征的值都独立于任何其他特征的值。 这称为独立性假设,它是朴素贝叶斯分类器的朴素部分。
给定类别变量,我们可以仅查看给定特征如何影响它,而不管其对其他特征的影响。 例如,如果发现动物,有四条腿,有一条尾巴并且以大约 70 MPH 的速度奔跑,则可以将其视为猎豹。 朴素的贝叶斯分类器认为这些特征中的每一个都对结果有独立的贡献。 结果是指该动物是猎豹的可能性。 我们并不关心皮肤图案,腿数,尾巴的存在和运动速度之间可能存在的相关性。 让我们看看如何构建朴素贝叶斯分类器。
创建一个新的 Python 文件并导入以下包:
代码语言:javascript复制import numpy as np
import matplotlib.pyplot as plt
from sklearn.naive_bayes import GaussianNB
from sklearn import.model_selection import train_test_split
from sklearn.model_selection import .model_selection import train_test_split
from sklearn.model_selection import cross_val_score
代码语言:javascript复制from utilities import visualize_classifier
我们将使用文件data_multivar_nb.txt
作为源数据。 此文件在每行中包含逗号分隔的值:
# Input file containing data
input_file = 'data_multivar_nb.txt'
让我们从该文件加载数据:
代码语言:javascript复制# Load data from input file
data = np.loadtxt(input_file, delimiter=',')
X, y = data[:, :-1], data[:, -1]
创建朴素贝叶斯分类器的实例。 我们将在这里使用高斯朴素贝叶斯分类器。 在这种类型的分类器中,我们假设与每个类关联的值都遵循高斯分布:
代码语言:javascript复制# Create Naïve Bayes classifier
classifier = GaussianNB()
使用训练数据训练分类器:
代码语言:javascript复制# Train the classifier
classifier.fit(X, y)
对训练数据运行分类器并预测输出:
代码语言:javascript复制# Predict the values for training data
y_pred = classifier.predict(X)
让我们通过将预测值与真实标签进行比较来计算分类器的准确率,然后可视化表现:
代码语言:javascript复制# Compute accuracy
accuracy = 100.0 * (y == y_pred).sum() / X.shape[0]
print("Accuracy of Naïve Bayes classifier =", round(accuracy, 2), "%")
代码语言:javascript复制# Visualize the performance of the classifier
visualize_classifier(classifier, X, y)
先前用于的计算分类器准确率的方法并不可靠。 我们需要执行交叉验证,以便在测试数据时不会使用相同的训练数据。
将数据分为训练和测试子集。 如以下行中的test_size
参数所指定,我们将分配 80% 用于训练,其余 20% 用于测试。 然后,我们将在此数据上训练朴素贝叶斯分类器:
# Split data into training and test data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=3)
classifier_new = GaussianNB()
classifier_new.fit(X_train, y_train)
y_test_pred = classifier_new.predict(X_test)
计算分类器的准确率并可视化表现:
代码语言:javascript复制# compute accuracy of the classifier
accuracy = 100.0 * (y_test == y_test_pred).sum() / X_test.shape[0]
print("Accuracy of the new classifier =", round(accuracy, 2), "%")
代码语言:javascript复制# Visualize the performance of the classifier
visualize_classifier(classifier_new, X_test, y_test)
让我们使用内置函数基于三重交叉验证来计算准确率,精确度和召回值:
代码语言:javascript复制num_folds = 3
accuracy_values = cross_val_score(classifier,
X, y, scoring='accuracy', cv=num_folds)
print("Accuracy: " str(round(100*accuracy_values.mean(), 2)) "%")
代码语言:javascript复制precision_values = cross_val_score(classifier,
X, y, scoring='precision_weighted', cv=num_folds)
print("Precision: " str(round(100*precision_values.mean(), 2)) "%")
代码语言:javascript复制recall_values = cross_val_score(classifier,
X, y, scoring='recall_weighted', cv=num_folds)
print("Recall: " str(round(100*recall_values.mean(), 2)) "%")
代码语言:javascript复制f1_values = cross_val_score(classifier,
X, y, scoring='f1_weighted', cv=num_folds)
print("F1: " str(round(100*f1_values.mean(), 2)) "%")
如果运行代码,则第一次训练将显示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oINgvRpk-1681568559579)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_05_05.png)]
图 5:第一次训练后的聚类和边界
前面的屏幕快照显示了从分类器获得的边界。 我们可以看到它们很好地分隔了四个聚类,并根据输入数据点的分布创建了具有边界的区域。 您将在下面的屏幕截图中看到带有交叉验证的第二次训练:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yrlhs8jF-1681568559579)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_05_06.png)]
图 6:使用交叉验证的第二次训练结果
您将和以下打印输出:
代码语言:javascript复制Accuracy of Naïve Bayes classifier = 99.75 %
Accuracy of the new classifier = 100.0 %
Accuracy: 99.75%
Precision: 99.76%
Recall: 99.75%
F1: 99.75%
该部分的代码在文件naive_bayes.py
中给出。
混淆矩阵
混淆矩阵是图形或用于描述分类器表现的表格。 矩阵中的每一行代表预测类中的实例,而每一列代表实际类中的实例。 之所以使用此名称,是因为如果模型混淆或错误标记了两个类别,则矩阵使可视化变得容易。 我们将每个类别与其他每个类别进行比较,看看有多少样本被正确分类或分类错误。
在构建此表的过程中,我们遇到了一些关键指标,这些指标在机器学习领域很重要。 让我们考虑一个二分类的情况,其中输出为0
或1
:
- 真阳性:这些是我们预测
1
作为输出的样本,而真实情况也是1
。 - 真阴性:这些是我们为其预测了
0
作为输出的样本,并且真实情况也是0
。 - 假阳性:这些是我们预测将其作为输出的
1
但实际情况为0
的样本。 这也称为 I 型错误。 - 假阴性:这些是我们预测其输出为
0
但实际情况为1
的样本。 这也称为 II 型错误。
根据当前的问题,我们可能必须优化算法以减少误报率或误报率。 例如,在生物识别系统中,避免误报非常重要,因为错误的人可能会访问敏感信息。 让我们看看如何创建一个混淆矩阵。
创建一个新的 Python 文件并导入以下包:
代码语言:javascript复制import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
为真实情况和预测的输出提供了一些定义的样本标签:
代码语言:javascript复制# Define sample labels
true_labels = [2, 0, 0, 2, 4, 4, 1, 0, 3, 3, 3]
pred_labels = [2, 1, 0, 2, 4, 3, 1, 0, 1, 3, 3]
使用我们刚刚定义的标签创建混淆矩阵:
代码语言:javascript复制# Create confusion matrix
confusion_mat = confusion_matrix(true_labels, pred_labels)
可视化混淆矩阵:
代码语言:javascript复制# Visualize confusion matrix
plt.imshow(confusion_mat, interpolation='nearest', cmap=plt.cm.gray)
plt.title('Confusion matrix')
plt.colorbar()
ticks = np.arange(5)
plt.xticks(ticks, ticks)
plt.yticks(ticks, ticks)
plt.ylabel('True labels')
plt.xlabel('Predicted labels')
plt.show()
在前面的可视化代码中,ticks
变量引用不同类的数量。 在我们的案例中,我们有五个不同的标签。
让我们打印分类报告:
代码语言:javascript复制# Classification report
targets = ['Class-0', 'Class-1', 'Class-2', 'Class-3', 'Class-4'] print('n', classification_report(true_labels, pred_labels, target_names=targets))
分类报告打印每个类别的表现。 如果运行代码,您将看到以下屏幕截图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BUkFcMwo-1681568559579)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_05_07.png)]
图 7:分类报告中每个类别的表现
白色表示较高的值,而黑色表示较低的值,如在图像右侧的颜色图键上所示。 在理想情况下,对角正方形将全为白色,其他所有区域均为黑色。 这表示 100% 的准确率。
输出应为如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pHM64ly5-1681568559579)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_05_08.png)]
图 8:分类报告中的值
可以看出,平均precision
为 85%,平均recall
为 73%。 而f1-score
为 75%。 根据我们正在使用的域,这些结果可能是好结果,也可能是不好的结果。 如果所讨论的领域是试图确定患者是否患有癌症,而我们的准确率只能达到 85%,那么将有 15% 的人口被错误分类,并且会非常不满意。 如果我们正在分析的领域是某人是否打算购买产品并且我们的精度结果相同,则可以认为这是本垒打,可以大大减少我们的营销费用。
该部分的代码在文件confusion_matrix.py
中给出。
支持向量机
支持向量机(SVM)是分类器,使用类别之间的分隔超平面进行定义。 此超平面是直线的 N 维版本。 给定带标签的训练数据和二分类问题,SVM 会找到将训练数据分为两类的最佳超平面。 这很容易扩展到N
类的问题。
让我们考虑具有两类点的二维情况。 考虑到它是 2D,我们只必须处理 2D 平面上的点和线。 这比在高维空间中的向量和超平面更容易可视化。 当然,这是 SVM 问题的简化版本,但是在将其应用于高维数据之前,了解它并对其进行可视化非常重要。
考虑下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FYbdTcTY-1681568559579)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_05_09.png)]
图 9:用超平面分离两个类
点分为两类,我们想找到最佳的超平面来将这两个类分开。 但是我们如何定义最优? 在此图片中,实线代表最佳超平面。 您可以绘制许多不同的线以将两类点分开,但这条线是最好的分隔符,因为它可以使每个点到分隔线的距离最大化。 虚线上的点称为支持向量。 两条虚线之间的垂直距离称为最大边距。 您可以将最大边距视为可以为给定数据集绘制的最粗边框。
使用支持向量机将收入数据分类
我们将构建一个支持向量机分类器,根据 14 个属性预测给定人员的收入等级。 我们的目标是查看年收入是高于还是低于 50,000 美元。 因此,这是一个二分类问题。 我们将使用这个页面上提供的普查收入数据集。 此数据集中需要注意的一项是,每个数据点都是单词和数字的混合体。 我们不能使用原始格式的数据,因为算法不知道如何处理单词。 我们无法使用标签编码器来转换所有内容,因为数字数据很有价值。 因此,我们需要结合使用标签编码器和原始数值数据来构建有效的分类器。
创建一个新的 Python 文件并导入以下包:
代码语言:javascript复制import numpy as np
import matplotlib.pyplot as plt from sklearn import preprocessing from sklearn.svm
import LinearSVC
from sklearn.multiclass import OneVsOneClassifier
from sklearn import cross_validation
我们将使用文件income_data.txt
加载数据。 此文件包含收入详细信息:
# Input file containing
data input_file = 'income_data.txt'
为了从文件中加载数据,我们需要对其进行预处理以准备进行分类。 每个类别最多使用 25,000 个数据点:
代码语言:javascript复制# Read the data X = []
y = []
count_class1 = 0
count_class2 = 0
max_datapoints = 25000
打开文件并开始阅读以下行:
代码语言:javascript复制with open(input_file, 'r') as f:
for line in f.readlines():
if count_class1 >= max_datapoints and count_class2 >= max_datapoints:
break
if '?' in line:
continue
每行都用逗号分隔,因此我们需要对其进行相应的拆分。 每行的最后一个元素代表标签。 根据该标签,我们将其分配给一个类:
代码语言:javascript复制 data = line[:-1].split(', ')
if data[-1] == '<=50K' and count_class1 < max_datapoints:
X.append(data)
count_class1 = 1
if data[-1] == '>50K' and count_class2 < max_datapoints:
X.append(data)
count_class2 = 1
将列表转换为numpy
数组,以便可以将其用作sklearn
函数的输入:
# Convert to numpy array
X = np.array(X)
如果任何属性是字符串,则需要对其进行编码。 如果是数字,则可以原样保留。 请注意,我们最终将使用多个标签编码器,并且需要跟踪所有这些标签编码器:
代码语言:javascript复制# Convert string data to numerical data
label_encoder = []
X_encoded = np.empty(X.shape)
for i,item in enumerate(X[0]):
if item.isdigit():
X_encoded[:, i] = X[:, i]
else:
label_encoder.append(preprocessing.LabelEncoder())
X_encoded[:, i] = label_encoder[-1].fit_transform(X[:, i])
X = X_encoded[:, :-1].astype(int)
y = X_encoded[:, -1].astype(int)
使用线性核创建SVM
分类器:
# Create SVM classifier
classifier = OneVsOneClassifier(LinearSVC(random_state=0))
训练分类器:
代码语言:javascript复制# Train the classifier
classifier.fit(X, y)
使用 80/20 分割进行交叉验证以进行训练和测试,然后预测训练数据的输出:
代码语言:javascript复制# Cross validation
X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y, test_size=0.2, random_state=5)
classifier = OneVsOneClassifier(LinearSVC(random_state=0)) classifier.fit(X_train, y_train)
y_test_pred = classifier.predict(X_test)
计算分类器的 F1 得分:
代码语言:javascript复制# Compute the F1 score of the SVM classifier
f1 = cross_validation.cross_val_score(classifier, X, y, scoring='f1_weighted', cv=3)
print("F1 score: " str(round(100*f1.mean(), 2)) "%")
现在分类器已经准备就绪,让我们看看如何获取随机输入数据点并预测输出。 让我们定义一个这样的数据点:
代码语言:javascript复制# Predict output for a test datapoint
input_data = ['37', 'Private', '215646', 'HS-grad', '9', 'Never-married', 'Handlers-cleaners', 'Not-in-family', 'White', 'Male', '0', '0', '40', 'United-States']
在执行预测之前,需要使用之前创建的标签编码器对数据点进行编码:
代码语言:javascript复制# Encode test datapoint
input_data_encoded = [-1] * len(input_data)
count = 0
for i, item in enumerate(input_data):
if item.isdigit():
input_data_encoded[i] = int(input_data[i])
else:
input_data_encoded[i] = int(label_encoder[count].transform(input_data[i]))
count = 1
代码语言:javascript复制input_data_encoded = np.array(input_data_encoded)
现在我们准备使用分类器预测输出:
代码语言:javascript复制# Run classifier on encoded datapoint and print output
predicted_class = classifier.predict(input_data_encoded)
print(label_encoder[-1].inverse_transform(predicted_class)[0])
如果运行代码,则将花费几秒钟来训练分类器。 完成后,您将看到以下输出:
代码语言:javascript复制F1 score: 66.82%
您还将看到测试数据点的输出:
代码语言:javascript复制<=50K
如果检查该数据点中的值,您将看到它与小于 50K 类中的数据点紧密对应。 您可以通过使用不同的内核并尝试参数的多种组合来更改分类器的表现(F1 得分,准确率或查全率)。
该部分的代码在文件income_classifier.py
中给出。
什么是回归?
回归是估计输入和输出变量之间关系的过程。 需要注意的一项是输出变量是连续值实数。 因此,存在无限的可能性。 这与分类相反,在分类中,输出类别的数量是固定的。 这些类属于一组有限的可能性。
在回归中,假设输出变量取决于输入变量,因此我们想看看它们是如何关联的。 因此,输入变量称为独立变量,也称为,称为预测变量,输出变量称为,称为因变量,也称为标准变量。 不需要输入变量彼此独立; 实际上,在许多情况下,输入变量之间存在相关性。
回归分析有助于我们理解当我们更改某些输入变量而其他输入变量保持固定时输出变量的值如何变化。 在线性回归中,我们假设输入和输出之间的关系是线性的。 这给我们的建模过程带来了限制,但是它是快速高效的。
有时,线性回归不足以解释输入和输出之间的关系。 因此,我们使用多项式回归,其中我们使用多项式来解释输入和输出之间的关系。 这在计算上更加复杂,但提供了更高的精度。 根据当前的问题,我们使用不同形式的回归来提取关系。 回归通常用于预测价格,经济型麦克风,价格变动等等。
建立单变量回归器
让我们看看如何构建单个变量回归模型。 创建一个新的 Python 文件并导入以下包:
代码语言:javascript复制import pickle
代码语言:javascript复制import numpy as np
from sklearn import linear_model
import sklearn.metrics as sm
import matplotlib.pyplot as plt
我们将使用提供给您的文件data_singlevar_regr.txt
。 这是我们的数据源:
# Input file containing data
input_file = 'data_singlevar_regr.txt'
这是一个逗号分隔的文件,因此我们可以使用单行函数调用轻松加载它:
代码语言:javascript复制# Read data
data = np.loadtxt(input_file, delimiter=',')
X, y = data[:, :-1], data[:, -1]
将其分为训练和测试:
代码语言:javascript复制# Train and test split
num_training = int(0.8 * len(X))
num_test = len(X) - num_training
代码语言:javascript复制# Training data
X_train, y_train = X[:num_training], y[:num_training]
代码语言:javascript复制# Test data
X_test, y_test = X[num_training:], y[num_training:]
创建一个线性回归对象并使用训练数据对其进行训练:
代码语言:javascript复制# Create linear regressor object
regressor = linear_model.LinearRegression()
代码语言:javascript复制# Train the model using the training sets
regressor.fit(X_train, y_train)
使用训练模型预测测试数据集的输出:
代码语言:javascript复制# Predict the output
y_test_pred = regressor.predict(X_test)
绘制输出:
代码语言:javascript复制# Plot outputs
plt.scatter(X_test, y_test, color='green')
plt.plot(X_test, y_test_pred, color='black', linewidth=4)
plt.xticks(())
plt.yticks(())
plt.show()
通过将参考实际输出的基本事实与预测输出进行比较,计算回归器的表现指标:
代码语言:javascript复制# Compute performance metrics
print("Linear regressor performance:")
print("Mean absolute error =", round(sm.mean_absolute_error(y_test, y_test_pred), 2))
print("Mean squared error =", round(sm.mean_squared_error(y_test, y_test_pred), 2))
print("Median absolute error =", round(sm.median_absolute_error(y_test, y_test_pred), 2))
print("Explain variance score =", round(sm.explained_variance_score(y_test, y_test_pred), 2))
print("R2 score =", round(sm.r2_score(y_test, y_test_pred), 2))
创建模型后,我们可以将其保存到文件中,以便以后使用。 Python 提供了一个名为pickle
的不错的模块,使我们能够执行此操作:
# Model persistence
output_model_file = 'model.pkl'
代码语言:javascript复制# Save the model
with open(output_model_file, 'wb') as f:
pickle.dump(regressor, f)
让我们从磁盘上的文件加载模型并执行预测:
代码语言:javascript复制# Load the model
with open(output_model_file, 'rb') as f:
regressor_model = pickle.load(f)
代码语言:javascript复制# Perform prediction on test data
y_test_pred_new = regressor_model.predict(X_test)
print("nNew mean absolute error =", round(sm.mean_absolute_error(y_test, y_test_pred_new), 2))
如果运行代码,将会看到以下屏幕:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nM2iyS9u-1681568559580)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_05_10.png)]
图 10:执行预测后的输出
您应该看到以下输出:
代码语言:javascript复制Linear regressor performance:
Mean absolute error = 0.59
Mean squared error = 0.49
Median absolute error = 0.51
Explain variance score = 0.86
R2 score = 0.86
New mean absolute error = 0.59
平均绝对误差(MAE)是绝对误差的平均值:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z7T2Uuzn-1681568559580)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/ai-py/img/B15441_05_002.png)]
其中y
i 是预测值,x
i 是实际值。
均方误差(MSE)是误差平方的平均值,即,预测值和实际值之间的均方差。 由于随机性,MSE 几乎总是严格为正(而不是零)。 MSE 是评估器质量的度量。 它始终是非负值,并且值越接近零越好。
解释的差异衡量模型占数据集中差异的比例。 通常,将变异量化为方差; 还可以使用更具体的术语解释方差。 总变化的其余部分是无法解释的或剩余的变化。
确定系数或 R2 分数用于分析如何通过第二个变量的差异解释一个变量的差异。 例如,如果一个女人怀孕了,那与她们生孩子的相关性很高。
该部分的代码在文件regressor_singlevar.py
中给出。
建立多元回归
在的上一部分中,我们讨论了如何为单个变量构建回归模型。 在本节中,我们将处理多维数据。 创建一个新的 Python 文件并导入以下包:
代码语言:javascript复制import numpy as np
from sklearn import linear_model
import sklearn.metrics as sm
from sklearn.preprocessing import PolynomialFeatures
我们将使用提供给您的文件data_multivar_regr.txt
。
# Input file containing data
input_file = 'data_multivar_regr.txt'
这是一个逗号分隔的文件,因此我们可以通过单行函数调用轻松加载它:
代码语言:javascript复制# Load the data from the input file
data = np.loadtxt(input_file, delimiter=',')
X, y = data[:, :-1], data[:, -1]
将数据分为训练和测试:
代码语言:javascript复制# Split data into training and testing
num_training = int(0.8 * len(X))
num_test = len(X) - num_training
代码语言:javascript复制# Training data
X_train, y_train = X[:num_training], y[:num_training]
代码语言:javascript复制# Test data
X_test, y_test = X[num_training:], y[num_training:]
创建并训练线性回归模型:
代码语言:javascript复制# Create the linear regressor model
linear_regressor = linear_model.LinearRegression()
代码语言:javascript复制# Train the model using the training sets
linear_regressor.fit(X_train, y_train)#
预测测试数据集的输出:
代码语言:javascript复制# Predict the output
y_test_pred = linear_regressor.predict(X_test)
打印表现指标:
代码语言:javascript复制# Measure performance
print("Linear Regressor performance:")
print("Mean absolute error =", round(sm.mean_absolute_error(y_test, y_test_pred), 2))
print("Mean squared error =", round(sm.mean_squared_error(y_test, y_test_pred), 2))
print("Median absolute error =", round(sm.median_absolute_error(y_test, y_test_pred), 2))
print("Explained variance score =", round(sm.explained_variance_score(y_test, y_test_pred), 2))
print("R2 score =", round(sm.r2_score(y_test, y_test_pred), 2))
创建度数为 10 的多项式回归器。在训练数据集上训练回归器。 让我们以一个样本数据点为例,看看如何执行预测。 第一步是将其转换为多项式:
代码语言:javascript复制# Polynomial regression
polynomial = PolynomialFeatures(degree=10)
X_train_transformed = polynomial.fit_transform(X_train)
datapoint = [[7.75, 6.35, 5.56]]
poly_datapoint = polynomial.fit_transform(datapoint)
如果仔细观察,该数据点非常接近我们数据文件中第 11 行的数据点,即[7.66, 6.29, 5.66]
。 因此,一个好的回归器应该预测接近41.35
的输出。 创建一个线性回归对象并执行多项式拟合。 使用线性和多项式回归器执行预测以查看差异:
poly_linear_model = linear_model.LinearRegression()
poly_linear_model.fit(X_train_transformed, y_train)
print("nLinear regression:n", linear_regressor.predict(datapoint))
print("nPolynomial regression:n", poly_linear_model.predict(poly_datapoint))
如果运行代码,则输出应如下所示:
代码语言:javascript复制Linear Regressor performance:
Mean absolute error = 3.58
Mean squared error = 20.31
Median absolute error = 2.99
Explained variance score = 0.86
R2 score = 0.86
您还将看到以下:
代码语言:javascript复制Linear regression:
[ 36.05286276]
Polynomial regression:
[ 41.46961676]
如您所见,线性回归为36.05
; 多项式回归系数接近 41.35,因此多项式回归模型能够做出更好的预测。
该部分的代码在文件regressor_multivar.py
中给出。
使用支持向量回归器估计房价
让我们看看如何使用 SVM 概念构建回归变量来估计房价。 我们将使用sklearn
中可用的数据集,其中每个数据点由 13 个属性定义。
我们的目标是根据这些属性估计住房价格。 创建一个新的 Python 文件并导入以下包:
代码语言:javascript复制import numpy as np
from sklearn import datasets
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error, explained_variance_score
from sklearn.utils import shuffle
加载住房数据集:
代码语言:javascript复制# Load housing data
data = datasets.load_boston()
让我们对数据进行混洗,以免产生偏差:
代码语言:javascript复制# Shuffle the data
X, y = shuffle(data.data, data.target, random_state=7)
将数据集以 80/20 格式分为训练和测试:
代码语言:javascript复制# Split the data into training and testing datasets
num_training = int(0.8 * len(X))
X_train, y_train = X[:num_training], y[:num_training]
X_test, y_test = X[num_training:], y[num_training:]
使用线性核创建并训练支持向量回归器。 C
参数代表训练误差的代价。 如果增加C
的值,则模型将对其进行微调以适合训练数据。 但这可能会导致过拟合并使其失去通用性。 epsilon
参数指定阈值; 如果预测值在与实际值的距离之内,则不会对训练误差造成任何损失:
# Create Support Vector Regression model
sv_regressor = SVR(kernel='linear', C=1.0, epsilon=0.1)
代码语言:javascript复制# Train Support Vector Regressor
sv_regressor.fit(X_train, y_train)
评估回归器的表现并打印指标:
代码语言:javascript复制# Evaluate performance of Support Vector Regressor
y_test_pred = sv_regressor.predict(X_test)
mse = mean_squared_error(y_test, y_test_pred)
evs = explained_variance_score(y_test, y_test_pred)
print("n#### Performance ####")
print("Mean squared error =", round(mse, 2))
print("Explained variance score =", round(evs, 2))
让我们以测试数据点进行预测:
代码语言:javascript复制# Test the regressor on test datapoint
test_data = [3.7, 0, 18.4, 1, 0.87, 5.95, 91, 2.5052, 26, 666, 20.2,
351.34, 15.27]
print("nPredicted price:", sv_regressor.predict([test_data])[0])
如果运行代码,则应看到以下输出:
代码语言:javascript复制#### Performance ####
Mean squared error = 15.41
Explained variance score = 0.82
Predicted price: 18.5217801073
该部分的代码在文件house_prices.py
中给出。 查看文件的第一行,查看18.52
的预测与实际目标变量的接近程度。
总结
在本章中,我们了解了监督学习和无监督学习之间的区别。 我们讨论了数据分类问题以及如何解决它。 我们了解了如何使用各种方法预处理数据。 我们还学习了标签编码以及如何构建标签编码器。 我们讨论了逻辑回归并构建了逻辑回归分类器。 我们了解了朴素的贝叶斯分类器是什么,并学习了如何建立分类器。 我们还学习了如何构建混淆矩阵。
我们讨论了支持向量机,并了解了如何基于该向量构建分类器。 我们了解了回归,并了解了如何对单变量和多变量数据使用线性和多项式回归。 然后,我们使用支持向量回归器通过输入属性来估计房屋价格。
在下一章中,我们将学习预测分析以及如何使用集成学习构建预测引擎。