书名:Python预测分析实战
ISBN:978-7-115-56570-9
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
著 [美] 阿尔瓦罗•富恩特斯(Alvaro Fuentes)
译 高 蓉 李 茂
责任编辑 吴晋瑜
人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
网址 http://www.ptpress.com.cn
读者服务热线:(010)81055410
反盗版热线:(010)81055315
读者服务:
微信扫码关注【异步社区】微信公众号,回复“e56570”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。
Copyright ©Packt Publishing 2018. First published in the English language under the title Hands-On Predictive Analytics with Python (9781789138719). All rights reserved.
本书由英国Packt Publishing公司授权人民邮电出版社有限公司出版。未经出版者书面许可,对本书的任何部分不得以任何方式或任何手段复制和传播。
版权所有,侵权必究。
本书先介绍预测分析的重要概念和原则,然后给出一系列的代码示例和算法讲解,引导读者了解完整的预测分析流程,进而用Python工具构建高性能的预测分析解决方案。全书所涵盖的内容包括预测分析过程、理解问题和准备数据、理解数据集—探索性数据分析、基于机器学习的数值预测、基于机器学习的类别预测、调整模型和提高性能、基于Dash的模型实现等。
本书适合想要学习预测建模并对用 Python 工具实现预测分析解决方案感兴趣的数据分析师、数据科学家、数据工程师和Python开发人员阅读,也适合对预测分析感兴趣的读者参考。
预测分析是人工智能时代非常重要的技术之一。每一天,各行各业都在用预测分析技术解决各式各样的问题。预测分析的原材料是数据,但搜集数据的成本很高。因此,虽然预测分析的大量主流思想和技术早在几十年前就已出现,但预测分析一直发展得较为缓慢。直至近年来,数据的获取能力和存储能力获得了空前提升,预测分析的应用才迎来爆发。预测分析变得流行还有两个原因:一是计算能力的显著提高;二是许多开源软件项目的出现极大地降低了预测分析技术的使用门槛,使学术界以外的人士也可以使用这一强大的技术。例如这个项目——Python编程语言及其分析库生态系统,也称为Python数据科学栈,就大大普及了高级分析技术的应用。
本书的主题是预测分析,其内容是与实际预测的分析过程紧密相关,而不限于算法和技术的详解。我们结合预测分析的实操示例,向你展示应用Python数据分析生态系统的主要技术和方法。本书主要使用两个项目贯穿整个预测分析过程,从商务业务实践和问题的理解到模型的开发,各个阶段均通过操作示例实现。
本书会介绍多种预测分析技术:统计模型、时间序列分析以及空间统计等。我们的关注重点是应用广泛的技术——机器学习,其中的监督学习是重点强调的部分。
本书认为,得到预测模型只是手段,不是目的。预测分析的目的是解决问题。因此,评价预测模型好坏的标准不应该是是否使用了最新和最时髦的技术,也不应该是评估模型本身是复杂还是简单。好的预测模型应该既能解决实际问题,操作起来又方便。我们的目标是,让你通过学习本书打好基础,随后能够使用预测分析解决实际问题。
本书的目标读者是数据科学家、数据工程师、软件工程师以及商业分析师。此外,金融和商业等量化领域需要从事数据处理工作的学生和专业人士,以及其他希望构建预测模型的人士,也会发现本书大有裨益。总之,我们希望可以通过本书帮助从事Python预测分析的所有人士。
第1章预测分析过程 介绍预测分析的基本概念,说明预测分析过程的不同阶段,并概述本书会用到的软件。
第2章理解问题和准备数据介绍本书会涉及的问题和数据集,并展示建模的基础工作,以及如何收集数据和准备数据集。
第3章理解数据集——探索性数据分析展示借助数据可视化技术和其他数值技术从数据集中获取重要信息的过程。
第4章基于机器学习的数值预测介绍机器学习的主要思想、概念以及一些流行的回归模型。
第5章基于机器学习的分类预测介绍机器学习中一些重要的分类模型。
第6章 面向预测分析的神经网络简介展示神经网络模型的构建过程。神经网络不但功能强大而且精度很高,广受欢迎。
第7章模型评价展示评价预测模型结果所需要的主要指标和方法。
第8章调整模型和提高性能介绍k折交叉验证等重要技术,这些技术可以改进预测模型的性能。
第9章基于Dash的模型实现展示交互式网络应用的构建过程,从用户处获取输入,再用训练好的预测模型生成预测。
要获得最佳学习效果,你需要具备以下基础。
● 一定的Python编程能力。
● 基本的统计知识。
你需要先了解Python数据科学栈的知识,但这也不是必备条件。本书将使用Python 3.6和许多的主流分析库。获取这些库的简单方式是直接安装Anaconda,Anaconda是一个开源的Python发行版本。虽然这并不是必需的,但可以简化你的工作。请浏览Anaconda官网以了解这个软件的更多内容。
本书所用的排版约定如下。
CodeInText
:表示文本中使用的代码、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟URL、用户输入等内容。例如,“把下载的磁盘映像文件WebStorm-10*.dmg
挂载到系统的另一个虚拟磁盘。”
代码块以如下样式显示:
carat_values = np.arange(0.5, 5.5, 0.5)
preds = first_ml_model(carat_values)
pd.DataFrame({"Carat": carat_values, "Predicted price":preds})
对于特殊的代码块,相关的行或者项目会被设置为粗体:
numerator = ((ccd['default']==1) & (ccd['male']==1)).sum()/N
denominator = Prob_B
Prob_A_given_B = numerator/denominator
print("P(A|B) = {:0.4f}".format(Prob_A_given_B))
命令行的输入和输出格式如下:
dim_features.corr()
黑体:表示新术语、重要的词或者屏幕上的词,比如文本中出现的菜单或对话框中的词。例如,“从管理员面板选择系统信息。”
表示警告或重要注释。
表示提示和技巧。
您还可以扫码右侧二维码, 关注【异步社区】微信公众号,回复“e56570”直接获取,同时可以获得异步社区15天VIP会员卡,近千本电子书免费畅读。
Doug Ortiz是一名经验丰富的架构师,擅长解决企业云、大数据、数据分析方面的问题,以及构建、设计、开发、重新设计并整合企业解决方案。他在亚马逊云服务、Azure、谷歌云、商业智能、Hadoop、Spark、NoSQL数据库以及SharePoint等方面也有非常丰富的工作经验。
感谢我的妻子Milla,感谢Maria和Nikolay,感谢我们的孩子,感谢他们给予我的所有支持!
——Doug Ortiz
高蓉,博士,毕业于南开大学,任教于杭州电子科技大学;研究领域包括资产定价、实证金融、数据科学应用;已出版多部著作,发表数篇论文;曾获浙江省教育科学规划课题(项目编号2019SCG006)、浙江省教育厅科研项目(项目编号Y201840396)、杭州电子科技大学校级高等教育教学研究改革项目(项目编号ZDJG201907)资助、国家自然科学基金(项目编号71671008、71303016)以及浙江省自然科学基金项目(项目编号LY17G030033)资助。
李茂,毕业于北京师范大学,任教于天津理工大学;热爱数据科学,目前从事与统计和数据分析相关的教学和研究工作。
阿尔瓦罗·富恩特斯(Alvaro Fuentes)是一位资深数据分析师,在分析行业的从业经验超过12年,拥有应用数学的硕士学位和数量经济学的学士学位。他在银行工作过多年,担任经济分析师。他后来创建了Quant公司,主要提供与数据科学相关的咨询和培训服务,并为许多项目做过顾问,涉及商业、教育、医药和大众传媒等领域。
他是一名Python的深度爱好者,有5年的Python工作经验,从事过分析数据、构建模型、生成报告、进行预测以及构建从数据到智能决策的智能转换交互式应用等工作。
本章主要内容
● 预测分析的内容。
● 预测分析的重要概念。
● 预测分析的过程。
● Python数据科学栈的简单介绍。
这是本书介绍概念较多的部分。你或许希望直奔“编程建模”的主题,但要学习本书的内容,还是应该先理解预测分析的基本概念。在本章中,我们将介绍什么是预测分析,接着对这个热点领域中一些最重要的概念加以定义,然后介绍预测分析过程的各个阶段,并进行简单的讨论。在后续章节中,我们会围绕每个阶段的主题展开详细阐述。
虽然本章大体上是属于概念性的,但是要读懂代码,请务必安装好下列软件。
● Python 3.6或更高版本。
● Jupyter Notebook。
● 最新版本的Python库:NumPy和Matplotlib。
本书强烈推荐你安装Anaconda。Anaconda是一个开源的Python发行版本,其中包含大量的软件包。安装好Anaconda就意味着成功安装了本书将要用到的大多数软件。如果你还不熟悉Anaconda,请参考1.5.1节的内容。
近年来,全世界可观测数据的数量呈现指数型增长态势,而相关科技术语的数量更是呈现突飞猛进的增长。业界、媒体和学术界的话题逐渐转向了(有时风头会过热)大数据、数据挖掘、分析、机器学习、数据科学、数据工程、统计学习和人工智能等。当然,本书的主题预测分析也是其中之一。
目前,这些术语还都比较新,因此术语本身及其确切含义多存在不少易混淆之处,不同的术语之间也会有重复。为便于理解,我们并没有定义所有术语,而是针对主要术语给出了实用性定义。这些定义足以刻画预测分析的内涵:
预测分析是一个应用领域,它基于数据应用各种量化方法进行预测。
下面让我们分析一下上述定义。
● 应用领域。事实上,所谓的理论性的预测分析并不存在。预测分析始终面向各行各业解决实际问题,涉及金融、电信、广告、保险、医疗、教育、娱乐等行业。记住,预测分析的目的是解决特定领域的某个问题,因此预测分析的关键是问题的背景和行业知识。我们将在第2章对此进行深入讨论。
● 应用各种量化方法。预测分析会应用多种理论、技术、实践方法、实证结论,用到的理论涉及计算机科学和统计学这样的数理科学领域,具体包括最优化、概率论、线性代数、人工智能、机器学习、深度学习、算法、数据结构、统计推断、可视化和贝叶斯推断等。这些知识虽然可以为解决问题提供分析工具,但不会产生任何理论结果,因此分析结论必须与既有理论一致。这意味着工具必须用对,因此你需要具备一定的概念基础,需要熟悉前面提到的一些专业基础知识,这样才能预测分析得既正确又严格。在后续章节中,我们会以一种抽象的方式讨论各个领域的相关基础知识。
● 基于数据。量化方法是预测分析的工具,数据则是构建模型的“原材料”。预测分析的关键在于从数据中提取有用的信息。事实证明,基于数据制定决策的价值很大。全世界的组织大都采用数据驱动的方法(而非随意)来制定各种决策,从而导致他们对数据的依赖越来越强。预测分析也是一种数据应用,即先根据数据进行预测,再根据预测结果解决问题。
预测分析(或其他任何类型的高级分析)中的操作通常会超出电子表格的功能范畴,有鉴于此,为了正确执行预测分析,我们可以应用编程语言——Python和R已经成为主流选择(也可以选择其他编程语言,如Julia)。
此外,你需要直接利用数据存储系统(如关系数据库或非关系数据库)或者大数据存储解决方案,因此需要熟悉相关工具(如SQL和Hadoop)。但是,这些工具涉及的操作超出了本书的范围。在本书中,我们不关心数据的提取,并假定所有示例提前从存储系统获取了数据。针对示例的分析,我们会从原始数据开始,展示预测分析过程常用的一些操作和变换。本书所涉及的处理都是用Python及相关工具完成的,具体操作过程参见后续章节。
● 进行预测。定义最后的部分看起来很直接,但需要澄清的是,在预测分析的背景下,预测(Prediction)针对的是未知事件,并不等同于口语意义上的未来。比如,我们构建一个医学预测模型,使用病人的临床数据预测该病人是否患有疾病X。当病人的数据收集完毕时,病人是否患有疾病X已是既定的事实,不需要预测病人是否在未来会患疾病X。模型给出的是未知事件“病人患有疾病X”的评估(是有根据的推测)。当然,预测有时候会与未来有关,但并不必然是一回事。
下面我们介绍预测分析领域中的一些重要概念,这些概念是需要你牢牢掌握的。
在本节中,我们将介绍本书会用到的一些术语,并明确其相关的含义。有时,初学者的学习困惑部分来自于术语。有些概念可能有多个术语。举一个极端的例子,变量、特征、属性、自变量、预测变量、回归变量、协变量、解释变量、输入和因子,这些术语可能表示的是相同的含义!造成这种糟糕局面的原因是研究者来自不同的领域(如统计学、计量经济学、计算机科学、运筹学等),每个领域都有独特的命名方式,因此进行预测分析时也引用了各领域的术语。但是别担心,你很快就会习惯了。
现在我们来看一些基本概念。记住,术语的定义不必过于正式,也不需要逐字记住。在这里,本书会为相关术语构建清晰的定义。数据是预测分析的“原始材料”,因此我们需要先对一些关键性的数据概念加以定义。
● 数据。获得并存储起来的记录,这些记录在某些上下文中是有意义的。
● 观测单元。分析对象的实体。很多时候它在背景中很清晰,但有时候很难定义(尤其是与非技术人士沟通时)。假设要对连锁超市的一组商店的“销售数据”进行分析,这项定义模糊的任务可以定义为许多观测单元的组合,观测单元包括商店、收银机、交易、日期等。一旦知道了观测单元是什么(如顾客、房屋、患者、城市、细胞、石头、星星、数据、产品、交易、推文、网站等),你就可以了解它们的属性。
● 属性。分析单元的特征。如果分析单元是患者,那么属性可以是年龄、身高、体重、体重指数、胆固醇水平等。
● 数据点、样本、观测和实例。具备所有可用属性的单个观测单元。
● 数据集。一组数据点,通常以表格形式储存,如关系数据库表或其他电子表格。
在许多问题中,数据集的形式是非结构化的,如视频、音频、推文和博客文章。但是,在预测分析中讨论数据集时,通常指结构化的数据集、一个表格或一组相关的表格。在进行预测分析时,大部分时间可能花在数据集的格式转换上,即从非结构化转到结构化。
此外,从现在开始,讨论数据集就表示对象是单个表格。尽管真实的数据集可能由多个表格组成,但本书把它当作单个表格。典型的表格如图1-1所示。
图1-1
在该数据集中,观测单元是“Customer”,它是项目关注的实体对象。每一行表示一个观测或一个数据点,可以看到,每个数据点都有一系列属性(如Customer id、Age、Preferential status等)。下面我们讨论与这个数据集有关的建模词汇表。首先,从数学的角度看,每一列可以看作一个变量,变量的取值可能有变化,可以从一个数据点改变至另一个数据点。数据集中的变量关键是类型,类型有以下多种可能。
● 分类变量:取值只考虑有限个可能的变量,如性别、国家、交易类型、年龄组、婚姻状况、电影类型等。这类变量包含如下两个子类。
❏ 序数变量:属性有大小排序的变量,如年龄组(21~30岁、31~40岁、41~50岁,51岁及以上)或者衬衣型号(小号、中号、大号)。
❏ 基数变量:属性取值顺序无意义的变量。
● 数值变量:取值可以在某个定义区间内发生变化的变量。这类变量包含如下两个子类。
❏ 连续变量:原则上可以取区间内任意值的变量,如人的身高、股票价格、星星的质量以及信用卡余额。
❏ 整数变量:只能取整数值的变量,如孩子的个数、年龄(如果用年来度量)、一座房子的房间个数等。
数据集中有一列非常重要:就是我们想预测的那一列。这一列也可以称为目标、因变量、响应结果或输出变量,表示预测的质量或数量,通常记作y。本书使用术语目标(Target)对其进行表示。
一旦识别了目标,其他候选列就成了特征、属性、因变量、预测变量、回归变量、解释变量或输入,这些列将用于预测目标。本书将使用术语变量(Variable)和特征(Feature)对其进行表示。
最后,我们给出预测模型(Predictive Model)的定义:它是一种使用特征预测目标的方法。我们也可以将其看作数学函数:输入是一组特征和目标,输出是目标的预测值。从抽象层次来看,预测模型如图1-2所示。
尽管图1-2有一定的局限(某些人甚至可能会认为它是错的),但是足以说明预测模型的一般性概念。我们将在后续章节深入研究预测模型的细节,并构建多个预测模型。
图1-2
至此,我们已经介绍了预测模型的定义和本书会用到的一些重要术语。接下来,我们讨论预测分析过程。
人们普遍对预测分析抱有一种常见的误解,认为预测分析就是建模。事实上,建模只是预测分析的一部分。多年来,人们就预测分析梳理出了相对规范的阶段,只不过不同领域的使用者会用不同的名称指代这些阶段。但是,各个阶段之间的顺序是有逻辑的,它们之间的关系也很容易理解。事实上,我们正是按照这些阶段的逻辑顺序加以组织的,具体如下。
● 理解问题和定义问题。
● 收集数据和准备数据。
● 使用探索性数据分析(Exploratory Data Analysis,EDA)挖掘数据信息。
● 构建模型。
● 评价模型。
● 沟通以及/或者部署。
我们将在后续章节详细介绍所有阶段。接下来,我们将简要介绍每个阶段的主要内容。我们认为,每个阶段都应该有一个明确的目标。
目标:理解问题和发现潜在的解决方案,同时定义解决问题所需要的条件。
这是预测分析过程的第一个阶段。这个阶段很关键,这时需要和利益相关方一起构建预测模型的目标,明确什么问题需要解决和解决方案的大致内容。
在这个阶段,我们还要明确项目的要求,如解决方案需要什么样的数据,数据需要什么格式,数据量需要多少,等等。最后,我们还要讨论模型输出的形式和提供的解决方案。相关内容详见第2章。
目标:得到可供分析的数据集。
这个阶段的主要任务是查看可用的数据。根据项目情况也许需要与数据库管理员沟通,请他们提供数据,也许还需要不同的数据源。有时候,数据可能还不存在,那么我们可能需要与某个团队协作,制订出收集数据的计划。记住,这个阶段的目标是获得可用于预测建模的数据。
在获取数据时,有可能会识别出数据中潜在的问题,因此这个阶段与前一个阶段紧密相关。在准备数据时,任务会在该阶段和前一阶段之间来回切换,因为在这个过程中很可能会发现,可用的数据无法解决问题,需要联合利益相关方,共同探讨具体情况,并重新思考解决方案。
在构建数据集时,可能还会发现数据带有某些问题,比如,可能数据集的某一列包含了许多缺失值,或者取值的编码不恰当。原则上,在这个阶段处理缺失值和离群点这样的问题非常适合,但实际情况往往并非如此,因此这个阶段与后一个阶段之间的界限也不太清晰。
目标:理解数据集。
一旦数据收集和准备完毕,我们就该进入用EDA分析数据集的阶段了。EDA是数值技术和可视化技术的组合,可以帮助理解数据集不同变量的含义和变量之间的潜在联系。通常,这一阶段与前一阶段和后一阶段的关系比较模糊,所以不要轻易认为数据集已经“做好准备”。分析过程从一开始就会遇到各种问题,例如,从一个来源得到了5个月的历史数据,从另一个来源得到的历史数据则可能只有两个月的;又如,可能发现数据集中的3个特征是多余的;再如,需要组合数据集中的一些特征生成新特征。所以,通常任务在多次往返于前几个阶段后才可能完成,最终准备好数据集。
要深入理解数据集,我们先要回答下面的问题。
● 数据中的变量类型是什么?
● 变量的分布是什么样的?
● 数据集中有缺失值吗?
● 有多余的变量吗?
● 数据集特征之间的关系是什么?
● 可以观测到离群点吗?
● 不同的特征对特征间的相关性有什么影响?
● 相关系数有意义吗?
● 数据集的特征和预测分析的目标之间存在什么关系?
这个阶段的所有问题要与项目的总目标相匹配。同时,我们必须牢记问题。一旦数据获得了良好的理解,我们就可以进行下一个阶段的工作——构建模型。
目标:生成可以解决问题的预测模型。
这个阶段会构建多个预测模型,然后通过评价选出最佳的一个。在这个阶段,我们必须选择所要训练和估计的模型的类型。术语训练与机器学习有关,术语估计与统计有关。对于建模方法、模型的类型以及训练/估计过程,我们必须通过问题和解决方案加以确定。
在本书中,我们主要介绍如何使用Python构建模型及其数据科学生态系统,并比较不同的建模方法,如机器学习、深度学习和贝叶斯统计。在尝试不同的方法、模型类型和调参技术后,我们会让得到的最终模型进行“终极对决”,并希望最好的模型胜出,生成最佳的解决方案。
目标:从模型中选择最佳的一个模型,并评估该模型的解决方案。
在这个阶段中,我们要评价进入“终极对决”的模型,衡量它们的表现。这个阶段中的评价取决于问题,通常会用到一些主要指标。除了指标,还要考虑其他准则,如计算因素、可解释性、对用户友好的程度以及方法。我们会在第7章中深入探讨上述内容。模型评价会选择哪些准则和指标,也取决于问题。
记住,最佳的模型并不是最标新立异的、最复杂的、数学形式最棒的、计算效率最高的或者最前沿的,但一定是最有可能解决问题的。
目标:使用预测模型和预测结果。
最终,模型构建完毕,检验完成,并得到不错的评价。在理想的情况下,这个模型可以解决问题,其性能也很好。接下来,我们应该进入应用阶段了。模型的应用取决于项目,有时我们可以直接将预测结果作为报告的主题向利益相关方汇报。这就是沟通,而良好的沟通技巧有助于完成既定目标。
有时,模型会被整合为软件应用的一部分:网络端、桌面、移动端或任何其他类型的技术。这时我们很可能需要与应用团队密切交流,甚至参与其中。还有另一种可能性,即模型本身也许会成为一个“数据产品”。例如,信用卡评分应用会利用客户数据计算客户违约的可能性。我们将在第9章中以这个数据产品作为实例。
尽管我们按各阶段的顺序对其进行了介绍,但需要明确的是,这个分析过程是高度迭代和非线性的,实际建模时将在这些阶段中来回往复。相邻阶段的边界是模糊的,它们之间总有一些重叠,所以确定每个任务究竟归入哪个阶段并不是特别重要。举例来说,处理离群点的任务是属于“收集数据和准备数据”阶段的一部分,还是属于“使用EDA挖掘数据信息”阶段的一部分?这在实践中无关紧要,这个任务可以放在任何阶段,重点在于需要针对这个任务进行什么处理。
不过,在预测分析中,了解各阶段的逻辑顺序非常有用,这有助于工作的准备和组织,也有助于为项目的持续时间设定合理的预期。前一阶段是后一阶段的先决条件,各阶段的顺序是合理的。例如,不能在模型尚未构建之前就进行评价,但在评价模型后,如果认为这个模型不合适,可以返回“构建模型”阶段并提出新模型。
预测分析还有另一种流行框架,是跨行业的数据挖掘标准过程(Cross-Industry Standard Process for Data Mining,CRISP-DM),它类似于刚才描述的过程,在Wirth R和Hipp J的论文(2000)中有详细描述。在该框架中,分析过程分为6个主要阶段,如图 1-3 所示。需要着重强调的是,各个阶段的顺序并不严格,图 1-3 中的箭头仅描述了各阶段之间沟通较频繁的关系,这些关系取决于项目的特性或正在解决的问题。这6个阶段如下。
图1-3
● 业务理解。
● 数据理解。
● 数据准备。
● 建模。
● 评价。
● 部署。
这个过程还有其他的理解方式,例如,R. Peng(2016)用数据分析周转的概念描述了这个过程。他认为,周转包括如下内容。
● 开发预期。
● 收集数据。
● 匹配预期与数据。
● 提出问题。
● 探索性数据分析。
● 构建模型。
● 解释。
● 沟通。
“周转”这个词表达了这样一个事实:这些阶段不仅相互关联,还形成了完整的数据分析过程,整个过程仿佛一个很大的“轮子”。
在本节中,我们将介绍相关软件和Python数据科学栈中主要的库。这些库是计算工具,尽管熟练掌握这些库并不是学习本书内容的必要条件,但它们的作用无疑也很大。我们不是要全面介绍这些工具,因为相关的资源和教程已经有很多了,而只是介绍一些相关的基本内容。我们将在后续章节介绍利用这些工具进行预测分析的方法。如果你已经熟悉这些工具,那么可以跳过这一节。
下面是引自Anaconda官方网站的描述:
“Anaconda是一个包管理器、环境管理器、Python发行版本以及超过1000个开源包的集合。它不仅免费,而且容易安装,还提供了免费的社区支持。”
我们可以把Anaconda视为一个工具箱:一组用Python进行分析和科学计算的现成工具的集合。当然,工具也可以一个个地单独获取,但一次性获取整个工具箱肯定更方便。Anaconda同时可以兼顾各个包之间的依赖性,以及单独安装各个Python包会引起的其他潜在问题。如果安装的包(以及依赖性)最终发生冲突,处理起来会相当麻烦。阻止包之间的通信很难,更难的是让所有包保持更新。Anaconda对所有包轻松实现了获取和维护。
我们强烈建议你使用Anaconda,否则你将不得不逐一安装书里涉及的所有包。Anaconda的安装过程和其他任何软件类似,如果还没有安装,请转到Anaconda官方网站,查找适合自己的计算机操作系统的下载程序。请选择Python 3版本,虽然许多公司还在使用Python 2.7,但Python社区已经尽力迁移到Python 3,请跟上步伐!
如果你对Anaconda非常感兴趣,请参考其官方文档。
原则上,你可以使用面向Python的许多集成开发环境(Integrated Development Environment,IDE),不过目前,Jupyter Notebook已经几乎成为数据科学分析的标准IDE:
“Jupyter Notebook不仅通用性很高,还可以通过文本解释、可视化和其他元素来补充代码,现已成为最受分析社区欢迎的IDE之一。”
安装了Anaconda就意味着同时安装了Jupyter Notebook,使用很方便。Jupyter Notebook的使用步骤如下。
● 打开Anaconda提示符窗口,导航到启动应用程序的目录(Desktop\Predictive AnalyticsWithPython),输入jupyter notebook(见图1-4),再按Enter键,就可以开启应用。
图1-4
● 选择New|Python 3,将打开一个新的浏览器窗口,如图1-5所示。Jupyter Notebook是一个由单元格组成的Web应用。单元格有两种类型:Markdown和代码。在Markdown类型的单元格中,我们可以编写格式化的文本,也可以插入图像、链接和其他元素。代码类型的单元格是默认类型。
图1-5
● 如果要在主菜单中将单元格类型修改为Markdown类型,应选择Cell|Cell Type| Markdown。编辑Markdown类型的单元格的界面如图1-6所示。
图1-6
编辑结果如图1-7所示。
图1-7
● 你还可以在代码类型的单元格中编写和执行Python代码,并展示执行的结果,如图1-8所示。要得到执行结果,请按Ctrl+Enter组合键。本书大部分示例会使用Jupyter Notebook进行操作(有时为了简化,我们会使用常规的Python shell)。
● 在Jupyter Notebook的主菜单中,转到Help,你可以找到用户界面教程(User Interface Tour)、键盘快捷方式(Keyboard Shortcuts)和其他有趣的资源。
图1-8
最后,在撰写本书时,Jupyter Lab已成为Jupyter社区的下一个项目,提供了一些新功能。如果你有兴趣,也可以尝试在Jupyter Lab中运行实例。本书的代码也可以在Jupyter Lab中运行。
对于Python生态系统来说,NumPy是科学计算库的基本库。Python生态系统中主要的库都以NumPy为基础,包括pandas、Matplotlib、SciPy和scikit-learn。
NumPy是一个基本库,因此学习相关的基础知识非常重要。下面我们给出一份NumPy的“迷你教程”。
在进行科学计算时,我们常常需要对变量进行向量化,下面通过两个示例给出这么做的原因,并明确向量化的含义。
让我们先用Python执行两个简单的计算。两个示例如下。
● 第一个示例,假设已经掌握了距离和时间的信息,目的是计算速度;
distances = [10, 15, 17, 26]
times = [0.3, 0.47, 0.55, 1.20]
# Calculate speeds with Python
speeds = []
for i in range(4):
speeds.append(distances[i]/times[i])
speeds
结果如下:
[33.333333333333336,
31.914893617021278,
30.909090909090907,
21.666666666666668]
● 第二个示例,用Python完成相同的计算:
# An alternative
speeds = [d/t for d,t in zip(distances, times)]
在第二个示例中,假设已知的条件是一系列产品的质量和相应的价格,目的是计算总的采购金额。Python中的代码如下:
product_quantities = [13, 5, 6, 10, 11]
prices = [1.2, 6.5, 1.0, 4.8, 5.0]
total = sum([q*p for q,p in zip(product_quantities,prices)])
total
得到总采购金额是157.1
。
这些示例的关键在于,这种计算本身需要逐个对元素进行操作,而Python(以及大多数编程语言)可以通过循环或列表解析(这只是编写循环的简便方法)完成。向量化是计算机编程的一种风格,这一操作会依次作用到数组中每个元素,换句话说,向量化操作是逐个对元素进行操作,而非显式地使用<strong>for</strong>
循环。
现在让我们来看NumPy的操作方法。
● 导入这个库:
import numpy as np
● 计算速度。可以看到,这很简单,只需要考虑速度的数学定义:
# calculating speeds
distances = np.array([10, 15, 17, 26])
times = np.array([0.3, 0.47, 0.55, 1.20])
speeds = distances / times
speeds
输出如下:
array([ 33.33333333, 31.91489362, 30.90909091, 21.66666667])
现在,购买金额已经计算完毕,我们可以轻松运行计算代码:
#Calculating the total of a purchase
product_quantities = np.array([13, 5, 6, 10, 11])
prices = np.array([1.2, 6.5, 1.0, 4.8, 5.0])
total = (product_quantities*prices).sum()
total
运行这个计算后,得到的总金额是相同的,total的值
为157.1。
现在我们讨论关于数组的创建、主要属性和操作的一些基本知识。这里的介绍并不会面面俱到,但我们可以大致介绍NumPy数组的工作原理,这就足够了。
和前面一样,可以基于列表创建数组,如下所示:
# arrays from lists
distances = [10, 15, 17, 26, 20]
times = [0.3, 0.47, 0.55, 1.20, 1.0]
distances = np.array(distances)
times = np.array(times)
如果给np.array()
传递一个列表的列表,则会创建一个二维数组。如果传递的是列表的列表的列表(三重嵌套列表),则会创建一个三维数组,代码如下:
A = np.array([[1, 2], [3, 4]])
三维数组A
如下所示:
array([[1, 2], [3, 4]])
下面看一下数组的一些主要属性。先创建一些数组,数字是随机生成的:
np.random.seed(0) # seed for reproducibility
x1 = np.random.randint(low=0, high=9, size=12) # 1D array
x2 = np.random.randint(low=0, high=9, size=(3, 4)) # 2D array
x3 = np.random.randint(low=0, high=9, size=(3, 4, 5)) # 3D array
print(x1, '\n')
print(x2, '\n')
print(x3, '\n')
下面是生成的数组:
[5 0 3 3 7 3 5 2 4 7 6 8]
[[8 1 6 7]
[7 8 1 5]
[8 4 3 0]]
[[[3 5 0 2 3]
[8 1 3 3 3]
[7 0 1 0 4]
[7 3 2 7 2]]
[[0 0 4 5 5]
[6 8 4 1 4]
[8 1 1 7 3]
[6 7 2 0 3]]
[[5 4 4 6 4]
[4 3 4 4 8]
[4 3 7 5 5]
[0 1 5 3 0]]]
数组的重要属性如下。
● ndarray.ndim
:数组轴的个数(维数)。
● ndarray.shape
:数组维度。这个整数元组表示数组在每个维度上的大小。
● ndarray.size
:数组元素的总数。它等于行元素个数与列元素个数的乘积。
● ndarray.dtype
:描述数组中元素类型的对象。可以使用标准Python类型对dtype进行创建或指定。另外,NumPy内置的类型包括numpy.int32
、numpy.int16
以及numpy.float64,比
Python支持的类型更加丰富。下面的例子列出了数组的这几个属性:
print("x3 ndim: ", x3.ndim)
print("x3 shape:", x3.shape)
print("x3 size: ", x3.size)
print("x3 dtype: ", x3.dtype)
输出如下所示:
x3 ndim: 3
x3 shape: (3, 4, 5)
x3 size: 60
x3 dtype: int32
一维数组可以进行索引、切片以及迭代,和列表或其他的Python序列一样:
>>> x1
array([5, 0, 3, 3, 7, 3, 5, 2, 4, 7, 6, 8])
>>> x1[5] # element with index 5
3
>>> x1[2:5] # slice from of elements in indexes 2,3 and 4
array([3, 3, 7])
>>> x1[-1] # the last element of the array
8
多维数组的每个轴都有一个索引,这些索引用逗号分隔的元组给出:
one_to_twenty = np.arange(1,21) # integers from 1 to 20
>>> my_matrix = one_to_twenty.reshape(5,4) # transform to a 5-row by 4-
column matrix
>>> my_matrix
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20]])
>>> my_matrix[2,3] # element in row 3, column 4 (remember Python is
zeroindexed)
12
>>> my_matrix[:, 1] # each row in the second column of my_matrix
array([ 2, 6, 10, 14, 18])
>>> my_matrix[0:2,-1] # first and second row of the last column
array([4, 8])
>>> my_matrix[0,0] = -1 # setting the first element to -1
>>> my_matrix
代码输出如下:
array([[-1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20]])
然后,在之前的矩阵上执行一些数学运算操作,可以当作向量化的示例:
>>> one_to_twenty = np.arange(1,21) # integers from 1 to 20
>>> my_matrix = one_to_twenty.reshape(5,4) # transform to a 5-row by 4-
column matrix
>>> # the following operations are done to every element of the matrix
>>> my_matrix + 5 # addition
array([[ 6, 7, 8, 9],
[10, 11, 12, 13],
[14, 15, 16, 17],
[18, 19, 20, 21],
[22, 23, 24, 25]])
>>> my_matrix / 2 # division
array([[ 0.5, 1. , 1.5, 2. ],
[ 2.5, 3. , 3.5, 4. ],
[ 4.5, 5. , 5.5, 6. ],
[ 6.5, 7. , 7.5, 8. ],
[ 8.5, 9. , 9.5, 10. ]])
>>> my_matrix ** 2 # exponentiation
array([[ 1, 4, 9, 16],
[ 25, 36, 49, 64],
[ 81, 100, 121, 144],
[169, 196, 225, 256],
[289, 324, 361, 400]], dtype=int32)
>>> 2**my_matrix # powers of 2
array([[ 2, 4, 8, 16],
[ 32, 64, 128, 256],
[ 512, 1024, 2048, 4096],
[ 8192, 16384, 32768, 65536],
[ 131072, 262144, 524288, 1048576]], dtype=int32)
>>> np.sin(my_matrix) # mathematical functions like sin
array([[ 0.84147098, 0.90929743, 0.14112001, -0.7568025 ],
[-0.95892427, -0.2794155 , 0.6569866 , 0.98935825],
[ 0.41211849, -0.54402111, -0.99999021, -0.53657292],
[ 0.42016704, 0.99060736, 0.65028784, -0.28790332],
[-0.96139749, -0.75098725, 0.14987721, 0.91294525]])
最后,让我们看一些数据分析中常见的高效方法:
>>> # some useful methods for analytics
>>> my_matrix.sum()
210
>>> my_matrix.max() ## maximum
20
>>> my_matrix.min() ## minimum
1
>>> my_matrix.mean() ## arithmetic mean
10.5
>>> my_matrix.std() ## standard deviation
5.766281297335398
这里的目的并不是“重新发明”NumPy,关于NumPy基础的优秀资源已经非常多了。
SciPy是面向科学计算的一组包。如果你想了解更详细的信息,可参考相关文档。 SciPy中的子包及其描述如表1-1所示。
表1-1
子包 |
描述 |
---|---|
cluster |
包含了许多用于聚类操作的程序和函数 |
constants |
用于物理、天文、工程以及其他领域的数学常数 |
fftpack |
快速傅里叶变换的程序和函数 |
integrate |
用于求解数值积分和偏微分方程的主要工具 |
interpolate |
插值工具和光滑样条函数 |
io |
从不同格式读取对象或将对象保存到不同格式的输入/输出函数 |
linalg |
主要的线性代数操作,它是NumPy的核心 |
ndimage |
图像处理工具,与n维对象一起使用 |
optimize |
包含了许多最常用的最优化和求根的程序与函数 |
sparse |
提供了处理稀疏矩阵的工具,补充了线性代数程序 |
special |
用于物理、天文、工程和其他领域的特殊函数 |
stats |
用于描述性统计和推断统计的统计分布与函数 |
我们将在后续章节对SciPy的一些函数和子包进行介绍。
pandas的创建基本上是为了处理两类数据结构:一类是一维数据,即序列;另一类是DataFrame,即二维结构,是pandas非常常见的结构,可以看成SQL表或者Excel表格。
尽管数据结构仍有其他类型,但上述两种结构已经可以涵盖大约90%的预测分析案例。事实上,大部分时候(以及本书所有示例中)在处理DataFrame。我们将在第2章通过案例介绍pandas的基本功能。如果你对这个库完全陌生,建议先阅读pandas的相关教程。
Matplotlib是二维可视化的主要的库,也是Python生态系统中最“古老”的科学计算工具之一。尽管Python可视化的库在不断增加,Matplotlib依然使用广泛,事实上Matplotlib也被整合到了pandas中。此外,某些其他更专业的可视化库也是基于Matplotlib开发的,如Seaborn。
本书只在需要时使用Matplotlib,因为高级的库更受偏爱,特别是Seaborn和pandas(它们包含了很棒的可视化函数)。但是,这些库都构建于Matplotlib的基础上,而分析过程经常需要对这些库生成的对象和图形进行修正,因此我们需要熟悉Matplotlib的一些基本术语和概念,之后就可以对数据进行可视化操作了。导入Matplotlib库,代码如下:
import matplotlib.pyplot as plt
%matplotlib inline # This is necessary for showing the figures in the
notebook
首先,这里有两个重要的对象,图像(Figure)和子图(Subplot,也称为Axes)。图是所有图形元素的顶层容器,也是子图的容器。一幅图可以有许多个子图,每个子图属于某幅图,包含着许多元素。下列代码生成了一幅图像(不可见),具有一个空的子图:
fig, ax = plt.subplots()
ax.plot();
子图如图1-9所示。
图1-9
下列代码可以生成一幅包含4个子图的图:
fig, axes = plt.subplots(ncols=2, nrows=2)
fig.show();
输出结果如图1-10所示。
图1-10
Matplotlib的使用方式容易引起初学者的混淆,它有两种使用接口,pyplot和面向对象的接口(Object Oriented Interface,OOI)。笔者偏爱OOI,因为它可以明确处理对象。前面生成的axes
对象是包含了4个子图的NumPy数组。这里画出一些随机数,目的是展示如何引用每个子图。运行代码之后,图像看起来会有所变化。这里的随机数可以通过设置随机种子进行控制:
fig, axes = plt.subplots(ncols=2, nrows=2)
axes[0,0].set_title('upper left')
axes[0,0].plot(np.arange(10), np.random.randint(0,10,10))
axes[0,1].set_title('upper right')
axes[0,1].plot(np.arange(10), np.random.randint(0,10,10))
axes[1,0].set_title('lower left')
axes[1,0].plot(np.arange(10), np.random.randint(0,10,10))
axes[1,1].set_title('lower right')
axes[1,1].plot(np.arange(10), np.random.randint(0,10,10))
fig.tight_layout(); ## this is for getting nice spacing between the
subplots
输出结果如图1-11所示。
axes
对象是一个NumPy数组,这里使用NumPy索引引用每个子图,可以在每个子图上使用.set_title()
或.plot()
方法,把它修正为理想的样子。这样的方法有很多,大多数用来修正子图的元素。例如,下面的代码几乎和之前一样,但编写得更紧凑,并修正了<em>y</em>
轴的刻度。
另一种应用程序接口(Application Programming Interface,API)是pyplot,它可以在大多数在线示例中发现,包括在文档中。这段代码使用pyplot重现了图1-11:
图1-11
titles = ['upper left', 'upper right', 'lower left', 'lower right']
fig, axes = plt.subplots(ncols=2, nrows=2)
for title, ax in zip(titles, axes.flatten()):
ax.set_title(title)
ax.plot(np.arange(10), np.random.randint(0,10,10))
ax.set_yticks([0,5,10])
fig.tight_layout();
输出结果如图1-12所示。
图1-12
下面是一小段的pyplot示例:
plt.plot([1,2,3,4])
plt.title('Minimal pyplot example')
plt.ylabel('some numbers')
输出结果如图1-13所示。
图1-13
Seaborn是一个高级的可视化库,可以生成数据分析常用的统计图形。使用Seaborn的优点是往往只需要很少的几行代码,就能生成高度复杂的多变量可视化图形,这些图形非常漂亮也显得非常专业。
Seaborn库能帮助我们在Python中创建有吸引力的而且含义丰富的统计图形。它构建于Matplotlib之上,与PyData栈高度集成。它支持NumPy和pandas的数据结构以及来自SciPy和statsmodels的统计程序。
Seaborn提供的一些特征是内置的主题,可以帮助Matplotlib的风格化图形工具选择合适的调色板,来制作揭示数据模式的漂亮图形。这个库的功能非常强大,可以为数据绘制一元和二元的分布;可以拟合同类型的自变量和因变量,并对线性模型进行可视化;可以对数据矩阵进行可视化,并利用聚类算法发现数据的结构;可以灵活估计时间序列,并对估计结果进行可视化;可以绘制高度抽象的图形网格,从而轻松构建复杂的可视化图形。
Seaborn旨在使可视化成为探索和理解数据的核心。绘图函数可以直接在包含完整数据集的DataFrame和数组上进行操作,因此使用Seaborn处理数据更加容易。
本书会始终使用Seaborn,并会介绍大量有“价值”的可视化图形,特别是在第3章中。
scikit-learn是Python生态系统中主要面向传统机器学习的一个库。它提供的API一致并简单,不仅可用于机器学习建模,也可用于许多的相关任务,例如数据的预处理、转换和超参数调整。它的构建基础是NumPy、SciPy和Matplotlib(因此这些库的相关知识需要了解),它也是Python社区最受欢迎的预测分析工具之一。我们将在第5章和第6章介绍更多关于这个库的知识。
TensorFlow是机器学习专用库,在2015年11月实现了开源,此后在许多行业的研究和产品应用中成为深度学习的首选库。
TensorFlow的计算实现过程基于一种数据流编程范式,并具有强大的复杂计算能力。TensorFlow的工作原理是这样的,首先构建一张计算图,再在名为“sessions”的指定对象中运行计算图所描述的计算,最后由“sessions”负责将计算结果输出到CPU或GPU上。TensorFlow的计算过程显得并不直接(特别是对于初学者),因此不在示例中直接使用。我们在第6章的计算中会用到TensorFlow,把它当作“后台”。
本书选择Keras构建深度学习模型。Keras是一个对用户友好的出色的库,可以作为TensorFlow(或其他如Theano这样的深度学习库)的“前台”使用。Keras的主要目标是成为“容易使用的深度学习库”。笔者认为,Keras实现了这个目标,它大大简化了深度学习的开发。
在第6章中,我们将以Keras作为工具。
Dash是一种能快速构建网络应用的Python框架,无须使用者了解JavaScript、CSS、HTML、服务器端编程或者属于网络开发领域的有关技术。
在本章中,我们介绍了预测分析的基本概念,随后就可以基于此概念深入介绍预测分析的实践知识。预测分析是一个应用领域,它应用各种量化方法基于数据进行预测。接着,我们抽象地讨论了预测分析过程的每一个阶段,还介绍了本书所用的Python数据科学栈的主要工具。随着将在后续章节应用这些工具,我们还会介绍更多的相关知识。
第1章是本书概念较多的部分。从第2章开始,我们会在内容中穿插相关的实践操作。
● Chin L, Dutta Tanmay, 2016. NumPy Essentials.Packt Publishing.
● Fuentes A, 2017. Become a Python Data Analyst.Packt Publishing.
● VanderPlas J, 2016. Python Data Science Handbook:Essential Tools for Working with Data,O'Reilly Media.
● Wirth R, Hipp J, 2000. CRISP-DM:Towards a standard process model for data mining. Proceedings of the 4th international conference on the practical applications of knowledge discovery and data mining.
● Yim A, Chung C, Yu A, 2018. Matplotlib for Python Developers.Packt Publishing.
微信扫码关注【异步社区】微信公众号,回复“e56570”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。