金融机器学习与数据科学蓝图(一)
原文:
annas-archive.org/md5/d5f4b91728e84d1cbeabc13a1198818d译者:飞龙
序言
机器学习(ML)在金融领域的价值每天都在变得更加明显。机器学习预计将对金融市场的运作变得至关重要。分析师、投资组合经理、交易员和首席投资官都应该熟悉 ML 技术。对于试图改善金融分析、简化流程和增强安全性的银行和其他金融机构来说,ML 正在成为首选技术。ML 在机构中的使用是一个增长趋势,其在交易策略、定价和风险管理方面提升系统潜力的潜力也在不断增加。
尽管机器学习在金融服务行业的所有垂直领域都在取得重大进展,但在机器学习算法的想法和实施之间存在差距。在这些领域网上提供了大量的资料,但很少有组织的资料。此外,大多数文献仅限于交易算法。金融机器学习和数据科学蓝图填补了这一空白,为金融市场量身定制了一个机器学习工具箱,让读者成为机器学习革命的一部分。本书不仅限于投资或交易策略;它侧重于利用构建在金融业务中至关重要的 ML 驱动算法的艺术和技术。
在金融领域实施机器学习模型比普遍认为的要容易。还有一个误解是建立机器学习模型需要大数据。本书中的案例研究涵盖了几乎所有机器学习领域,并旨在解决这些误解。本书不仅涵盖了在交易策略中使用 ML 相关的理论和案例研究,还深入探讨了其他重要的“必须了解”概念,如投资组合管理、衍生品定价、欺诈检测、企业信用评级、机器人顾问开发和聊天机器人开发。它将解决从业者面临的现实问题,并提供科学支持的代码和示例。
本书在 GitHub 上的Python 代码库将对行业从业者在他们的项目上起到有用的作用,并作为一个起点。本书中展示的示例和案例研究展示了可以轻松应用于各种数据集的技术。未来主义的案例研究,如交易的强化学习、建立机器人顾问和使用机器学习进行工具定价,激励读者超越传统思维,并激励他们充分利用现有的模型和数据。
本书适合谁
本书的格式和涵盖主题的列表适合从事对冲基金、投资和零售银行以及金融科技公司工作的专业人士。他们可能担任数据科学家、数据工程师、量化研究员、机器学习架构师或软件工程师等职务。此外,本书对从事支持职能的专业人士如合规和风险方面的工作也非常有用。
无论是量化对冲基金交易员寻找有关使用强化学习进行加密货币交易的想法,还是投资银行量化分析师寻找改进定价模型校准速度的机器学习技术,本书都将为其增加价值。本书中提到的理论、概念和代码库将在模型开发生命周期的每个阶段都非常有用,从构思到模型实施。读者可以使用共享的代码库并自行测试提议的解决方案,实现亲身实践的阅读体验。读者应具备统计学、机器学习和 Python 的基本知识。
本书的组织方式
本书全面介绍了如何利用机器学习和数据科学设计金融领域不同领域的模型。本书分为四个部分组织。
第 I 部分:框架
第一部分概述了金融中的机器学习及其实施的基本构建块。这些章节为本书后续介绍的不同类型机器学习的案例研究奠定了基础。
第一部分的章节如下:
第一章,金融中的机器学习:概览
本章概述了机器学习在金融中的应用,并简要介绍了几种机器学习的类型。
第二章,Python 中开发机器学习模型
本章探讨了基于 Python 的机器学习生态系统。还涵盖了 Python 框架中进行机器学习模型开发的步骤。
第三章,人工神经网络
鉴于人工神经网络(ANN)是所有类型机器学习中使用的主要算法,本章详细讨论了 ANN 的细节,随后使用 Python 库详细实现了一个 ANN 模型。
第 II 部分:监督学习
第二部分涵盖了基本的监督学习算法,并展示了具体的应用和案例研究。
第二部分的章节如下:
第四章,监督学习:模型与概念
本章介绍了监督学习技术(包括分类和回归)。鉴于许多模型在分类和回归之间是共通的,本章将详细介绍这些模型,同时还涵盖了模型选择、分类和回归的评估指标等概念。
第五章,监督学习:回归(包括时间序列模型)
基于监督学习的回归模型是金融领域中最常用的机器学习模型。本章涵盖了从基本线性回归到高级深度学习的模型。本节的案例研究包括股票价格预测、衍生品定价和投资组合管理模型。
第六章,监督学习:分类
分类是监督学习的一个子类别,其目标是基于过去的观察预测新实例的分类类标签。本节讨论了基于分类技术的几个案例研究,如逻辑回归、支持向量机和随机森林等。
第三部分:无监督学习
第三部分涵盖了基本的无监督学习算法,并提供了应用和案例研究。
第三部分的章节如下:
第七章,无监督学习:降维
本章描述了减少数据集中特征数量的基本技术,同时保留大部分有用和区分信息的标准方法,如主成分分析,并涵盖了在投资组合管理、交易策略和收益率曲线构建中的案例研究。
第八章,无监督学习:聚类
本章涵盖了与聚类相关的算法和技术,用于识别共享相似度的对象群。本章还涵盖了在交易策略和投资组合管理中应用聚类的案例研究。
第四部分:强化学习和自然语言处理
第四部分涵盖了强化学习和自然语言处理(NLP)技术。
第四部分的章节如下:
第九章,强化学习
本章涵盖了强化学习的概念和案例研究,这在金融行业具有广泛的应用潜力。强化学习的主要思想“最大化回报”与金融多个领域的核心动机完美契合。本章还涵盖了与交易策略、投资组合优化和衍生品对冲相关的案例研究。
第十章,自然语言处理
本章描述了自然语言处理中的技术,并讨论了将文本数据转化为金融领域中有意义的表示的基本步骤。涵盖了与情感分析、聊天机器人和文档解释相关的案例研究。
本书使用的约定
本书中使用了以下印刷约定:
斜体
表示新术语、URL、电子邮件地址、文件名和文件扩展名。
等宽字体
用于程序列表,以及段落内引用程序元素,如变量或函数名称、数据库、数据类型、环境变量、语句和关键字。
提示
此元素表示提示或建议。
注意
此元素表示一般注意事项。
警告
此元素表示警告或注意事项。
注意
此元素表示蓝图。
使用本书中的代码
本书中的所有代码(案例研究和主模板)都可以在 GitHub 目录中找到:https://github.com/tatsath/fin-ml。代码托管在云平台上,因此可以通过点击https://mybinder.org/v2/gh/tatsath/fin-ml/master在本地机器上不安装任何包就运行每个案例研究。
本书旨在帮助您完成工作。一般情况下,如果提供示例代码,您可以在自己的程序和文档中使用它。除非您要复制代码的大部分,否则无需联系我们以获取许可。例如,编写使用本书中几个代码块的程序不需要许可。销售或分发 O’Reilly 书籍中的示例需要许可。引用本书并引用示例代码来回答问题不需要许可。将本书中大量示例代码整合到产品文档中需要许可。
我们感谢您的支持,但通常不要求署名。署名通常包括标题、作者、出版社和 ISBN 号。例如:Machine Learning and Data Science Blueprints for Finance,作者 Hariom Tatsat、Sahil Puri 和 Brad Lookabaugh(O’Reilly,2021),978-1-492-07305-5。
如果您觉得您对代码示例的使用超出了公平使用范围或上述授权,请随时通过 permissions@oreilly.com 联系我们。
Python 库
本书使用 Python 3.7. 推荐安装 Conda 包管理器,以创建 Conda 环境来安装所需的库。安装说明请参见 GitHub 仓库的 README 文件。
O’Reilly 在线学习
注意
40 多年来,O’Reilly Media 一直提供技术和商业培训、知识和见解,帮助公司取得成功。
我们独特的专家和创新者网络通过书籍、文章和我们的在线学习平台分享他们的知识和专业知识。O’Reilly 的在线学习平台让您随需应变地访问直播培训课程、深入学习路径、交互式编码环境以及来自 O’Reilly 和其他 200 多个出版商的大量文本和视频内容。欲了解更多信息,请访问 http://oreilly.com。
如何联系我们
请将关于本书的评论和问题发送至出版商:
-
O’Reilly Media, Inc.
-
1005 Gravenstein Highway North
-
加利福尼亚州塞巴斯托波尔 95472
-
800-998-9938(美国或加拿大)
-
707-829-0515(国际或本地)
-
707-829-0104(传真)
我们为这本书创建了一个网页,列出勘误、示例和任何额外信息。您可以访问该页面 https://oreil.ly/ML-and-data-science-blueprints。
通过电子邮件 bookquestions@oreilly.com 发表评论或提出关于本书的技术问题。
获取关于我们书籍和课程的新闻和信息,请访问 http://oreilly.com
在 Facebook 上找到我们:http://facebook.com/oreilly
在 Twitter 上关注我们:http://twitter.com/oreillymedia
在 YouTube 上观看我们:http://youtube.com/oreillymedia
致谢
我们要感谢所有帮助使这本书变成现实的人。特别感谢 Jeff Bleiel 提供诚实、有见地的反馈,并指导我们完成整个过程。我们非常感激 Juan Manuel Contreras、Chakri Cherukuri 和 Gregory Bronner,他们抽出宝贵时间详细审查了我们的书籍。书籍受益于他们宝贵的反馈和建议。同样感谢 O’Reilly 出色的工作人员,特别是 Michelle Smith,她对这个项目的支持和帮助让我们明确了其范围。
Hariom 的特别感谢
我要感谢我的妻子 Prachi 和我的父母,感谢他们的爱和支持。特别感谢我的父亲,在我所有追求中鼓励我,并持续成为我的灵感源泉。
Sahil 的特别感谢
感谢我的家人,在我所有努力中始终鼓励和支持我。
Brad 的特别感谢
感谢我的妻子 Megan,她无尽的爱和支持。
第一部分:框架
第一章:机器学习在金融中的景观
机器学习有望彻底改变金融的大片领域
经济学人(2017 年)
金融中有一波新的机器学习和数据科学浪潮,相关应用将在未来几十年内彻底改变这个行业。
目前,包括对冲基金、投资和零售银行以及金融科技公司在内的大多数金融公司,都在采用并大量投资于机器学习。未来,金融机构将需要越来越多的机器学习和数据科学专家。
由于大量数据的可用性和更加负担得起的计算能力,近年来机器学习在金融中的使用正呈指数级增长。
机器学习在金融领域的成功取决于构建高效的基础设施,使用正确的工具包和应用合适的算法。本书全程演示和利用了机器学习在金融中这些基础模块的相关概念。
在本章中,我们介绍了机器学习在金融中当前和未来的应用,包括对不同类型机器学习的简要概述。本章和随后的两章为本书其余部分中介绍的案例研究奠定了基础。
金融中当前和未来的机器学习应用
让我们看看金融中一些有前途的机器学习应用。本书中介绍的案例研究涵盖了这里提到的所有应用。
算法交易
算法交易(或简称algo trading)是使用算法自主进行交易的方法。起源可以追溯到上世纪 70 年代,算法交易(有时被称为自动交易系统,这可能更准确地描述)涉及使用自动预编程的交易指令,以做出极快速、客观的交易决策。
机器学习有望将算法交易推向新的高度。不仅可以采用和实时调整更先进的策略,而且基于机器学习的技术可以提供更多获得市场走向特殊洞察的途径。大多数对冲基金和金融机构并不公开披露他们基于机器学习的交易方法(出于正当理由),但机器学习在实时校准交易决策中的作用越来越重要。
投资组合管理和智能投顾
资产和财富管理公司正在探索潜在的人工智能(AI)解决方案,以改善他们的投资决策并利用他们的大量历史数据。
一个例子是使用智能投顾,这是为了根据用户的目标和风险承受能力调整金融投资组合的算法。此外,它们为最终投资者和客户提供自动化的财务指导和服务。
用户输入他们的财务目标(例如在 65 岁时以 25 万美元的储蓄退休)、年龄、收入和当前财务资产。顾问(分配器)然后将投资分散到资产类别和金融工具中,以达到用户的目标。
系统然后根据用户的目标和市场实时变化进行校准,始终致力于找到用户原始目标的最佳匹配。机器顾问已经在那些无需人类顾问即可感到舒适的消费者中获得了显著的吸引力。
欺诈检测
对金融机构而言,欺诈是一个巨大的问题,也是在金融中利用机器学习的首要原因之一。
当前存在显著的数据安全风险,由于高计算能力、频繁的互联网使用以及存储在线上的公司数据量不断增加。虽然以前的金融欺诈检测系统严重依赖复杂而健壮的规则集,但现代欺诈检测超越了遵循风险因素清单的检查——它积极学习并校准到新的潜在(或实际)安全威胁。
机器学习非常适合于打击欺诈金融交易。这是因为机器学习系统可以扫描庞大的数据集,检测异常活动,并立即标记它们。鉴于安全性可能被侵犯的方式不可胜数,真正的机器学习系统将在未来成为绝对必要。
贷款/信用卡/保险核保
核保可以被描述为金融中机器学习的完美工作,确实有很多担忧,即机器将取代今天存在的大量核保职位。
尤其是在大公司(大银行和上市保险公司),机器学习算法可以基于数百万个消费者数据和金融贷款或保险结果进行训练,例如一个人是否违约其贷款或抵押贷款。
利用算法可以评估潜在的金融趋势,并持续分析,以便检测可能影响未来贷款和核保风险的趋势。算法可以执行自动化任务,如匹配数据记录、识别异常情况,并计算申请人是否符合信贷或保险产品的资格。
自动化与聊天机器人
自动化显然非常适合于金融领域。它减少了重复、低价值任务对人类员工的压力。它处理日常例行流程,使团队能够完成其高价值工作。通过这样做,它带来了巨大的时间和成本节约。
将机器学习和人工智能融入自动化中,为员工提供了另一层支持。通过获取相关数据,机器学习和人工智能可以提供深入的数据分析,支持金融团队进行困难决策。在某些情况下,甚至可以推荐最佳行动方案供员工批准和实施。
金融领域的人工智能和自动化还可以学习识别错误,减少在发现和解决之间浪费的时间。这意味着人类团队成员在提供报告时更不容易延迟,能够减少工作中的错误。
AI 聊天机器人可以被用来支持金融和银行客户。随着银行和金融企业中实时聊天软件的流行,聊天机器人是自然演变的产物。
风险管理
机器学习技术正在改变我们对风险管理的方式。通过机器学习驱动的解决方案的增长,所有了解和控制风险的方面都正在发生革命性变化。例子包括决定银行应该向客户贷款多少,改善合规性并减少模型风险。
资产价格预测
资产价格预测被认为是金融领域中讨论最频繁、最复杂的领域。预测资产价格使人们能够了解推动市场的因素并推测资产表现。传统上,通过分析过去的财务报告和市场表现来预测资产价格,以确定特定证券或资产类别的持仓位置。然而,随着金融数据量的大幅增加,传统的分析方法和股票选择策略正在补充机器学习技术。
衍生品定价
最近机器学习取得的成功以及创新的快速步伐表明,未来几年衍生品定价的机器学习应用将广泛应用。黑-舒尔斯模型、波动率笑曲线和 Excel 电子表格模型的世界应逐渐消退,因为更先进的方法变得更易获取。
经典的衍生品定价模型建立在几个不切实际的假设上,旨在复制市场上观察到的衍生品价格与基础输入数据(行权价格、到期时间、期权类型)之间的经验关系。机器学习方法不依赖于多个假设;它们只是尝试估计输入数据与价格之间的函数,最小化模型结果与目标之间的差异。
最先进的机器学习工具实现的更快部署时间只是加速衍生品定价机器学习应用使用的优势之一。
情绪分析
情感分析涉及对大量非结构化数据进行审视,例如视频、转录、照片、音频文件、社交媒体帖子、文章和商业文件,以确定市场情绪。情感分析在今天的工作场所对所有企业至关重要,并且是金融中机器学习的一个极好的示例。
在金融领域中,情感分析最常见的用途是分析金融新闻,特别是预测市场的行为和可能的趋势。股市的波动是由无数与人类相关的因素引起的,机器学习能够通过发现新的趋势和发出信号来复制和增强人类对金融活动的直觉。
然而,未来机器学习的大部分应用将集中在理解社交媒体、新闻趋势和其他与预测客户对市场发展的情绪相关的数据来源上。它不仅限于预测股票价格和交易。
交易结算
交易结算是在金融资产交易后将证券转入买方账户并将现金转入卖方账户的过程。
尽管大多数交易都是自动结算的,并且很少或没有人类干预,约 30% 的交易仍然需要手动结算。
使用机器学习不仅可以识别失败交易的原因,还可以分析为什么交易被拒绝,提供解决方案,并预测未来可能失败的交易。通常人类需要花费五到十分钟来解决的问题,机器学习可以在几秒钟内完成。
洗钱
联合国的一份报告估计,全球每年洗钱金额占全球 GDP 的 2%–5%。机器学习技术可以分析客户广泛网络中的内部、公开存在的和交易数据,试图发现洗钱迹象。
机器学习、深度学习、人工智能和数据科学
对于大多数人来说,机器学习、深度学习、人工智能 和 数据科学 这些术语很令人困惑。事实上,很多人会将其中一个术语与其他术语混为一谈。
图 1-1 显示了人工智能、机器学习、深度学习和数据科学之间的关系。机器学习是人工智能的一个子集,包括使计算机能够识别数据中的模式并交付人工智能应用的技术。而深度学习则是机器学习的一个子集,使计算机能够解决更复杂的问题。
数据科学并不完全是机器学习的一个子集,但它利用机器学习、深度学习和人工智能来分析数据并得出可操作的结论。它结合了机器学习、深度学习和人工智能与其他学科,如大数据分析和云计算。
图 1-1. AI、机器学习、深度学习和数据科学
以下是关于人工智能、机器学习、深度学习和数据科学的详细信息摘要:
人工智能
人工智能是研究计算机(及其系统)如何成功完成通常需要人类智能的复杂任务的领域。这些任务包括但不限于视觉感知、语音识别、决策制定和语言之间的翻译。人工智能通常被定义为使计算机在人类执行时需要智能的事物的科学。
机器学习
机器学习是人工智能的一种应用,它使 AI 系统能够自动从环境中学习,并将这些教训应用于做出更好的决策。机器学习使用各种算法来迭代学习、描述和改进数据,识别模式,然后对这些模式进行操作。
深度学习
深度学习是机器学习的一个子集,涉及与人工神经网络相关的算法研究,这些网络包含许多块(或层)堆叠在一起。深度学习模型的设计受到人类大脑生物神经网络的启发。它努力分析具有类似逻辑结构的数据,就像人类如何得出结论一样。
数据科学
数据科学是一个类似于数据挖掘的跨学科领域,利用科学方法、过程和系统从各种形式的数据中提取知识或洞见。数据科学与机器学习和人工智能不同,因为它的目标是通过使用不同的科学工具和技术来洞察和理解数据。然而,机器学习和数据科学都有一些共同的工具和技术,其中一些在本书中有所展示。
机器学习类型
本节将概述本书中用于各种金融应用的不同案例研究中使用的所有类型的机器学习。如图 1-2 所示,机器学习的三种类型是监督学习、无监督学习和强化学习。
图 1-2. 机器学习类型
监督
监督学习 的主要目标是从带标签数据中训练模型,使我们能够对未见或未来的数据进行预测。这里,“监督”一词指的是已知期望输出信号(标签)的一组样本。监督学习算法有两种类型:分类和回归。
分类
分类 是监督学习的一个子类,其目标是基于过去的观察预测新实例的分类类别标签。
回归
回归 是监督学习的另一子类,用于预测连续结果。在回归中,我们有多个预测(解释)变量和一个连续的响应变量(结果或目标),并尝试找到这些变量之间的关系,以便预测结果。
回归与分类的一个示例显示在 图 1-3 中。左侧的图表显示了一个回归的示例。连续的响应变量是回报,观察到的值与预测的结果相对比。右侧的图表显示了一个分类的示例,结果是一个分类类别标签,即市场是牛市还是熊市。
图 1-3. 回归与分类
无监督
无监督学习是一种机器学习类型,用于从不带标记响应的输入数据集中推断。无监督学习分为两种类型:降维和聚类。
降维
降维 是在保留信息和整体模型性能的同时减少数据集中特征或变量数量的过程。这是处理具有大量维度的数据集的常见且强大的方式。
图 1-4 展示了这一概念,其中数据的维度从两个维度(X[1] 和 X[2])转换为一个维度(Z[1])。 Z[1] 传达了嵌入在 X[1] 和 X[2] 中的相似信息,并且减少了数据的维度。
图 1-4. 降维
聚类
聚类 是无监督学习技术的一个子类,允许我们发现数据中隐藏的结构。聚类的目标是在数据中找到自然的分组,使同一组中的项目彼此更相似,而与来自不同组的项目更不相似。
聚类的一个示例显示在 图 1-5 中,聚类算法将整个数据聚集为两个明显的组。
图 1-5. 聚类
强化学习
从经验中学习,并伴随奖励或惩罚,是强化学习(RL)的核心概念。它涉及在特定情况下采取适当的行动以最大化奖励。学习系统称为智能体,可以观察环境,选择和执行动作,并获得回报(或以负奖励形式的惩罚),如 图 1-6 所示。
强化学习在以下方面与监督学习不同:在监督学习中,训练数据有答案标签,因此模型是根据可用的正确答案进行训练的。在强化学习中,没有显式的答案。学习系统(代理)决定如何执行给定任务,并根据奖励学习该动作是否正确。算法通过其经验确定答案标签。
图 1-6. 强化学习
强化学习的步骤如下:
-
首先,代理通过执行一个动作与环境进行交互。
-
然后,代理根据执行的动作获得奖励。
-
根据奖励,代理接收一个观察结果并理解该动作是好是坏。如果动作是好的,也就是代理收到了正面奖励,那么代理将更倾向于执行这个动作。如果奖励不太好,代理将尝试执行其他动作以获得正面奖励。这基本上是一个试错学习过程。
自然语言处理
自然语言处理(NLP)是人工智能的一个分支,处理机器理解人类使用的自然语言结构和含义的问题。NLP 内部使用了多种机器学习和深度学习技术。
NLP 在金融领域有许多应用,如情感分析、聊天机器人和文档处理等。很多信息,如卖方报告、收益电话和报纸头条,是通过文本信息传达的,使得 NLP 在金融领域非常有用。
鉴于基于机器学习的 NLP 算法在金融中的广泛应用,本书有一章(第十章)专门介绍 NLP 及相关案例研究。
章节总结
机器学习正在金融服务行业的各个垂直领域取得显著进展。本章介绍了机器学习在金融领域的不同应用,从算法交易到智能投顾。这些应用将在本书后面的案例研究中详细介绍。
后续步骤
在用于机器学习的平台方面,Python 生态系统正在发展壮大,是最主要的机器学习编程语言之一。在下一章中,我们将学习基于 Python 框架的模型开发步骤,从数据准备到模型部署。
第二章:在 Python 中开发机器学习模型
在用于机器学习的平台方面,有许多算法和编程语言可选择。然而,Python 生态系统是最主流和增长最快的机器学习编程语言之一。
鉴于 Python 的流行度和高采纳率,我们将其作为本书的主要编程语言。本章将概述基于 Python 的机器学习框架。首先,我们将回顾用于机器学习的 Python 包的详细信息,然后介绍 Python 框架中的模型开发步骤。
本章介绍的 Python 模型开发步骤将作为本书其余案例研究的基础。在金融领域开发任何基于机器学习的模型时,也可以利用 Python 框架。
为何选择 Python?
Python 受欢迎的原因有:
-
高级语法(与 C、Java 和 C++等低级语言相比)。编写更少的代码即可开发应用程序,这使得 Python 对初学者和高级程序员都很有吸引力。
-
高效的开发生命周期。
-
社区管理的大量开源库。
-
强大的可移植性。
Python 的简单性吸引了许多开发者为机器学习创建新的库,从而使 Python 的使用率大幅提升。
Python 机器学习包
主要用于机器学习的 Python 包在图 2-1 中得到了突出显示。
图 2-1. Python 软件包
下面简要总结了每个软件包:
提供对大型多维数组的支持以及广泛的数学函数集合。
用于数据处理和分析的库。除其他功能外,它还提供了处理表格的数据结构和相关工具。
允许创建 2D 图表和图形的绘图库。
NumPy、Pandas 和 Matplotlib 的组合通常被称为 SciPy。SciPy 是用于数学、科学和工程的 Python 库生态系统。
Scikit-learn(或 sklearn)
提供广泛算法和工具的机器学习库。
一个 Python 模块,提供类和函数,用于众多不同统计模型的估计,以及进行统计检验和统计数据探索。
数据流编程库有助于处理神经网络。
一个人工神经网络库,可以作为简化的 TensorFlow/Theano 软件包接口。
基于 Matplotlib 的数据可视化库。它提供了一个高级接口,用于绘制引人入胜且信息丰富的统计图形。
这些是 Python 包管理器。pip 是一个包管理器,用于简化 Python 包的安装、升级和卸载。Conda 是一个包管理器,处理 Python 包以及 Python 包之外的库依赖。
Python 和包安装
安装 Python 有不同的方法。然而,强烈建议通过Anaconda安装 Python。Anaconda 包含 Python、SciPy 和 Scikit-learn。
安装完 Anaconda 后,可以通过打开机器的终端并输入以下代码来在本地启动 Jupyter 服务器:
$jupyter notebook
注意
本书中的所有代码示例均使用 Python 3,并以 Jupyter 笔记本形式呈现。在案例研究中广泛使用了多个 Python 包,特别是 Scikit-learn 和 Keras。
Python 生态系统中模型开发步骤
从头到尾解决机器学习问题至关重要。除非从开始到结束定义了步骤,否则应用的机器学习将无法真正发挥作用。
图 2-2 提供了一个简单的七步机器学习项目模板概述,可用于快速启动 Python 中的任何机器学习模型。前几个步骤包括探索性数据分析和数据准备,这是典型的数据科学步骤,旨在从数据中提取含义和洞见。这些步骤之后是模型评估、微调和最终化模型。
图 2-2. 模型开发步骤
注意
本书中的所有案例研究均遵循标准的七步模型开发过程。然而,有些案例研究会根据步骤的适当性和直观性跳过、重命名或重新排序一些步骤。
模型开发蓝图
下一节详细介绍了每个模型开发步骤及其支持的 Python 代码细节。
1. 问题定义
任何项目的第一步都是定义问题。可以使用强大的算法来解决问题,但如果解决了错误的问题,结果将毫无意义。
应使用以下框架来定义问题:
-
非正式和正式地描述问题。列出假设和类似问题。
-
列出解决问题的动机,解决方案提供的好处以及解决方案的使用方式。
-
描述如何使用领域知识解决问题。
2. 加载数据和包
第二步提供了开始解决问题所需的一切。这包括加载用于模型开发所需的库、包和单个函数。
2.1. 加载库
加载库的示例代码如下:
# Load libraries
import pandas as pd
from matplotlib import pyplot
特定功能的库和模块的详细信息在个案研究中进一步定义。
2.2. 加载数据
在加载数据之前,应检查并删除以下项目:
-
列标题
-
注释或特殊字符
-
分隔符
有许多加载数据的方法。以下是一些最常见的方法:
使用 Pandas 加载 CSV 文件
from pandas import read_csv
filename = 'xyz.csv'
data = read_csv(filename, names=names)
从 URL 加载文件
from pandas import read_csv
url = 'https://goo.gl/vhm1eU'
names = ['age', 'class']
data = read_csv(url, names=names)
使用 pandas_datareader 加载文件
import pandas_datareader.data as web
ccy_tickers = ['DEXJPUS', 'DEXUSUK']
idx_tickers = ['SP500', 'DJIA', 'VIXCLS']
stk_data = web.DataReader(stk_tickers, 'yahoo')
ccy_data = web.DataReader(ccy_tickers, 'fred')
idx_data = web.DataReader(idx_tickers, 'fred')
3. 探索性数据分析
在此步骤中,我们查看数据集。
3.1. 描述统计
了解数据集是模型开发中最重要的步骤之一。了解数据的步骤包括:
-
查看原始数据。
-
查看数据集的维度。
-
查看属性的数据类型。
-
汇总数据集中变量的分布、描述统计和关系。
使用示例 Python 代码演示以下步骤:
查看数据
set_option('display.width', 100)
dataset.head(1)
输出
| 年龄 | 性别 | 工作 | 住房 | 储蓄账户 | 支票账户 | 信用金额 | 期限 | 目的 | 风险 | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 67 | 男性 | 2 | 自有 | NaN | 少量 | 1169 | 6 | 无线电/电视 | 良好 |
查看数据集的维度
dataset.shape
输出
(284807, 31)
结果显示数据集的维度,并表明数据集有 284,807 行和 31 列。
查看数据属性的数据类型
# types
set_option('display.max_rows', 500)
dataset.dtypes
使用描述性统计汇总数据
# describe data
set_option('precision', 3)
dataset.describe()
输出
| 年龄 | 职业 | 信用金额 | 期限 | |
|---|---|---|---|---|
| count | 1000.000 | 1000.000 | 1000.000 | 1000.000 |
| mean | 35.546 | 1.904 | 3271.258 | 20.903 |
| std | 11.375 | 0.654 | 2822.737 | 12.059 |
| min | 19.000 | 0.000 | 250.000 | 4.000 |
| 25% | 27.000 | 2.000 | 1365.500 | 12.000 |
| 50% | 33.000 | 2.000 | 2319.500 | 18.000 |
| 75% | 42.000 | 2.000 | 3972.250 | 24.000 |
| max | 75.000 | 3.000 | 18424.000 | 72.000 |
3.2. 数据可视化
最快了解数据的方法是将其可视化。可视化包括独立理解数据集的每个属性。
以下是一些绘图类型:
单变量图
直方图和密度图
多变量图
相关矩阵图和散点图
以下是单变量绘图类型的 Python 代码示例:
单变量绘图:直方图
from matplotlib import pyplot
dataset.hist(sharex=False, sharey=False, xlabelsize=1, ylabelsize=1,\
figsize=(10,4))
pyplot.show()
单变量绘图:密度图
from matplotlib import pyplot
dataset.plot(kind='density', subplots=True, layout=(3,3), sharex=False,\
legend=True, fontsize=1, figsize=(10,4))
pyplot.show()
图 2-3 说明了输出。
图 2-3. 直方图(上)和密度图(下)
以下是多变量绘图类型的 Python 代码示例:
多变量绘图:相关矩阵图
from matplotlib import pyplot
import seaborn as sns
correlation = dataset.corr()
pyplot.figure(figsize=(5,5))
pyplot.title('Correlation Matrix')
sns.heatmap(correlation, vmax=1, square=True,annot=True,cmap='cubehelix')
多变量绘图:散点图矩阵
from pandas.plotting import scatter_matrix
scatter_matrix(dataset)
图 2-4 说明了输出。
图 2-4. 相关性(左)和散点图(右)
4. 数据准备
数据准备是一种预处理步骤,其中来自一个或多个来源的数据被清理和转换,以提高其质量,以便在使用之前使用。
4.1. 数据清洗
在机器学习建模中,不正确的数据可能会很昂贵。数据清洗包括检查以下内容:
有效性
数据类型、范围等。
准确性
数据接近真实值的程度。
完整性
所需数据完全已知的程度。
统一性
使用相同测量单位指定数据的程度。
执行数据清洗的不同选项包括:
删除数据中的“NA”值
dataset.dropna(axis=0)
用 0 填充“NA”
dataset.fillna(0)
用列均值填充 NA 值
dataset['col'] = dataset['col'].fillna(dataset['col'].mean())
4.2. 特征选择
用于训练机器学习模型的数据特征对性能有很大影响。不相关或部分相关的特征可能会对模型性能产生负面影响。特征选择¹ 是一个过程,在这个过程中,自动选择对预测变量或输出贡献最大的数据特征。
在对数据建模之前执行特征选择的好处是:
减少过拟合²
较少冗余数据意味着模型基于噪声进行决策的机会更少。
改善性能
较少误导性数据意味着改进的建模性能。
减少训练时间和内存占用
较少的数据意味着更快的训练速度和更低的内存占用。
下面的样本特征是一个示例,演示了如何使用SelectKBest函数选择最佳的两个特征。SelectKBest函数使用底层函数对特征进行评分,然后移除除了k个最高评分特征以外的所有特征:
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
bestfeatures = SelectKBest( k=5)
fit = bestfeatures.fit(X,Y)
dfscores = pd.DataFrame(fit.scores_)
dfcolumns = pd.DataFrame(X.columns)
featureScores = pd.concat([dfcolumns,dfscores],axis=1)
print(featureScores.nlargest(2,'Score')) #print 2 best features
输出
Specs Score
2 Variable1 58262.490
3 Variable2 321.031
当特征无关时,它们应该被删除。删除无关特征的方法如下示例代码所示:
#dropping the old features
dataset.drop(['Feature1','Feature2','Feature3'],axis=1,inplace=True)
4.3. 数据转换
许多机器学习算法对数据有假设。以最佳方式对数据进行准备,使数据能够最好地暴露给机器学习算法,这是一个良好的实践。这可以通过数据转换来实现。
下面是不同的数据转换方法:
重新调整比例
当数据包含具有不同比例的属性时,许多机器学习算法可以通过将所有属性重新调整到相同的比例来受益。属性通常重新调整到零到一的范围内。这对于机器学习算法中使用的优化算法非常有用,也有助于加速算法中的计算:
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
rescaledX = pd.DataFrame(scaler.fit_transform(X))
标准化
标准化 是一种有用的技术,用于将属性转换为均值为零、标准差为一的标准正态分布。对于假设输入变量表示正态分布的技术非常适用:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler().fit(X)
StandardisedX = pd.DataFrame(scaler.fit_transform(X))
标准化
标准化 指的是将每个观察(行)重新缩放为长度为一(称为单位范数或向量)。在使用加权输入值的算法处理具有不同尺度属性的稀疏数据集时,这种预处理方法非常有用:
from sklearn.preprocessing import Normalizer
scaler = Normalizer().fit(X)
NormalizedX = pd.DataFrame(scaler.fit_transform(X))
5. 评估模型
一旦我们估算了算法的性能,我们可以在整个训练数据集上重新训练最终的算法,并准备好用于操作。这样做的最佳方法是在新数据集上评估算法的性能。不同的机器学习技术需要不同的评估指标。在选择模型时,除了模型性能之外,还考虑了几个其他因素,如简易性、可解释性和训练时间。有关这些因素的详细信息在第四章中有所涵盖。
5.1. 训练和测试分割
评估机器学习算法性能的最简单方法是使用不同的训练和测试数据集。我们可以将原始数据集分成两部分:在第一部分上训练算法,对第二部分进行预测,并将预测结果与期望结果进行评估。分割的大小可以取决于数据集的大小和具体情况,尽管通常使用 80%的数据进行训练,剩余的 20%用于测试。训练和测试数据集之间的差异可能导致准确度估计的显著差异。可以使用 sklearn 中提供的train_test_split函数轻松地将数据分割成训练集和测试集:
# split out validation dataset for the end
validation_size = 0.2
seed = 7
X_train, X_validation, Y_train, Y_validation =\
train_test_split(X, Y, test_size=validation_size, random_state=seed)
5.2. 确定评估指标
选择用于评估机器学习算法的度量标准非常重要。评估指标的一个重要方面是其在区分模型结果方面的能力。本书的多个章节详细介绍了不同类型的 ML 模型所使用的不同类型的评估指标。
5.3. 比较模型和算法
选择机器学习模型或算法既是一门艺术,也是一门科学。没有一种适合所有情况的解决方案或方法。除了模型性能之外,还有多个因素可能影响选择机器学习算法的决策。
让我们通过一个简单的例子来理解模型比较的过程。我们定义两个变量,X和Y,并尝试构建一个预测Y使用X的模型。作为第一步,数据按前面部分提到的训练和测试分割进行分割:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
validation_size = 0.2
seed = 7
X = 2 - 3 * np.random.normal(0, 1, 20)
Y = X - 2 * (X ** 2) + 0.5 * (X ** 3) + np.exp(-X)+np.random.normal(-3, 3, 20)
# transforming the data to include another axis
X = X[:, np.newaxis]
Y = Y[:, np.newaxis]
X_train, X_test, Y_train, Y_test = train_test_split(X, Y,\
test_size=validation_size, random_state=seed)
我们不知道哪种算法在这个问题上表现良好。现在让我们设计我们的测试。我们将使用两个模型——一个线性回归和第二个多项式回归来拟合Y和X。我们将使用*均方根误差(RMSE)*指标来评估算法的性能,这是模型性能的一种度量。RMSE 将给出所有预测的错误程度的大致概念(零是完美的):
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.preprocessing import PolynomialFeatures
model = LinearRegression()
model.fit(X_train, Y_train)
Y_pred = model.predict(X_train)
rmse_lin = np.sqrt(mean_squared_error(Y_train,Y_pred))
r2_lin = r2_score(Y_train,Y_pred)
print("RMSE for Linear Regression:", rmse_lin)
polynomial_features= PolynomialFeatures(degree=2)
x_poly = polynomial_features.fit_transform(X_train)
model = LinearRegression()
model.fit(x_poly, Y_train)
Y_poly_pred = model.predict(x_poly)
rmse = np.sqrt(mean_squared_error(Y_train,Y_poly_pred))
r2 = r2_score(Y_train,Y_poly_pred)
print("RMSE for Polynomial Regression:", rmse)
输出
RMSE for Linear Regression: 6.772942423315028
RMSE for Polynomial Regression: 6.420495127266883
我们可以看到多项式回归的 RMSE 略优于线性回归的 RMSE。由于前者拟合效果更好,因此在这一步骤中它是首选模型。
6. 模型调优
找到模型最佳超参数组合可以被视为一个搜索问题。⁴ 这种搜索练习通常被称为模型调优,是模型开发中最重要的步骤之一。通过使用诸如网格搜索等技术,通过创建所有可能的超参数组合网格并对每一个进行训练来寻找最佳模型的参数。除了网格搜索外,还有几种其他模型调优技术,包括随机搜索、贝叶斯优化和超品牌。
在本书介绍的案例研究中,我们主要集中于模型调优的网格搜索。
继续前述示例,以多项式作为最佳模型:接下来,对模型进行网格搜索,使用不同的次数重新拟合多项式回归。我们比较所有模型的 RMSE 结果:
Deg= [1,2,3,6,10]
results=[]
names=[]
for deg in Deg:
polynomial_features= PolynomialFeatures(degree=deg)
x_poly = polynomial_features.fit_transform(X_train)
model = LinearRegression()
model.fit(x_poly, Y_train)
Y_poly_pred = model.predict(x_poly)
rmse = np.sqrt(mean_squared_error(Y_train,Y_poly_pred))
r2 = r2_score(Y_train,Y_poly_pred)
results.append(rmse)
names.append(deg)
plt.plot(names, results,'o')
plt.suptitle('Algorithm Comparison')
输出
当多项式模型的次数增加时,RMSE 减小,而次数为 10 的模型具有最低的 RMSE。然而,次数低于 10 的模型表现非常好,测试集将用于确定最佳模型。
每个算法的通用输入参数集为分析提供了一个起点,但可能并非特定数据集和业务问题的最优配置。
7. 完善模型
在这里,我们执行选择模型的最后步骤。首先,我们使用训练好的模型对测试数据集进行预测。然后,我们尝试理解模型的直觉并保存以备进一步使用。
7.1. 测试集上的性能
在训练步骤中选择的模型会在测试集上进一步评估。测试集能够以无偏的方式比较不同模型,通过在训练的任何部分都未使用的数据进行比较。以下是前述步骤开发的模型的测试结果示例:
Deg= [1,2,3,6,8,10]
for deg in Deg:
polynomial_features= PolynomialFeatures(degree=deg)
x_poly = polynomial_features.fit_transform(X_train)
model = LinearRegression()
model.fit(x_poly, Y_train)
x_poly_test = polynomial_features.fit_transform(X_test)
Y_poly_pred_test = model.predict(x_poly_test)
rmse = np.sqrt(mean_squared_error(Y_test,Y_poly_pred_test))
r2 = r2_score(Y_test,Y_poly_pred_test)
results_test.append(rmse)
names_test.append(deg)
plt.plot(names_test, results_test,'o')
plt.suptitle('Algorithm Comparison')
输出
在训练集中,我们看到随着多项式模型次数的增加,RMSE 减小,并且次数为 10 的多项式具有最低的 RMSE。然而,正如前面输出的次数为 10 的多项式所示,尽管训练集结果最佳,但测试集结果较差。对于次数为 8 的多项式,测试集中的 RMSE 相对较高。次数为 6 的多项式在测试集中表现最佳(尽管与测试集中其他次数较低的多项式相比差距不大),并且在训练集中也有良好的结果。因此,这是首选的模型。
除了模型性能之外,在选择模型时还有几个其他因素需要考虑,例如简单性、可解释性和训练时间。这些因素将在接下来的章节中进行讨论。
7.2. 模型/变量直觉
本步骤涉及综合考虑解决问题所采用的方法,包括模型在实现所期望的结果时的局限性、使用的变量以及选择的模型参数。关于不同类型的机器学习模型的模型和变量直觉的详细信息将在随后的章节和案例研究中呈现。
7.3. 保存/部署
找到准确的机器学习模型后,必须保存和加载它以确保以后的使用。
Pickle 是 Python 中用于保存和加载训练模型的包之一。使用 pickle 操作,训练好的机器学习模型可以以序列化的格式保存到文件中。稍后,可以加载这个序列化文件以反序列化模型进行使用。以下示例代码演示了如何将模型保存到文件并加载以在新数据上进行预测:
# Save Model Using Pickle
from pickle import dump
from pickle import load
# save the model to disk
filename = 'finalized_model.sav'
dump(model, open(filename, 'wb'))
# load the model from disk
loaded_model = load(filename)
提示
近年来,像AutoML这样的框架已经被构建出来,以自动化机器学习模型开发过程中的最大数量步骤。这些框架允许模型开发人员以高规模、高效率和高生产力构建 ML 模型。建议读者探索这些框架。
章节总结
由于其流行度、采纳率和灵活性,Python 往往是机器学习开发的首选语言。有许多可用的 Python 包来执行多种任务,包括数据清洗、可视化和模型开发。其中一些关键包括 Scikit-learn 和 Keras。
本章提到的模型开发的七个步骤可以在金融中开发任何基于机器学习的模型时使用。
下一步
在接下来的章节中,我们将涵盖机器学习的关键算法——人工神经网络。人工神经网络是金融领域机器学习的另一个构建模块,并且在各类机器学习和深度学习算法中广泛使用。
¹ 特征选择对监督学习模型更为重要,在第五章和第六章的个案研究中有详细描述。
² 过拟合在第四章中有详细讨论。
³ 应注意,在这种情况下,RMSE 的差异很小,并且可能在不同的训练/测试数据拆分下不会复制。
⁴ 超参数是模型的外部特性,可以被视为模型的设置,并且不是基于数据估计的模型参数。
第三章:人工神经网络
在机器学习中使用许多不同类型的模型。然而,一种突出的机器学习模型类别是人工神经网络(ANNs)。鉴于人工神经网络应用于所有类型的机器学习,本章将介绍 ANN 的基础知识。
ANN 是基于一组连接单位或节点(称为人工神经元)的计算系统,它们松散地模拟生物大脑中的神经元。每个连接就像生物大脑中的突触一样,可以将信号从一个人工神经元传输到另一个。接收信号的人工神经元可以处理它,然后将信号传递给连接到它的其他人工神经元。
深度学习 包括复杂的与 ANN 相关的算法研究。其复杂性归因于信息如何在模型中的精细模式中流动。深度学习能够将世界表示为概念的嵌套层次结构,每个概念都与更简单的概念相关定义。我们将在第 9 和 10 章中详细探讨深度学习技术在强化学习和自然语言处理应用中的使用。
ANN:架构、训练和超参数
ANN 包含多个层中排列的神经元。ANN 通过将建模输出与期望输出进行比较,通过训练阶段来学习在数据中识别模式。让我们详细介绍 ANN 的组成部分。
架构
ANN 架构包括神经元、层和权重。
神经元
ANN 的构建模块是神经元(也称为人工神经元、节点或感知器)。神经元具有一个或多个输入和一个输出。可以构建神经元网络来计算复杂的逻辑命题。这些神经元中的激活函数创建输入和输出之间复杂的非线性功能映射。²
如图 3-1 所示,一个神经元接受输入 (x[1], x[2]…x[n]),应用学习参数生成加权和 (z),然后将该和传递给计算输出 f(z) 的激活函数 f。
图 3-1. 人工神经元
层
单个神经元的输出 f(z)(如图 3-1 所示)无法对复杂任务进行建模。因此,为了处理更复杂的结构,我们使用多层这样的神经元。随着我们在水平和垂直方向上堆叠神经元,我们可以得到的函数类变得越来越复杂。图 3-2 展示了具有输入层、输出层和隐藏层的 ANN 架构。
图 3-2. 神经网络架构
输入层
输入层从数据集获取输入并且是网络的暴露部分。神经网络通常以数据集中每个输入值(或列)的一个神经元作为输入层来绘制。输入层中的神经元只是将输入值传递给下一层。
隐藏层
输入层之后的层称为隐藏层,因为它们不直接暴露给输入。最简单的网络结构是在隐藏层中有一个单独的神经元直接输出该值。
多层 ANN 能够解决更复杂的与机器学习相关的任务,因为它具有隐藏层。随着计算能力的增加和高效的库的出现,可以构建具有许多层的神经网络。具有许多隐藏层(超过三层)的 ANN 被称为深度神经网络。多个隐藏层允许深度神经网络学习数据的特征,因为简单的特征在一层到下一层的重新组合形成更复杂的特征。具有许多层的 ANN 将输入数据(特征)通过更多的数学运算而不是具有较少层的 ANN,并因此在训练过程中需要更多的计算量。
输出层
最终层称为输出层;它负责输出与解决问题所需格式相对应的值或值向量。
神经元权重
神经元权重表示单元之间连接的强度,并测量输入对输出的影响。如果从神经元一到神经元二的权重具有较大的幅度,则意味着神经元一对神经元二的影响较大。接近零的权重意味着改变此输入不会改变输出。负权重意味着增加此输入会减少输出。
训练
训练神经网络基本上意味着校准 ANN 中的所有权重。这种优化是使用涉及前向传播和反向传播步骤的迭代方法执行的。
前向传播
前向传播是将输入值馈送到神经网络并获得输出的过程,我们称之为预测值。当我们将输入值馈送到神经网络的第一层时,它会直接通过,不进行任何操作。第二层从第一层获取值,并在将该值传递到下一层之前应用乘法、加法和激活操作。同样的过程对任何后续层都重复,直到从最后一层接收到输出值。
反向传播
经过前向传播,我们从人工神经网络得到预测值。假设网络的期望输出是Y,前向传播的预测值是Y′。预测输出与期望输出的差异(Y–Y′)被转换为损失(或成本)函数J(w),其中w表示人工神经网络中的权重。³ 目标是优化损失函数(即使损失尽可能小)在训练集上的表现。
使用的优化方法是梯度下降。梯度下降方法的目标是找到J(w)关于w的梯度,并沿着负梯度方向迈出一小步,直到达到最小值,如图 3-3 所示。
图 3-3. 梯度下降
在人工神经网络中,函数J(w)本质上是多个层的组合,如前文所述。因此,如果将第一层表示为函数p(),第二层表示为q(),第三层表示为r(),那么整体函数为J(w)=r(q(p()))。w包含所有三层中的所有权重。我们希望找到J(w)关于w的每个分量的梯度。
略过数学细节,以上实质上意味着第一层中某个分量w的梯度将取决于第二层和第三层中的梯度。类似地,第二层中的梯度将取决于第三层中的梯度。因此,我们从最后一层开始反向计算导数,并使用反向传播计算前一层的梯度。
总体上,在反向传播过程中,模型误差(预测输出与期望输出之间的差异)逐层传播回网络,并根据它们对误差的贡献量更新权重。
几乎所有人工神经网络都使用梯度下降和反向传播。反向传播是找到梯度的一种清晰高效的方法之一。
超参数
超参数是在训练过程之前设置的变量,无法在训练中学习。人工神经网络具有大量超参数,这使得它们非常灵活。然而,这种灵活性使得模型调整过程变得困难。理解超参数及其背后的直觉有助于确定每个超参数的合理值,从而限制搜索空间。让我们从隐藏层和节点的数量开始。
隐藏层和节点数量
更多的隐藏层或每层节点意味着 ANN 中有更多的参数,使模型能够拟合更复杂的函数。为了有一个泛化能力良好的训练好的网络,我们需要选择一个最佳的隐藏层数量,以及每个隐藏层中的节点数量。节点和层数量过少会导致系统错误率高,因为预测因素可能对于少数节点来说过于复杂,难以捕捉。节点和层数量过多则会导致对训练数据过拟合,泛化能力差。
没有硬性规定来决定层数和节点的数量。
隐藏层数量主要取决于任务的复杂性。非常复杂的任务,如大规模图像分类或语音识别,通常需要具有数十层和大量训练数据的网络。对于大多数问题,我们可以从只有一个或两个隐藏层开始,然后逐渐增加隐藏层数量,直到开始过拟合训练集。
隐藏节点的数量应与输入和输出节点的数量、可用的训练数据量以及正在建模的函数复杂性有关。作为经验法则,每层隐藏节点的数量应该在输入层大小和输出层大小之间,理想情况下应接近平均值。每层隐藏节点的数量不应超过输入节点数量的两倍,以避免过拟合。
学习率
当我们训练 ANN 时,我们使用前向传播和反向传播的多次迭代来优化权重。在每次迭代中,我们计算损失函数对每个权重的导数,并从该权重中减去。学习率决定了我们希望更新权重值的速度。学习率应该足够高,以便在合理的时间内收敛。但它应该足够低,以便找到损失函数的最小值。
激活函数
激活函数(如在图 3-1 中所示)指的是 ANN 中用于获取期望输出的加权输入的函数。激活函数允许网络以更复杂的方式组合输入,并在建模关系和生成输出方面提供更丰富的能力。它们决定哪些神经元将被激活,即传递给更深层的信息。
没有激活函数,ANN 将失去其表示学习能力的大部分功能。有几种激活函数。最广泛使用的如下:
线性(恒等)函数
由直线方程表示(即,f ( x ) = m x + c ),其中激活与输入成正比。如果我们有多个层,并且所有层都是线性的,那么最后一层的激活函数与第一层的线性函数相同。线性函数的范围是 –inf 到 +inf。
Sigmoid 函数
指的是作为 S 形图像投射的函数(如图 3-4 所示)。其数学方程为 f ( x ) = 1 / ( 1 + e –x ) ,范围从 0 到 1。大正输入导致大正输出;大负输入导致大负输出。它也称为 logistic 激活函数。
双曲正切函数
与上述 sigmoid 激活函数类似,具有数学方程 T a n h ( x ) = 2 S i g m o i d ( 2 x ) – 1 ,其中 Sigmoid 表示上述讨论的 sigmoid 函数。此函数的输出范围为 –1 到 1,在零轴两侧具有相等的质量,如图 3-4 所示。
ReLU 函数
ReLU 代表修正线性单元,表示为 f ( x ) = m a x ( x , 0 ) 。因此,如果输入是正数,则函数返回该数本身,如果输入是负数,则函数返回零。由于其简单性,它是最常用的函数。
图 3-4 显示了本节讨论的激活函数的总结。
图 3-4. 激活函数
激活函数的选择没有硬性规定。决策完全依赖于问题的性质和建模的关系。我们可以尝试不同的激活函数,并选择帮助提供更快收敛和更高效训练过程的激活函数。输出层的激活函数的选择在很大程度上受到建模问题类型的限制。⁴
成本函数
成本函数(也称为损失函数)是 ANN 性能的一种度量,用于衡量 ANN 对经验数据的拟合程度。最常见的两种成本函数是:
均方误差(MSE)
这是主要用于回归问题的损失函数,其中输出是连续值。MSE 被定义为预测值与实际观察值之间差异的平方的平均值。在第四章中进一步描述了 MSE。
交叉熵(或log loss)
这个成本函数主要用于分类问题,其中输出是介于零和一之间的概率值。交叉熵损失随着预测概率与实际标签的偏差增大而增加。一个完美的模型的交叉熵为零。
优化器
优化器更新权重参数以最小化损失函数。⁵ 成本函数作为地形的指南,告诉优化器是否朝着达到全局最小值的正确方向移动。以下是一些常见的优化器:
动量
动量优化器除了当前步骤外,还查看先前的梯度。如果先前的更新和当前更新将权重移动到相同方向(增加动量),则会采取较大步长。如果梯度方向相反,则采取较小步长。可以将这种情况巧妙地想象成一个球在山谷中滚动——它在接近山谷底部时会获得动量。
AdaGrad(自适应梯度算法)
AdaGrad根据参数调整学习率,对于频繁出现的特征,执行较小的更新,并对于不频繁出现的特征执行较大的更新。
RMSProp
RMSProp代表 Root Mean Square Propagation。在 RMSProp 中,学习率会自动调整,并为每个参数选择不同的学习率。
Adam(自适应矩估计)
Adam结合了 AdaGrad 和 RMSProp 算法的最佳特性,提供了一种优化方式,是最流行的梯度下降优化算法之一。
Epoch
将整个训练数据集更新一轮称为epoch。根据数据大小和计算约束,网络可能会训练数十次、数百次,甚至数千次epoch。
Batch size
Batch size 是一次前向/反向传递中的训练样本数量。批量大小为 32 意味着在更新模型权重之前,将使用来自训练数据集的 32 个样本来估计误差梯度。批量大小越大,所需的内存空间就越多。
在 Python 中创建人工神经网络模型
在第二章中,我们讨论了在 Python 中进行端到端模型开发的步骤。在本节中,我们深入探讨了在 Python 中构建基于 ANN 的模型所涉及的步骤。
我们的第一步将是查看 Keras,这是专为人工神经网络(ANN)和深度学习而构建的 Python 软件包。
安装 Keras 和机器学习包
有几个 Python 库可以轻松快速地构建 ANN 和深度学习模型,而无需深入了解底层算法的细节。Keras 是最用户友好的软件包之一,可以有效进行与 ANN 相关的数值计算。使用 Keras,可以在几行代码中定义和实现复杂的深度学习模型。我们将主要使用 Keras 软件包来实现本书的几个案例研究中的深度学习模型。
Keras只是TensorFlow和Theano等更复杂的数值计算引擎的一个包装器。要安装 Keras,必须先安装 TensorFlow 或 Theano。
本节描述了在 Keras 中定义和编译基于 ANN 的模型的步骤,重点放在以下步骤上。⁶
导入包
在您开始构建 ANN 模型之前,您需要从 Keras 软件包中导入两个模块:Sequential和Dense:
from Keras.models import Sequential
from Keras.layers import Dense
import numpy as np
载入数据
此示例使用 NumPy 的random模块快速生成一些数据和标签,供我们在下一步中构建的 ANN 使用。具体来说,首先构建一个大小为*(1000,10)的数组。接下来,我们创建一个包含零和一的标签数组,大小为(1000,1)*:
data = np.random.random((1000,10))
Y = np.random.randint(2,size= (1000,1))
model = Sequential()
模型构建-定义神经网络架构
快速入门的一种方式是使用 Keras 的 Sequential 模型,它是层的线性堆栈。我们创建一个 Sequential 模型,并一次添加一个层,直到网络拓扑结构最终确定。正确的第一步是确保输入层具有正确数量的输入。我们可以在创建第一层时指定这一点。然后,我们选择一个密集或全连接层,通过使用参数input_dim来指示我们正在处理一个输入层。
我们使用add()函数向模型添加一层,并指定每层中的节点数。最后,另一个密集层被添加为输出层。
图 3-5 中显示的模型架构如下:
-
该模型期望具有 10 个变量的数据行(
input_dim_=10参数)。 -
第一个隐藏层有 32 个节点,并使用
relu激活函数。 -
第二个隐藏层有 32 个节点,并使用
relu激活函数。 -
输出层有一个节点,并使用
sigmoid激活函数。
图 3-5. ANN 架构
图中 3-5 中的网络的 Python 代码如下所示:
model = Sequential()
model.add(Dense(32, input_dim=10, activation= 'relu' ))
model.add(Dense(32, activation= 'relu' ))
model.add(Dense(1, activation= 'sigmoid'))
编译模型
模型构建完毕后,可以通过compile()函数进行编译。编译模型利用 Theano 或 TensorFlow 软件包中的高效数值库。在编译时,重要的是指定训练网络时所需的附加属性。训练网络意味着找到一组最佳权重以对所面临的问题进行预测。因此,我们必须指定用于评估一组权重的损失函数,用于搜索网络不同权重的优化器,并在训练过程中收集和报告任何可选的度量标准。
在下面的示例中,我们使用了cross-entropy损失函数,在 Keras 中被定义为binary_crossentropy。我们还将使用 adam 优化器,这是默认选项。最后,因为这是一个分类问题,我们将收集并报告分类准确性作为度量标准。⁷以下是 Python 代码:
model.compile(loss= 'binary_crossentropy' , optimizer= 'adam' , \
metrics=[ 'accuracy' ])
适配模型
定义并编译了我们的模型后,现在是在数据上执行它的时候了。我们可以通过在模型上调用fit()函数来训练或适配我们加载的数据。
训练过程将在数据集上通过固定次数的迭代(epochs)运行,使用nb_epoch参数进行指定。我们还可以设置在网络执行权重更新之前评估的实例数。这是通过batch_size参数设置的。对于这个问题,我们将运行少量 epochs(10),并使用相对较小的批量大小为 32。同样,这些可以通过试验和错误选择。以下是 Python 代码:
model.fit(data, Y, nb_epoch=10, batch_size=32)
评估模型
我们已经在整个数据集上训练了我们的神经网络,并且可以评估网络在同一数据集上的性能。这将使我们了解我们对数据集建模的效果(例如,训练准确性),但不会提供有关算法在新数据上表现如何的洞察。为此,我们将数据分为训练和测试数据集。使用evaluation()函数在训练数据集上评估模型。这将为每个输入和输出对生成预测,并收集分数,包括平均损失和配置的任何指标,如准确性。以下是 Python 代码:
scores = model.evaluate(X_test, Y_test)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
加速运行 ANN 模型:GPU 和云服务
对于训练 ANNs(特别是具有许多层的深度神经网络),需要大量的计算能力。可用的 CPU,或称为中央处理单元,在本地机器上负责处理和执行指令。由于 CPU 在核心数量上受限,并且顺序地执行作业,它们无法快速执行训练深度学习模型所需的大量矩阵计算。因此,在 CPU 上训练深度学习模型可能非常慢。
对于通常需要大量时间在 CPU 上运行的 ANNs,以下备选方案非常有用:
-
在本地 GPU 上运行笔记本。
-
在 Kaggle Kernels 或 Google Colaboratory 上运行笔记本。
-
使用亚马逊网络服务。
GPU
GPU 由数百个核心组成,可以同时处理数千个线程。使用 GPU 可以加速运行 ANN 和深度学习模型。
GPU 特别擅长处理复杂的矩阵运算。GPU 核心高度专业化,并通过将处理从 CPU 转移到 GPU 子系统中的核心来大幅加速深度学习训练等过程。
所有与机器学习相关的 Python 包,包括 Tensorflow、Theano 和 Keras,都可以配置为使用 GPU。
云服务,如 Kaggle 和 Google Colab
如果您有启用 GPU 的计算机,可以在本地运行 ANNs。如果没有,我们建议您使用 Kaggle Kernels、Google Colab 或 AWS 等服务:
Kaggle
由 Google 拥有的一个流行的数据科学网站,托管 Jupyter 服务,也称为Kaggle Kernels。Kaggle Kernels 可免费使用,并预先安装了最常用的包。您可以将内核连接到托管在 Kaggle 上的任何数据集,或者您也可以随时上传新的数据集。
Google Colaboratory
由 Google 提供的免费 Jupyter Notebook 环境,您可以使用免费的 GPU。Google Colaboratory的功能与 Kaggle 相同。
亚马逊网络服务(AWS)
AWS 深度学习提供了一个基础设施,可以在云中加速深度学习,无论规模大小。您可以快速启动预先安装了流行深度学习框架和接口的 AWS 服务器实例,用于训练复杂的自定义 AI 模型,尝试新算法,或学习新技能和技术。这些 Web 服务器可以比 Kaggle Kernels 运行更长时间。因此,对于大型项目,使用 AWS 而不是内核可能更值得。
章节总结
ANNs 是一类用于各种类型的机器学习的算法。这些模型受生物神经网络启发,包含构成动物大脑的神经元和神经元层。具有许多层的 ANN 称为深度神经网络。训练这些 ANN 需要几个步骤,包括前向传播和反向传播。诸如 Keras 之类的 Python 包可以让这些 ANN 的训练在几行代码内完成。训练这些深度神经网络需要更多的计算能力,仅靠 CPU 可能不够。备选方案包括使用 GPU 或云服务,如 Kaggle Kernels、Google Colaboratory 或 Amazon Web Services 来训练深度神经网络。
下一步
作为下一步,我们将深入探讨监督学习的机器学习概念的详细内容,然后进行使用本章涵盖的概念的案例研究。
¹ 读者被鼓励参考由 Aaron Courville、Ian Goodfellow 和 Yoshua Bengio(MIT Press)合著的书籍*《深度学习》*,以获取有关 ANN 和深度学习的更多细节。
² 激活函数将在本章后面详细描述。
³ 下一节讨论了许多可用的损失函数。我们问题的性质决定了我们对损失函数的选择。
⁴ 通过改变输出层的激活函数来导出回归或分类输出在第四章中进一步描述。
⁵ 有关优化的更多细节,请参阅https://oreil.ly/FSt-8。
⁶ 使用 Keras 实现深度学习模型的步骤和 Python 代码,如本节所示,在后续章节中的几个案例研究中使用。
⁷ 分类模型的评估指标的详细讨论在第四章中呈现。
第二部分:监督学习
第四章:监督学习:模型与概念
监督学习是机器学习的一个领域,选择的算法试图使用给定的输入来拟合目标。算法提供了包含标签的训练数据集。基于大量数据,算法将学习一条规则,用于预测新观察值的标签。换句话说,监督学习算法基于历史数据,并试图找到具有最佳预测能力的关系。
有两种类型的监督学习算法:回归算法和分类算法。基于回归的监督学习方法试图根据输入变量预测输出。基于分类的监督学习方法确定数据项属于哪个类别。分类算法是基于概率的,意味着算法找到数据集属于哪个类别的概率最高,就会输出该类别。相反,回归算法估计具有无限解(可能结果的连续集)的问题的结果。
在金融领域,监督学习模型代表了最常用的机器学习模型之一。许多在算法交易中广泛应用的算法依赖于监督学习模型,因为它们可以高效训练,相对稳健地处理嘈杂的金融数据,并且与金融理论有着密切联系。
学术界和行业研究人员已经利用基于回归的算法开发了许多资产定价模型。这些模型用于预测各种时间段的回报,并识别影响资产回报的重要因素。在投资组合管理和衍生品定价中还有许多其他基于回归的监督学习的用例。
另一方面,基于分类的算法已经在金融领域的许多领域中得到应用,这些领域需要预测分类响应。这些包括欺诈检测、违约预测、信用评分、资产价格运动方向的预测以及买入/卖出建议。在投资组合管理和算法交易中还有许多其他基于分类的监督学习的用例。
在第五章和第六章中介绍了基于回归和分类的监督学习的许多用例。
Python 及其库提供了在几行代码中实现这些监督学习模型的方法和方式。这些库中的一些在第二章中有详细介绍。借助易于使用的机器学习库,如 Scikit-learn 和 Keras,可以简单地对给定的预测建模数据集拟合不同的机器学习模型。
在本章中,我们提供了监督学习模型的高级概述。有关这些主题的全面覆盖,请参阅 Aurélien Géron 的《使用 Scikit-Learn、Keras 和 TensorFlow 进行实战机器学习》,第 2 版(O'Reilly)。
监督学习模型:概述
分类预测建模问题与回归预测建模问题有所不同,因为分类是预测离散类别标签的任务,而回归是预测连续量的任务。然而,两者共享利用已知变量进行预测的概念,并且在两种模型之间存在显著的重叠。因此,分类和回归模型在本章中一起介绍。图 4-1 总结了用于分类和回归的常用模型列表。
一些模型可以通过小的修改同时用于分类和回归。这些模型包括 K 近邻、决策树、支持向量机、集成装袋/提升方法以及人工神经网络(包括深度神经网络),如图 4-1 所示。然而,一些模型,如线性回归和逻辑回归,不能(或者不容易)同时用于两种问题类型。
图 4-1. 回归和分类模型
本节包含以下有关模型的详细信息:
-
模型理论。
-
在 Scikit-learn 或 Keras 中的实现。
-
不同模型的网格搜索。
-
模型的优缺点。
注意
在金融领域,重点放在从先前观察到的数据中提取信号以预测同一时间序列的未来值的模型上。这类时间序列模型预测连续输出,并且更符合监督回归模型的特性。时间序列模型在监督回归章节中单独进行讨论(第五章)。
线性回归(普通最小二乘法)
线性回归(普通最小二乘回归或 OLS 回归)或许是统计学和机器学习中最为知名且理解最透彻的算法之一。线性回归是一个线性模型,例如,它假设输入变量 (x) 和单一输出变量 (y) 之间存在线性关系。线性回归的目标是训练一个线性模型,以尽可能小的误差来预测新的 y 给定先前未见的 x。
我们的模型将是一个函数,其预测 y 给定 x 1 , x 2 . . . x i :
y = β 0 + β 1 x 1 + . . . + β i x i
其中,β 0 被称为截距,β 1 . . . β i 是回归系数。
Python 中的实现
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X, Y)
在接下来的部分中,我们涵盖了线性回归模型的训练和模型的网格搜索。然而,总体概念和相关方法适用于所有其他监督学习模型。
训练模型
正如我们在第三章中提到的,训练模型基本上意味着通过最小化成本(损失)函数来检索模型参数。训练线性回归模型的两个步骤是:
定义成本函数(或损失函数)
衡量模型预测的不准确性。如方程 4-1 中定义的残差平方和(RSS),衡量实际值与预测值之间差异的平方和,是线性回归的成本函数。
方程 4-1. 残差平方和
R S S = ∑ i=1 n y i – β 0 – ∑ j=1 n β j x ij 2
在这个方程中,β 0 是截距;β j 代表系数;β 1 , . . , β j 是回归的系数;x ij 表示第i th观测和第j th变量。
找到最小化损失的参数
例如,使我们的模型尽可能准确。在二维图中,这会导致最佳拟合线,如图 4-2 所示。在更高维度中,我们将会有更高维的超平面。从数学角度来看,我们关注每个真实数据点(y)与我们模型预测(ŷ)之间的差异。平方这些差异以避免负数并惩罚较大的差异,然后将它们相加并取平均值。这衡量了我们的数据与拟合线的拟合程度。
图 4-2. 线性回归
网格搜索
网格搜索的总体思想是创建所有可能的超参数组合的网格,并使用每个组合来训练模型。超参数是模型的外部特征,可以被视为模型的设置,不像模型参数那样基于数据估计。这些超参数在网格搜索过程中被调整以实现更好的模型性能。
由于其穷举搜索,网格搜索保证在网格内找到最优参数。缺点是随着参数或考虑值的增加,网格的大小呈指数增长。
sklearn 软件包的model_selection模块中的GridSearchCV类有助于系统地评估我们希望测试的所有超参数值的组合。
第一步是创建一个模型对象。然后我们定义一个字典,其中关键字命名超参数,值列表显示要测试的参数设置。对于线性回归,超参数是fit_intercept,它是一个布尔变量,确定是否计算此模型的截距。如果设置为False,计算中将不使用截距:
model = LinearRegression()
param_grid = {'fit_intercept': [True, False]}
}
第二步是实例化GridSearchCV对象,并提供评估器对象和参数网格,以及评分方法和交叉验证选择给初始化方法。交叉验证是一种用于评估机器学习模型的重采样过程,评分参数是模型的评估指标:¹
在所有设置就位后,我们可以拟合GridSearchCV:
grid = GridSearchCV(estimator=model, param_grid=param_grid, scoring= 'r2', \
cv=kfold)
grid_result = grid.fit(X, Y)
优点和缺点
在优点方面,线性回归易于理解和解释。然而,当预测变量与预测变量之间存在非线性关系时,它可能效果不佳。线性回归容易出现过拟合(我们将在下一节讨论)问题,而且当存在大量特征时,可能无法很好地处理不相关的特征。线性回归还要求数据遵循某些假设,如不存在多重共线性。如果假设不成立,则无法信任所得到的结果。
正则化回归
当线性回归模型包含许多自变量时,它们的系数将难以确定,模型将倾向于非常适合训练数据(用于构建模型的数据),但对测试数据(用于测试模型好坏的数据)适配不佳。这被称为过拟合或高方差。
控制过拟合的一种流行技术是正则化,它涉及向误差或损失函数添加一个惩罚项,以防止系数达到较大值。简单来说,正则化是一种惩罚机制,通过收缩模型参数(使其接近于零)来建立预测精度更高且易于解释的模型。正则化回归比线性回归有两个优点:
预测精度
模型在测试数据上的表现更好表明,模型试图从训练数据中概括。具有过多参数的模型可能尝试拟合特定于训练数据的噪声。通过收缩或将一些系数设为零,我们权衡了适合复杂模型(更高偏差)的能力,以换取更具泛化能力的模型(更低方差)。
解释
大量预测子可能会复杂化结果的解释或传达大局。为了限制模型仅包括对结果影响最大的一小部分参数,可能需要牺牲一些细节。
正则化线性回归模型的常见方法如下:
L1 正则化或 Lasso 回归
Lasso 回归 通过在线性回归的成本函数(RSS)中添加系数绝对值之和的因素(如 Equation 4-1 所述)执行 L1 正则化。Lasso 正则化的方程可以表示如下:
C o s t F u n c t i o n = R S S + λ * ∑ j=1 p β j
L1 正则化可以导致零系数(即某些特征在输出评估中被完全忽略)。λ 值越大,被收缩至零的特征越多。这可以完全消除一些特征,并给出预测子集,从而降低模型复杂度。因此,Lasso 回归不仅有助于减少过拟合,还可以帮助进行特征选择。未收缩至零的预测子集表明它们很重要,因此 L1 正则化允许进行特征选择(稀疏选择)。正则化参数( λ )可控制,lambda 值为零时产生基本线性回归方程。
可以使用 Python 的 sklearn 包中的 Lasso 类构建 Lasso 回归模型,如下所示的代码片段:
from sklearn.linear_model import Lasso
model = Lasso()
model.fit(X, Y)
L2 正则化或 Ridge 回归
Ridge 回归 通过在线性回归的成本函数(RSS)中添加系数平方和的因素执行 L2 正则化(如 Equation 4-1 所述)。Ridge 正则化的方程可以表示如下:
C o s t F u n c t i o n = R S S + λ * ∑ j=1 p β j 2
岭回归对系数施加了约束。惩罚项( λ )正则化系数,如果系数取大值,则优化函数受到惩罚。因此,岭回归会收缩系数并有助于降低模型复杂度。收缩系数会导致较低的方差和较低的误差值。因此,岭回归减少了模型的复杂度,但并不减少变量的数量;它只是缩小它们的影响。当 λ 接近零时,成本函数变得类似于线性回归成本函数。因此,对于特征的约束越低(低 λ ),模型越类似于线性回归模型。
可以使用 Python 的 sklearn 包中的 Ridge 类构建岭回归模型,如下面的代码片段所示:
from sklearn.linear_model import Ridge
model = Ridge()
model.fit(X, Y)
弹性网络
弹性网络 向模型添加了正则化项,这是 L1 和 L2 正则化的组合,如下方程所示:
C o s t F u n c t i o n = R S S + λ (1–α) / 2 ∑ j=1 p β j 2 + α * ∑ j=1 p β j
除了设置和选择 λ 值外,弹性网还允许我们调整 alpha 参数,其中 α = 0 对应于岭回归,α = 1 对应于拉索。因此,我们可以选择一个介于 0 和 1 之间的 α 值来优化弹性网。这将有效地收缩一些系数并将一些系数设置为 0 以进行稀疏选择。
可以使用 Python 的 sklearn 包中的 ElasticNet 类构建弹性网络回归模型,如下面的代码片段所示:
from sklearn.linear_model import ElasticNet
model = ElasticNet()
model.fit(X, Y)
对于所有正则化回归,在 Python 的网格搜索期间调整的关键参数是 λ 。在弹性网中,α 可以是一个额外的可调参数。
逻辑回归
逻辑回归 是最广泛使用的分类算法之一。逻辑回归模型出现的原因是希望在 x 的线性函数中建模输出类的概率,同时确保输出概率总和为一,并且保持在零到一之间,这是我们从概率中期望的结果。
如果我们在几个示例上训练线性回归模型,其中 Y = 0 或 1,我们可能会预测出一些小于零或大于一的概率,这是不合理的。相反,我们使用逻辑回归模型(或 logit 模型),这是线性回归的修改版,通过应用 sigmoid 函数确保输出的概率在零到一之间。²
方程 4-2 展示了逻辑回归模型的方程式。类似于线性回归,输入值(x)通过权重或系数值线性组合以预测输出值(y)。从方程 4-2 得到的输出是一个概率,被转换成二进制值(0或1)以获取模型预测。
方程 4-2. 逻辑回归方程
y = exp(β 0 +β 1 x 1 +....+β i x 1 ) 1+exp(β 0 +β 1 x 1 +....+β i x 1 )
其中y是预测输出,β 0是偏置或截距项,而 B[1]是单个输入值(x)的系数。输入数据中的每一列都有一个关联的β系数(一个常数实数值),必须从训练数据中学习。
在逻辑回归中,成本函数基本上是衡量我们在真实答案为零时多少次预测为一,反之亦然。训练逻辑回归系数使用诸如最大似然估计(MLE)的技术,以预测接近1的默认类别值和接近0的其他类别值。³
可以使用 Python 的 sklearn 包的LogisticRegression类构建逻辑回归模型,如下代码片段所示:
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X, Y)
超参数
正则化(penalty在 sklearn 中)
类似于线性回归,逻辑回归可以进行正则化,可以是L1、L2或elasticnet。在sklearn库中的取值为[l1, l2, elasticnet]。
正则化强度(C在 sklearn 中)
此参数控制正则化强度。想要的惩罚参数的好值可以是*[100, 10, 1.0, 0.1, 0.01]*。
优缺点
就优点而言,逻辑回归模型易于实现,具有良好的解释性,并且在线性可分的类别上表现非常好。模型的输出是概率,提供更多的见解并可用于排名。该模型具有少量的超参数。虽然可能存在过拟合的风险,但可以通过类似于线性回归模型的L1/L2正则化来解决这个问题。
在缺点方面,当提供大量特征时,模型可能会过拟合。逻辑回归只能学习线性函数,并且不太适合处理特征与目标变量之间的复杂关系。此外,如果特征强相关,可能无法很好地处理无关特征。
支持向量机
支持向量机(SVM)算法的目标是最大化边界(如图 4-3 中的阴影区域所示),即分隔超平面(或决策边界)与最接近该超平面的训练样本之间的距离,即所谓的支持向量。边界计算为从线到仅最接近点的垂直距离,如图 4-3 所示。因此,SVM 计算出导致所有数据点均匀分区的最大间隔边界。
图 4-3. 支持向量机
在实践中,数据杂乱无章,并且不能使用超平面完美分离。必须放宽最大化分隔类别的线条的约束。此变更允许训练数据中的一些点违反分隔线。引入了一组额外的系数,这些系数在每个维度中提供间隙余地。引入了一个调整参数,简称为C,它定义了允许跨所有维度的摆动幅度。C 的值越大,允许的超平面违规就越多。
在某些情况下,无法找到超平面或线性决策边界,因此使用内核。内核只是输入数据的转换,允许 SVM 算法更轻松地处理数据。使用内核,原始数据被投影到更高的维度以更好地分类数据。
SVM 用于分类和回归。我们通过将原始优化问题转换为对偶问题来实现这一点。对于回归,技巧在于颠倒目标。在试图在两个类之间拟合尽可能大的街道同时限制边界违规时,SVM 回归试图在街道上(图 4-3 中阴影区域)尽可能多地拟合实例,同时限制边界违规。街道的宽度由超参数控制。
SVM 回归和分类模型可以使用 Python 的 sklearn 包构建,如下面的代码片段所示:
回归
from sklearn.svm import SVR
model = SVR()
model.fit(X, Y)
分类
from sklearn.svm import SVC
model = SVC()
model.fit(X, Y)
超参数
在 sklearn 实现的 SVM 中存在以下关键参数,并可在执行网格搜索时进行调整:
内核(sklearn 中的 kernel)
内核的选择控制输入变量将被投影的方式。有许多内核可供选择,但线性和RBF是最常见的。
惩罚(sklearn 中的 C)
惩罚参数告诉 SVM 优化希望避免每个训练样本的错误分类程度。对于惩罚参数的大值,优化会选择一个较小间隔的超平面。良好的值可能在对数尺度从 10 到 1,000 之间。
优缺点
就优点而言,SVM 对过拟合相当鲁棒,特别是在高维空间中。它能够很好地处理非线性关系,提供多种核函数选择。此外,对数据没有分布要求。
就缺点而言,SVM 在训练时可能效率低且内存占用高,并且调整困难。它在处理大型数据集时表现不佳。它要求对数据进行特征缩放。还有许多超参数,它们的含义通常不直观。
K-最近邻算法
K-最近邻(KNN)被认为是一种“惰性学习器”,因为模型不需要学习。对于新数据点,预测是通过在整个训练集中搜索K个最相似的实例(邻居),并总结这些K个实例的输出变量来实现的。
为了确定训练数据集中与新输入最相似的K个实例,使用了一个距离度量。最流行的距离度量是欧几里得距离,其计算方法是在所有输入属性i上,点a和点b之间的平方差的平方根,表示为 d ( a , b ) = ∑ i=1 n (a i –b i ) 2 。欧几里得距离在输入变量类型相似时是一种很好的距离度量。
另一种距离度量是曼哈顿距离,其中点a和点b之间的距离表示为 d ( a , b ) = ∑ i=1 n | a i – b i | 。曼哈顿距离在输入变量类型不相似时是一种很好的度量。
KNN 的步骤可以总结如下:
-
选择K的数量和距离度量。
-
找到我们要分类的样本的K个最近邻居。
-
通过多数投票分配类别标签。
可以使用 Python 的 sklearn 包构建 KNN 回归和分类模型,如下所示:
分类
from sklearn.neighbors import KNeighborsClassifier
model = KNeighborsClassifier()
model.fit(X, Y)
回归
from sklearn.neighbors import KNeighborsRegressor
model = KNeighborsRegressor()
model.fit(X, Y)
超参数
在 sklearn 实现的 KNN 中存在以下关键参数,可以在执行网格搜索时调整:
邻居数(sklearn 中的n_neighbors)
KNN 最重要的超参数是邻居数(n_neighbors)。良好的值在 1 到 20 之间。
距离度量(在 sklearn 中称为metric)
测试不同距离度量来选择邻域组成可能也会很有趣。良好的值为euclidean和manhattan。
优缺点
在优点方面,无需训练,因此没有学习阶段。由于算法在进行预测之前不需要训练,因此可以轻松添加新数据而不影响算法的准确性。它直观且易于理解。该模型自然处理多类别分类,并能学习复杂的决策边界。如果训练数据量大,则 KNN 非常有效。它还对噪声数据具有鲁棒性,无需过滤异常值。
在缺点方面,选择距离度量并不明显,很难在许多情况下进行证明。KNN 在高维数据集上表现不佳。预测新实例的成本高且速度慢,因为必须重新计算到所有邻居的距离。KNN 对数据集中的噪声敏感。我们需要手动输入缺失值并移除异常值。此外,在应用 KNN 算法之前需要进行特征缩放(标准化和归一化),否则 KNN 可能会生成错误的预测。
线性判别分析
线性判别分析(LDA)算法的目标是以一种方式将数据投影到低维空间,使得类别的可分离性最大化,类内方差最小化。⁴
在训练 LDA 模型期间,会计算每个类别的统计特性(即均值和协方差矩阵)。这些统计特性是基于以下关于数据的假设进行估计的:
-
数据是normally distributed,因此每个变量在绘制时都呈钟形曲线。
-
每个属性具有相同的方差,并且每个变量的值平均围绕均值变化相同量。
要进行预测,LDA 估计新输入数据属于每个类别的概率。输出类别是具有最高概率的类别。
Python 中的实现及超参数
可以使用 Python 的 sklearn 包构建 LDA 分类模型,如下面的代码片段所示:
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
model = LinearDiscriminantAnalysis()
model.fit(X, Y)
LDA 模型的关键超参数是number of components,用于降维,而在 sklearn 中表示为n_components。
优缺点
在优点方面,LDA 是一个相对简单的模型,实现快速且易于实现。在缺点方面,它需要特征缩放并涉及复杂的矩阵操作。
分类和回归树
从最一般的角度来看,通过树构建算法进行分析的目的是确定一组if–then逻辑(分裂)条件,以便准确预测或分类案例。分类与回归树(或CART或决策树分类器)是具有吸引力的模型,如果我们关心解释性的话。我们可以将这个模型视为分解数据并基于一系列问题做出决策的过程。这种算法是随机森林和梯度提升方法等集成方法的基础。
表示
该模型可以通过二叉树(或决策树)来表示,其中每个节点是一个输入变量 x,带有一个分割点,每个叶子包含用于预测的输出变量 y。
图 4-4 展示了一个简单分类树的示例,根据身高(以厘米为单位)和体重(以公斤为单位)两个输入预测一个人是男性还是女性。
图 4-4. 分类与回归树示例
学习 CART 模型
创建一个二叉树实际上是一个将输入空间分割的过程。采用一种称为递归二元分割的贪婪方法来分割空间。这是一个数值过程,在此过程中,所有值都被排列,并尝试使用成本(损失)函数测试不同的分割点。选择具有最佳成本(因为我们最小化成本)的分割点。所有输入变量和所有可能的分割点都以贪婪的方式进行评估和选择(例如,每次都选择最佳分割点)。
对于回归预测建模问题,用于选择分裂点的成本函数是在所有落入矩形内的训练样本上最小化的平方误差和:
∑ i=1 n (y i –prediction i ) 2
其中y i是训练样本的输出,prediction 是矩形的预测输出。对于分类问题,使用基尼成本函数;它提供了叶子节点纯度的指示(即分配给每个节点的训练数据的混合程度),并定义为:
G = ∑ i=1 n p k * ( 1 – p k )
其中G是兴趣区域矩形中所有类的基尼成本,p k是具有类k的训练实例数量。具有完全类纯度(完美类纯度)的节点将具有G = 0,而在二元分类问题中具有50-50类分布(最差纯度)的节点将具有G = 0.5。
停止准则
在前面的部分描述的递归二元分裂过程中,需要知道何时停止分裂,因为它在训练数据中沿着树的路径工作。最常见的停止程序是在每个叶节点分配的训练实例数达到最小值时停止。如果计数少于某个最小值,则不接受分裂,并将节点视为最终叶节点。
修剪树
停止准则非常重要,因为它强烈影响树的性能。学习树后可以使用修剪来进一步提升性能。决策树的复杂性定义为树中的分裂数。更简单的树更受欢迎,因为它们运行更快,易于理解,在处理和存储过程中消耗更少的内存,并且不太可能过度拟合数据。最快和最简单的修剪方法是通过测试集逐个处理树中的每个叶节点,并评估移除它的效果。仅当这样做会导致整个测试集上成本函数的下降时才移除叶节点。当不能进一步改善时,可以停止删除节点。
Python 实现
使用 Python 的 sklearn 包可以构建 CART 回归和分类模型,如下面的代码片段所示:
分类
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier()
model.fit(X, Y)
回归
from sklearn.tree import DecisionTreeRegressor
model = DecisionTreeRegressor ()
model.fit(X, Y)
超参数
CART 有许多超参数。然而,关键的超参数是树模型的最大深度,这是降维的组件数量,用max_depth在 sklearn 包中表示。好的取值范围可以从2到30,具体取决于数据中的特征数量。
优缺点
在优点方面,CART 易于解释并能够适应学习复杂关系。它需要很少的数据准备工作,通常不需要缩放数据。由于决策节点的构建方式,特征重要性是内置的。它在大型数据集上表现良好。它适用于回归和分类问题。
在缺点方面,除非使用修剪,否则 CART 易于过拟合。它可能非常不稳健,意味着训练数据集的小变化可能导致所学习的假设函数存在较大差异。通常情况下,CART 的性能不如下面将要讨论的集成模型。
集成模型
集成模型的目标是将不同的分类器组合成一个元分类器,其泛化性能优于单个分类器。例如,假设我们从 10 位专家收集了预测结果,集成方法允许我们策略性地结合他们的预测,得到比专家个体预测更准确和更稳健的预测。
最流行的两种集成方法是装袋(bagging)和提升(boosting)。装袋(或自举聚合)是一种并行训练多个独立模型的集成技术。每个模型由数据的随机子集训练。提升则是一种串行训练多个独立模型的集成技术。通过从训练数据构建一个模型,然后创建第二个模型来纠正第一个模型的错误。模型逐步添加,直到训练集被完美预测或者达到最大模型数量。每个独立模型从前一个模型的错误中学习。就像决策树本身一样,装袋和提升可用于分类和回归问题。
通过结合独立模型,集成模型更加灵活(偏差较小)且对数据不敏感(方差较小)。⁵ 集成方法结合多个简单算法以获得更好的性能。
在本节中,我们将涵盖随机森林、AdaBoost、梯度提升方法和额外树,以及它们在 sklearn 包中的实现。
随机森林
随机森林是装袋决策树的调整版本。为了理解随机森林算法,首先了解装袋算法。假设我们有一个包含一千个实例的数据集,装袋的步骤如下:
-
创建许多(例如一百个)数据集的随机子样本。
-
对每个样本训练一个 CART 模型。
-
给定一个新数据集,计算每个模型的平均预测,并通过每棵树的预测结果进行多数投票来确定最终标签。
像 CART 这样的决策树存在一个问题,即它们是贪婪的。它们通过最小化误差的贪婪算法选择分裂变量。即使在装袋之后,决策树可能具有很多结构相似性,并导致其预测高度相关。如果子模型的预测相互不相关,或者最好是弱相关,那么从多个模型的预测中组合预测将效果更好。随机森林通过改变学习算法的方式,使得所有子树的预测结果相关性更低。
在 CART 中,选择分裂点时,学习算法允许查看所有变量和所有变量值,以选择最优的分裂点。随机森林算法改变了这个过程,使得每个子树在选择分裂点时只能访问一部分随机抽取的特征。在算法中必须指定一个参数来表示每个分裂点可以搜索的特征数量(m)。
当构建装袋决策树时,我们可以计算每个分裂点的变量的误差函数降低量。在回归问题中,这可能是总平方误差的减少量,在分类问题中,可能是基尼成本。装袋方法可以通过计算并平均单个变量的误差函数降低量来提供特征重要性。
Python 实现
可使用 Python 的 sklearn 包构建随机森林回归和分类模型,如下所示的代码:
分类
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(X, Y)
回归
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor()
model.fit(X, Y)
超参数
sklearn 实现的随机森林中存在一些主要的超参数,可以在执行网格搜索时进行调整。
最大特征数(max_features在 sklearn 中)
这是最重要的参数。它是在每个分裂点随机抽取的特征数量。您可以尝试一系列整数值,例如从 1 到 20,或从 1 到输入特征数量的一半。
树的数量(n_estimators在 sklearn 中)
此参数代表树的数量。理想情况下,应该增加此数量,直到模型不再显示进一步改善为止。良好的值可能在对数尺度从 10 到 1,000 之间。
优缺点
随机森林算法(或模型)由于其良好的性能、可扩展性和易用性,在过去十年中在机器学习应用中获得了巨大的流行。它灵活,并自然地分配特征重要性分数,因此可以处理冗余的特征列。它适用于大型数据集,并且通常对过拟合具有较强的鲁棒性。该算法不需要对数据进行缩放,并且可以建模非线性关系。
在缺点方面,随机森林可能感觉像一个黑盒方法,因为我们对模型的操作非常有限,结果可能难以解释。虽然随机森林在分类方面表现良好,但对于回归问题可能不太适用,因为它无法给出精确的连续性预测。在回归情况下,它不会预测超出训练数据范围,并可能在特别嘈杂的数据集上过拟合。
极端随机树(Extra trees)
Extra trees,又称极端随机树,是随机森林的一个变种;它构建多棵树,并使用特征的随机子集来分裂节点,类似于随机森林。然而,与随机森林不同的是,在 extra trees 中,观测样本是不重复抽取的。因此,观测样本不会重复出现。
此外,随机森林选择最佳分裂点将父节点转换为两个最同质的子节点。⁶ 然而,extra trees 选择一个随机分裂来将父节点分割为两个随机子节点。在 extra trees 中,随机性不是来自于数据的自助抽样,而是来自于所有观测样本的随机分割。
在实际案例中,性能与普通随机森林可比,有时稍好。额外树的优缺点与随机森林类似。
Python 实现
可以使用 Python 的 sklearn 包构建 Extra trees 的回归和分类模型,如下面的代码片段所示。Extra trees 的超参数与随机森林相似,如前一节所示:
分类
from sklearn.ensemble import ExtraTreesClassifier
model = ExtraTreesClassifier()
model.fit(X, Y)
回归
from sklearn.ensemble import ExtraTreesRegressor
model = ExtraTreesRegressor()
model.fit(X, Y)
自适应增强(AdaBoost)
自适应增强或AdaBoost是一种提升技术,其基本思想是依次尝试预测器,每个后续模型试图修正其前任的错误。每次迭代中,AdaBoost 算法通过修改附加到每个实例的权重来改变样本分布。它增加错误预测实例的权重,减少正确预测实例的权重。
AdaBoost 算法的步骤如下:
-
最初,所有观测样本被赋予相等的权重。
-
模型建立在数据子集上,使用该模型对整个数据集进行预测。通过比较预测值和实际值来计算错误。
-
在创建下一个模型时,对预测错误的数据点赋予更高的权重。可以使用错误值确定权重。例如,错误越大,分配给观察值的权重越大。
-
该过程重复进行,直到错误函数不再改变,或者达到最大估计器数量的限制。
Python 实现
可以使用 Python 的 sklearn 包构建 AdaBoost 的回归和分类模型,如下面的代码片段所示:
分类
from sklearn.ensemble import AdaBoostClassifier
model = AdaBoostClassifier()
model.fit(X, Y)
回归
from sklearn.ensemble import AdaBoostRegressor
model = AdaBoostRegressor()
model.fit(X, Y)
超参数
sklearn 实现的 AdaBoost 中的一些主要超参数,在执行网格搜索时可以进行调整,包括以下内容:
学习率 (learning_rate 在 sklearn 中)
学习率缩小每个分类器/回归器的贡献。可以考虑在对数尺度上。网格搜索的样本值可以是 0.001、0.01 和 0.1。
估计器数量 (n_estimators 在 sklearn 中)
此参数表示树的数量。理想情况下,应该增加到在模型中不再看到进一步改进的情况下。良好的值可能是从 10 到 1,000 的对数尺度。
优势和劣势
在优势方面,AdaBoost 具有较高的精度。AdaBoost 可以在几乎不调整参数或设置的情况下达到与其他模型类似的结果。该算法不需要数据进行缩放,并且可以建模非线性关系。
在劣势方面,AdaBoost 的训练时间较长。AdaBoost 对噪声数据和异常值敏感,并且数据不平衡导致分类精度降低。
梯度提升方法
梯度提升方法(GBM)是另一种类似于 AdaBoost 的提升技术,其一般思想是顺序地尝试预测器。梯度提升通过将前一步骤中未拟合的预测逐步添加到集成中来工作,确保先前的错误得到纠正。
梯度提升算法的步骤如下:
-
在一个数据子集上构建模型(可以称为第一个弱学习器)。使用该模型,在整个数据集上进行预测。
-
通过比较预测值和实际值计算错误,并使用损失函数计算损失。
-
使用前一步骤的错误作为目标变量创建一个新模型。其目标是找到数据中的最佳分割以最小化误差。该新模型的预测值与前一模型的预测值相结合。使用此预测值和实际值计算新的错误。
-
直到错误函数不再变化或达到最大估计器数的限制为止,重复此过程。
与 AdaBoost 相反,后者在每次交互中调整实例权重,该方法试图将新的预测器拟合到前一个预测器产生的残差错误中。
Python 中的实现和超参数
使用 Python 的 sklearn 包可以构建梯度提升方法的回归和分类模型,如下面的代码片段所示。梯度提升方法的超参数与 AdaBoost 相似,如前一节所示:
分类
from sklearn.ensemble import GradientBoostingClassifier
model = GradientBoostingClassifier()
model.fit(X, Y)
回归
from sklearn.ensemble import GradientBoostingRegressor
model = GradientBoostingRegressor()
model.fit(X, Y)
优势和劣势
在优势方面,梯度提升方法对于缺失数据、高度相关的特征和无关特征具有鲁棒性,与随机森林相似。它自然地分配特征重要性分数,稍微优于随机森林的性能。该算法不需要数据进行缩放,并且可以建模非线性关系。
在劣势方面,可能比随机森林更容易过拟合,因为提升方法的主要目的是减少偏差而不是方差。它有许多超参数需要调整,因此模型开发可能不那么迅速。此外,特征重要性可能对训练数据集的变化不太稳健。
基于 ANN 的模型
在第三章中,我们讨论了 ANN 的基础知识,以及 ANN 的架构及其在 Python 中的训练和实现。该章提供的细节适用于机器学习的所有领域,包括监督学习。然而,从监督学习的角度来看,还有一些额外的细节,我们将在本节中介绍。
神经网络可以通过输出层节点的激活函数减少到分类或回归模型。在回归问题中,输出节点具有线性激活函数(或无激活函数)。线性函数产生从-inf到+inf的连续输出。因此,输出层将是前一层节点的线性函数,并且它将是基于回归的模型。
在分类问题中,输出节点具有 sigmoid 或 softmax 激活函数。sigmoid 或 softmax 函数产生一个从零到一的输出,表示目标值的概率。softmax 函数还可以用于多组分类。
使用 sklearn 的 ANN
可以使用 Python 的 sklearn 包构建 ANN 回归和分类模型,如下面的代码片段所示:
分类
from sklearn.neural_network import MLPClassifier
model = MLPClassifier()
model.fit(X, Y)
回归
from sklearn.neural_network import MLPRegressor
model = MLPRegressor()
model.fit(X, Y)
超参数
正如我们在第三章中看到的,ANN 具有许多超参数。在 sklearn 的 ANN 实现中存在的一些超参数,在执行网格搜索时可以调整:
隐藏层(sklearn 中的hidden_layer_sizes)
它代表 ANN 架构中的层数和节点数。在 sklearn 的 ANN 实现中,第 i 个元素表示第 i 个隐藏层中的神经元数。在 sklearn 实现的网格搜索中,用于示例值的样本值可以是[(20,), (50,), (20, 20), (20, 30, 20)]。
激活函数(sklearn 中的activation)
它代表隐藏层的激活函数。一些在第三章中定义的激活函数,如sigmoid、relu或tanh,可以使用。
深度神经网络
具有多个隐藏层的人工神经网络通常被称为深度网络。我们喜欢使用库 Keras 来实现这样的网络,因为这个库非常灵活。详细介绍了在 Keras 中实现深度神经网络的具体实现。类似于MLPClassifier和MLPRegressor在 sklearn 中用于分类和回归,Keras 还有名为KerasClassifier和KerasRegressor的模块,可用于创建具有深度网络的分类和回归模型。
金融领域中一个流行的问题是时间序列预测,即基于历史概述预测时间序列的下一个值。一些深度神经网络,如循环神经网络(RNN),可以直接用于时间序列预测。该方法的详细信息在第五章中提供。
优缺点
人工神经网络(ANN)的主要优势在于它相当好地捕捉了变量之间的非线性关系。ANN 可以更轻松地学习丰富的表示,并且在大数据集和大量输入特征的情况下表现良好。ANN 在使用方式上非常灵活。这一点可以从其在机器学习和人工智能中广泛应用的各种领域中看出,包括强化学习和自然语言处理,正如第三章所讨论的那样。
ANN 的主要缺点是模型的可解释性,这是一个常常不能忽视的缺点,有时在选择模型时是决定性因素。ANN 在处理小数据集方面表现不佳,需要大量的调整和猜测。选择正确的拓扑结构/算法来解决问题是困难的。此外,ANN 在计算上很昂贵,训练所需时间较长。
在金融监督学习中使用人工神经网络
如果一个简单的模型(如线性或逻辑回归)完全适合您的问题,那么不要考虑使用 ANN。然而,如果您正在建模复杂的数据集并感觉需要更好的预测能力,那么试试 ANN 吧。ANN 是最灵活的模型之一,能够自适应数据的形状,在监督学习问题中使用它可能是一个有趣且有价值的练习。
模型性能
在前一节中,我们讨论了网格搜索作为寻找正确超参数以获得更好性能的方法。在本节中,我们将扩展该过程,讨论评估模型性能的关键组成部分,即过拟合、交叉验证和评估指标。
过拟合和欠拟合
机器学习中常见的问题是过拟合,它被定义为学习一个完美解释模型从中学到的训练数据的函数,但对未见过的测试数据泛化效果不佳。过拟合发生在模型从训练数据中过度学习,以至于开始捕捉到不代表真实世界模式的特质。随着我们的模型变得越来越复杂,这种问题变得尤为严重。欠拟合是一个相关问题,即模型不够复杂,无法捕捉数据中的潜在趋势。Figure 4-5 说明了过拟合和欠拟合。Figure 4-5 的左侧面板显示了一个线性回归模型;一条直线明显地对真实函数拟合不足。中间面板显示了高次多项式相对合理地近似了真实关系。另一方面,高次多项式几乎完美地适应了小样本,并且在训练数据上表现最好,但这种情况并不具有泛化性,并且在解释新数据点时效果非常糟糕。
过拟合和欠拟合的概念与偏差-方差权衡密切相关。偏差是由于学习算法中过于简化或错误的假设而导致的错误。偏差导致数据的拟合不足,如 Figure 4-5 的左侧面板所示。高偏差意味着我们的学习算法忽略了特征之间的重要趋势。方差是由于一个过于复杂的模型试图尽可能紧密地拟合训练数据而导致的错误。在高方差的情况下,模型的预测值与训练集中的实际值非常接近。高方差导致过拟合,如 Figure 4-5 的右侧面板所示。最终,为了得到一个好的模型,我们需要低偏差和低方差。
图 4-5. 过拟合和欠拟合
可以有两种方法来对抗过拟合:
使用更多的训练数据
我们拥有的训练数据越多,就越难通过从任一训练示例中学习过多来过拟合数据。
使用正则化
在损失函数中为建立模型增加一项惩罚,以使模型不会赋予任何一个特征过多的解释力量,或者允许考虑太多的特征。
过拟合的概念及其对策适用于所有监督学习模型。例如,正则化回归可以解决线性回归中的过拟合问题,正如本章前面讨论的那样。
交叉验证
机器学习面临的挑战之一是训练能够很好地泛化到未见数据的模型(过拟合与欠拟合或偏差-方差权衡)。交叉验证的主要思想是将数据一次或多次分割,以便每次分割都将一个部分作为验证集,其余部分作为训练集:数据的一部分(训练样本)用于训练算法,剩余部分(验证样本)用于估计算法的风险。交叉验证允许我们获得模型泛化误差的可靠估计。通过一个例子最容易理解它。在进行k折交叉验证时,我们将训练数据随机分成k折。然后我们使用k-1折训练模型,并在第k折上评估性能。我们重复这个过程k次,并平均得分。
Figure 4-6 显示了一个交叉验证的示例,其中数据被分成五组,在每一轮中,其中一个组被用作验证集。
图 4-6. 交叉验证
交叉验证的一个潜在缺点是计算成本,特别是与超参数调整的网格搜索结合时。使用 sklearn 包可以在几行代码中执行交叉验证;我们将在监督学习案例研究中执行交叉验证。
在下一节中,我们将介绍用于测量和比较模型性能的监督学习模型的评估指标。
评估指标
评估机器学习算法使用的指标非常重要。选择使用的指标影响着如何衡量和比较机器学习算法的性能。这些指标影响您如何权衡结果中不同特征的重要性,以及最终选择的算法。
回归和分类的主要评估指标在 Figure 4-7 中有所说明。
图 4-7. 回归和分类的评估指标
让我们首先看一下监督回归的评估指标。
平均绝对误差
平均绝对误差(MAE)是预测值与实际值之间绝对差值的总和。MAE 是线性评分,这意味着平均值中所有个体差异的权重相等。它提供了预测有多大错误的想法。该指标给出了误差的大小,但不指示方向(例如,过高或过低预测)。
均方误差
均方误差(MSE)表示预测值与观测值(称为残差)之间差异的样本标准偏差。这与平均绝对误差类似,提供了误差大小的大致概念。将均方误差的平方根取出,可以将单位转换回输出变量的原始单位,并且对描述和展示有意义。这被称为均方根误差(RMSE)。
R²指标
R²指标提供了预测与实际值“拟合度”的指示。在统计文献中,这个度量被称为决定系数。它的值介于零和一之间,分别表示无拟合和完美拟合。
调整后的 R²指标
像R²一样,调整后的 R²也显示了项在曲线或直线上拟合的程度,但会根据模型中的项数进行调整。其表达式如下:
R adj 2 = 1 – (1–R 2 )(n–1)) n–k–1
其中n为总观测数,k为预测变量数。调整后的R²永远小于或等于R²。
选择监督回归的评估指标
在这些评估指标中,如果主要目标是预测准确性,则 RMSE 是最好的选择。它计算简单,易于区分。损失对称,但较大误差在计算中权重更大。MAE 对称,但不会给较大误差加权。R²和调整后的R²通常用于解释目的,指示选择的独立变量如何解释因变量的变异性。
让我们首先看看监督分类的评估指标。
分类
为简便起见,我们将大多数讨论限于二元分类问题(例如,仅有两个结果,如真或假);一些常见术语包括:
真阳性(TP)
预测为正实际为正。
假阳性(FP)
预测为正实际为负。
真阴性(TN)
预测为负实际为负。
假阴性(FN)
预测为负实际为正。
展示了分类常用的三个评估指标——准确率、精确率和召回率——之间的区别,如图 4-8 所示。
图 4-8. 准确率、精确率和召回率
准确率
如图 4-8 所示,准确率是所有预测中正确预测的比例。这是分类问题最常见的评估指标,但也是最常被误用的。它在每个类中观察数相等时最合适(这种情况很少出现),以及所有预测和相关预测误差同等重要时最合适(这种情况通常不成立)。
精确率
精确率 是总预测正实例中的正实例百分比。在这里,分母是整个给定数据集中模型预测为正的部分。当假阳性的成本较高时(例如电子邮件垃圾邮件检测),精确率是一个很好的度量标准。
召回率
召回率(或敏感度或真正率)是总实际正实例中的正实例百分比。因此,分母(真正阳性+假阴性)是数据集中实际存在的正实例数量。当虚假阴性成本高昂时(例如欺诈检测),召回率是一个很好的度量标准。
除了准确率、精确率和召回率之外,还讨论了分类的其他常用评估指标。
ROC 曲线下的面积
ROC 曲线下的面积(AUC)是用于二元分类问题的评估指标。ROC 是一个概率曲线,AUC 表示可分离性的程度或度量。它告诉我们模型区分类别的能力有多强。AUC 越高,模型在将零预测为零和一预测为一方面的能力越好。AUC 为0.5意味着模型根本没有类别分离能力。AUC 分数的概率解释是,如果您随机选择一个正案例和一个负案例,那么正案例根据分类器的排序超过负案例的概率由 AUC 给出。
混淆矩阵
混淆矩阵展示了学习算法的性能。混淆矩阵简单地是报告分类器预测的真阳性(TP)、真阴性(TN)、假阳性(FP)和假阴性(FN)的计数的方阵,如图 4-9 所示。
图 4-9. 混淆矩阵
混淆矩阵是对具有两个或多个类别的模型准确性的便利展示。表格展示了x 轴上的预测和y 轴上的准确结果。表格的单元格是模型做出的预测数量。例如,模型可以预测零或一,每个预测实际上可能是零或一。实际为零的预测出现在预测=0 且实际=0 的单元格中,而实际为一的预测出现在预测=0 且实际=1 的单元格中。
为监督分类选择评估指标
分类的评估指标严重依赖于手头的任务。例如,当虚假阴性(如欺诈检测)带来高昂成本时,召回率是一个很好的度量标准。我们将在案例研究中进一步研究这些评估指标。
模型选择
选择完美的机器学习模型既是艺术也是科学。观察机器学习模型时,并没有适合所有情况的单一解决方案或方法。有几个因素可能会影响您选择机器学习模型的选择。大多数情况下的主要标准是我们在前一节中讨论的模型性能。然而,在进行模型选择时,还有许多其他因素需要考虑。在接下来的部分中,我们将详细介绍所有这些因素,并讨论模型的权衡。
模型选择的因素
模型选择过程中考虑的因素如下:
简单性
模型的简单程度。简单性通常导致模型和结果更快、更可扩展和更易理解。
训练时间
模型训练中的速度、性能、内存使用情况和总体时间。
处理数据中的非线性关系
模型处理变量之间的非线性关系的能力。
对过拟合的鲁棒性
模型处理过拟合的能力。
数据集的大小
模型处理数据集中大量训练样本的能力。
特征数量
模型处理特征空间高维度的能力。
模型解释性
模型的解释能力如何?模型的可解释性很重要,因为它允许我们采取具体措施解决潜在问题。
特征缩放
模型是否要求变量进行缩放或者服从正态分布?
图 4-10 对之前提到的因素比较了监督学习模型,并概述了在给定问题下缩小最佳机器学习算法搜索范围的经验法则⁷。该表基于本章节中讨论的不同模型的优缺点。
图 4-10. 模型选择
从表中可以看出,相对简单的模型包括线性回归和逻辑回归,而随着向集成和人工神经网络(ANN)方向发展,复杂性增加。在训练时间方面,与集成方法和 ANN 相比,线性模型和 CART 的训练速度相对较快。
线性和逻辑回归不能处理非线性关系,而其他所有模型都可以。支持向量机(SVM)可以通过非线性核处理因变量和自变量之间的非线性关系。
支持向量机(SVM)和随机森林倾向于比线性回归、逻辑回归、梯度提升和 ANN 过拟合较少。过拟合程度还取决于其他参数,如数据集大小和模型调整,并且可以通过查看每个模型的测试集结果来检查。此外,与随机森林等装袋方法相比,梯度提升等增强方法的过拟合风险更高。需要注意的是,梯度提升的重点是最小化偏差而不是方差。
线性回归和逻辑回归在处理大数据集和大量特征时效果不佳。然而,CART、集成方法和人工神经网络(ANN)能够很好地处理大数据集和许多特征。在数据集较小的情况下,线性回归和逻辑回归通常表现优于其他模型。应用变量减少技术(如第七章所示)可以使线性模型处理大数据集。随着数据集大小的增加,ANN 的性能也会提高。
相比于集成模型和人工神经网络(ANN),线性回归、逻辑回归和 CART 等相对简单的模型具有更好的模型解释性能。
模型权衡
在选择模型时,通常需要在不同因素之间进行权衡。人工神经网络(ANN)、支持向量机(SVM)和某些集成方法可以用来创建非常精确的预测模型,但它们可能缺乏简单性和可解释性,并且可能需要大量资源进行训练。
选择最终模型时,当预测性能是最重要的目标时,通常会更倾向于可解释性较低的模型,而不需要解释模型的工作原理和预测过程。然而,在某些情况下,模型的解释性是必须的。
在金融行业经常看到以可解释性为驱动的示例。在许多情况下,选择机器学习算法与算法的优化或技术方面关系较少,更多地与业务决策有关。假设一个机器学习算法用于接受或拒绝个人的信用卡申请。如果申请人被拒绝并决定提出投诉或采取法律行动,金融机构将需要解释如何做出这个决定。对于人工神经网络(ANN)而言,这几乎是不可能的,但对于基于决策树的模型而言相对简单。
不同类别的模型擅长建模不同类型的数据潜在模式。因此,一个很好的第一步是快速测试几种不同类别的模型,以了解哪些模型最有效地捕捉数据集的潜在结构。在所有基于监督学习的案例研究中,我们将遵循这种方法进行模型选择。
章节总结
在本章中,我们讨论了监督学习模型在金融中的重要性,随后简要介绍了几种监督学习模型,包括线性回归、逻辑回归、SVM、决策树、集成学习、KNN、LDA 和 ANN。我们展示了如何使用 sklearn 和 Keras 库的几行代码进行这些模型的训练和调优。
我们讨论了回归和分类模型中最常见的错误度量标准,解释了偏差-方差的权衡,并且用交叉验证说明了管理模型选择过程的各种工具。
我们介绍了每个模型的优缺点,并讨论了在选择最佳模型时需要考虑的因素。我们还讨论了模型性能和可解释性之间的权衡。
在接下来的章节中,我们将深入研究回归和分类的案例研究。在接下来的两章中的所有案例研究都利用了本章和前两章提出的概念。
¹ 交叉验证将在本章后面详细介绍。
² 有关sigmoid函数的详细信息,请参阅第三章的激活函数部分。
³ MLE 是一种估计概率分布参数的方法,使得在假定的统计模型下观察到的数据最有可能。
⁴ 数据投影的方法类似于第七章中讨论的 PCA 算法。
⁵ 偏差和方差将在本章后面详细描述。
⁶ 分裂是将非同质父节点转换为两个同质子节点的过程(最佳可能的)。
⁷ 在这张表中,我们不包括AdaBoost和extra trees,因为它们在所有参数上的整体行为与Gradient Boosting和Random Forest类似。