Skip to content

Latest commit

 

History

History
944 lines (575 loc) · 58.5 KB

File metadata and controls

944 lines (575 loc) · 58.5 KB

一、Jupyter 基础知识

Jupyter 笔记本是,是使用 Python 的数据科学家最重要的工具之一。 这是因为它们是开发可重现的数据分析管道的理想环境。 可以在单个笔记本内全部加载,转换和建模数据,在此方便快捷地测试代码并探索思路。 此外,所有这些都可以使用格式文本“内联”记录,因此您可以自己做笔记,甚至生成结构化的报告。

其他类似的平台(例如 RStudio 或 Spyder)为用户提供了多个窗口,这些窗口促进了繁重的任务,例如在周围复制和粘贴代码以及重新运行已经执行的代码。 这些工具还倾向于涉及读取求值提示循环REPL),其中代码在已节省内存的终端会话中运行。 这种开发环境不利于可重复性,也不适合开发。 Jupyter 笔记本通过为用户提供一个在其中执行代码段并内联显示输出的窗口,解决了所有这些问题。 这使用户可以有效地开发代码,并允许他们回顾以前的工作以供参考,甚至进行更改。

我们将通过确切地解释什么是 Jupyter 笔记本开始本课,并继续讨论为什么它们在数据科学家中如此受欢迎。 然后,我们将一起打开一个笔记本,并进行一些练习以了解如何使用该平台。 最后,我们将深入研究第一个分析并对“基本功能和特性”进行探索性分析。

课程目标

在本课程中,您将:

  • 了解什么是 Jupyter 笔记本及其为何对数据分析有用
  • 使用 Jupyter 笔记本功能
  • 学习 Python 数据科学库
  • 执行简单的探索性数据分析

注意

本书中的所有代码都可以在代码包中作为特定于课程的 IPython 笔记本使用。 本书中的所有色图也可在代码包中找到。

基本功能和特性

在本节中,我们首先通过示例和讨论来证明 Jupyter 笔记本的有用性。 然后,为了涵盖面向初学者的 Jupyter 笔记本的基础知识,我们将在启动平台和与平台交互方面看到它们的基本用法。 对于以前使用 Jupyter 笔记本的用户,这主要是评论。 但是,您当然也会在该主题中看到新事物。

副题 A:什么是 Jupyter 笔记本,为什么有用?

Jupyter 笔记本是在本地运行的 Web 应用,其中包含实时代码,方程式,图形,交互式应用和 Markdown 文本。 标准语言是 Python,这就是我们将在本书中使用的。 但是,请注意,支持多种选择。 这包括其他主导数据科学语言 R:

Subtopic A: What is a Jupyter Notebook and Why is it Useful?

那些熟悉 R 的人会知道 R Markdown。 Markdown 文档允许将 Markdown 格式的文本与可执行代码结合在一起。 Markdown 是一种用于在网络上设置样式的简单语言。 例如,大多数 GitHub 存储库都有一个README.md Markdown 文件。 此格式对于基本文本格式很有用。 它可以与 HTML 媲美,但允许更少的自定义。 Markdown 中常用的符号包括将文本变成标题的哈希(#),用于插入超链接的方括号和圆括号,以及用于创建斜体或粗体文本的星号:

Subtopic A: What is a Jupyter Notebook and Why is it Useful?

了解了 Markdown 的基础知识之后,让我们回到 R Markdown,其中 Markdown 文本可以与可执行代码一起编写。 Jupyter 笔记本提供了与 Python 相同的功能,尽管我们将看到,它们的功能与 R Markdown 文档完全不同。 例如,除非另有说明,否则 R Markdown 假定您正在编写 Markdown,而 Jupyter 笔记本假定您正在输入代码。 这使使用 Jupyter 笔记本进行快速开发和测试更具吸引力。

从数据科学的角度来看,Jupyter 笔记本电脑有两种主要类型,具体取决于使用方式:实验室型和可交付使用。

实验室样式的笔记本旨在用作研究期刊的编程类似物。 这些应该包含您为加载,处理,分析和建模数据所做的所有工作。 这里的想法是记录您所做的一切,以备将来参考,因此通常不建议删除或更改以前的实验室样式的笔记本。 最好在分析过程中累积多个带日期戳的笔记本版本,以防您想回顾以前的状态。

可交付使用的笔记本旨在作为展示,并且应仅包含实验室样式笔记本的某些部分。 例如,这可能是一个有趣的发现,可以与您的同事共享,可以为管理者提供深入的分析报告,也可以为利益相关者总结重要发现。

在这两种情况下,重要的概念都是可重复性。 如果您一直在努力记录软件版本,则收到报告的任何人都可以重新运行笔记本并计算与您相同的结果。 在可重复性变得越来越困难的科学界,这是新鲜空气。

子主题 B:浏览平台

现在,我们将打开 Jupyter 笔记本并开始学习界面。 在这里,我们将假设您没有平台的先验知识,然后介绍基本用法。

介绍 Jupyter 笔记本

  1. 导航到终端中的随附材料目录。

    注意

    在 Mac 或 Linux 等 Unix 机器上,可以使用ls显示目录内容,并使用cd更改目录来完成命令行导航。

    在 Windows 计算机上,使用dir显示目录内容,而使用cd更改目录。 例如,如果要将驱动器从C:更改为D:,则应执行d:来更改驱动器。

  2. 通过在终端中键入以下内容,在此处启动新的本地笔记本服务器:

    jupyter notebook

    默认浏览器的新窗口或新标签页将打开笔记本仪表盘至工作目录。 在这里,您将看到其中包含的文件夹和文件的列表。

  3. 单击文件夹以导航到该特定路径,然后通过单击打开文件。 尽管 Jupyter 的主要用途是编辑 IPYNB 笔记本文件,但 Jupyter 也可以用作标准的文本编辑器。

  4. 我们可以看到NotebookApp正在本地服务器上运行。

    [I 20:03:01.045 NotebookApp] The Jupyter Notebook is running at: http://localhost:8888/ ?token=e915bb06866f19ce462d959a9193a94c7c088e81765f9d8a

    转到该 HTTP 地址将在浏览器窗口中加载该应用,就像启动该应用时自动完成的一样。 关闭窗口不会停止应用; 这应该从终端通过键入Ctrl + C完成。

  5. 通过在终端中键入Ctrl + C关闭应用。 您可能还需要输入y进行确认。 同时关闭 Web 浏览器窗口。

  6. 加载 NotebookApp 时,有多种可用选项。 在终端中,通过运行以下命令查看可用选项的列表:

    jupyter notebook-help
  7. 一种这样的选择是指定一个特定的端口。 通过运行以下命令,在本地端口9000上打开NotebookApp

    jupyter notebook --port 9000
  8. 创建新的 Jupyter 笔记本的主要方法是从 Jupyter 仪表板。 单击右上角的“新建”,然后从下拉菜单中选择一个内核(即,在“笔记本”部分中选择某些内容):

    Introducing Jupyter Notebooks

    内核为笔记本提供编程语言支持。 如果您在 Anaconda 中安装了 Python,则该版本应为默认内核。 Conda 虚拟环境也将在此处提供。

    注意

    虚拟环境是在同一台计算机上管理多个项目的绝佳工具。 每个虚拟环境可能包含不同版本的 Python 和外部库。 Python 具有内置的虚拟环境。 但是,Conda 虚拟环境与 Jupyter 笔记本集成得更好,并拥有其他出色的功能。 该文档位于

  9. 使用新创建的空白笔记本,在顶部的单元格中单击,然后键入print('hello world')或写入屏幕的任何其他代码段。 通过单击单元格并按Shift + Enter或在“单元格”菜单中选择“运行单元格”来执行它。

    单元运行时,代码的任何stdoutstderr输出将显示在下方。 此外,写在最后一行的对象的字符串表示形式也会显示在中。 这非常方便,尤其是对于显示表格而言,但有时我们不希望显示最终对象。 在这种情况下,可以在行的末尾添加分号(;)以抑制显示。

    默认情况下,新单元格期望并运行代码输入; 但是,可以将它们更改为呈现 Markdown。

  10. 单击进入一个空单元格并将其更改为接受 Markdown 格式的文本。 这可以通过工具栏中的下拉菜单图标或通过从单元格菜单中选择 Markdown 来完成。 在此处写一些文本(任何文本都可以),确保使用 Markdown 格式符号,例如#

  11. 将重点放在笔记本顶部的工具栏上:

![Introducing Jupyter Notebooks](img/image1_07.jpg)

工具栏中有一个“播放”图标,可用于运行单元格。 但是,正如我们稍后将看到的那样,使用键盘快捷键`Shift + Enter`来运行单元格更加方便。 在其旁边是一个停止图标,可以使用来停止运行单元。 例如,这在单元运行时间过长时非常有用:

![Introducing Jupyter Notebooks](img/image1_09.jpg)

可以从**插入**菜单中手动添加新单元格:

![Introducing Jupyter Notebooks](img/image1_11.jpg)

可以使用图标或通过从**编辑**菜单中选择选项来复制,粘贴和删除单元格:

![Introducing Jupyter Notebooks](img/image1_13.jpg)

![Introducing Jupyter Notebooks](img/image1_15.jpg)

单元也可以通过以下方式上下移动:

![Introducing Jupyter Notebooks](img/image1_17.jpg)

**单元格**菜单下有一些有用的选项,可以运行一组单元格或整个笔记本:

![Introducing Jupyter Notebooks](img/image1_19.jpg)
  1. 尝试使用工具栏选项来上下移动单元格,插入新单元格以及删除单元格。
关于这些笔记本电脑要了解的重要一点是单元之间的共享内存。 这非常简单:工作表中存在的每个单元格都可以访问全局变量集。 因此,例如,在一个单元格中定义的函数可以从任何其他单元调用,并且同样适用于变量。 正如人们所期望的,函数范围内的任何内容都不是全局变量,只能从该特定函数中进行访问。
  1. 打开内核菜单以查看选择。 如果内核死了,内核菜单对于停止脚本执行和重新启动笔记本电脑很有用。 也可以随时在此处交换内核,但是由于对可重复性的考虑,建议不要在单个笔记本中使用多个内核。
  2. 打开“文件”菜单以查看选择。 “文件”菜单包含用于下载各种格式的笔记本的选项。 特别是,建议保存您的笔记本的 HTML 版本,其中的内容是静态呈现的,可以在 Web 浏览器中“按预期方式”打开和查看。
笔记本名称将显示在左上角。 新笔记本将自动命名为**无标题**。
  1. 通过单击左上角的当前名称并输入新名称来更改 IPYNB 笔记本文件的名称。 然后,保存文件。
  2. 关闭网络浏览器中的当前选项卡(退出笔记本电脑),然后转到“Jupyter 仪表板”选项卡,该选项卡仍应处于打开状态。 (如果未打开,请通过复制并从终端粘贴 HTTP 链接来重新加载它。)
由于我们没有关闭笔记本电脑,因此我们保存并退出了笔记本电脑,在 Jupyter 仪表板的**文件**部分中,它的名称旁边会有一个绿皮书符号,并将列为最后修改日期旁边的**运行**。 可以从此处关闭笔记本电脑。
  1. 选中您正在使用的笔记本(名称左侧的复选框),然后单击橙色的关闭按钮,退出该笔记本:
![Introducing Jupyter Notebooks](img/image1_21.jpg)

注意

如果您打算花费大量时间使用 Jupyter 笔记本,则值得学习键盘快捷键。 这将大大加快您的工作流程。 要学习的特别有用的命令是用于手动添加新单元格并将单元格从代码转换为 Markdown 格式的快捷方式。 单击帮助菜单中的键盘快捷方式,以了解操作方法。

子主题 C:Jupyter 功能

Jupyter 具有的许多吸引人的功能,这些特征使高效的 Python 编程成为可能。 这些包括各种各样的东西,从查看文档字符串的方法到执行 Bash 命令。 让我们在本节中一起探讨其中一些功能。

注意

可以在以下位置找到 IPython 的官方文档。 它包含有关我们将在此处和其他地方讨论的功能的详细信息。

探索 Jupyter 的一些最有用的功能

  1. 从 Jupyter 仪表板中,导航到lesson-1目录,然后通过选择它来打开lesson-1-workbook.ipynb文件。 Jupyter 笔记本的标准文件扩展名是.ipynb,它在被称为 IPython 笔记本时就引入了。

  2. 向下滚动到 Jupyter 笔记本中的Subtopic C: Jupyter Features。 我们首先回顾基本的键盘快捷键。 这些特别有助于避免不得不如此频繁地使用鼠标,这将大大加快工作流程。 这是最有用的键盘快捷键。 学习使用这些功能将极大地改善您使用 Jupyter 笔记本的体验以及您自己的效率:

    • Shift + Enter用于运行单元格
    • Esc键用于离开单元格
    • M键用于将单元格更改为 Markdown(按Esc后)
    • Y键用于更改要编码的单元格(按Esc后)
    • 箭头键移动单元格(按Esc后)
    • Enter键用于输入单元格

    从快捷方式继续,帮助选项对初学者和经验丰富的编码人员都非常有用。 它可以为每个不确定的步骤提供指导。

    通过在任何对象的末尾添加问号并运行单元格,用户可以获得帮助。 Jupyter 找到该对象的文档字符串,并在应用底部的弹出窗口中将其返回。

  3. 运行“获得帮助”部分的单元格,并查看 Jupyter 如何在笔记本底部显示文档字符串。 在此部分中添加一个单元格,并获得有关所选对象的帮助:

    Explore some of Jupyter's most useful features

    制表符补全可用于执行以下操作:

    • 导入外部库时列出可用的模块
    • 列出导入的外部库的可用模块
    • 功能和变量补全

    当您需要了解模块的可用输入参数,探索新库,发现新模块或只是加快工作流程时,尤其有用。 它们将节省写出变量名或函数的时间,并减少了拼写错误。 制表符的完成效果非常好,以至于您可能在今天以后难以在其他编辑器中编写 Python 代码!

  4. 单击“制表符完成”部分中的空代码单元,然后尝试按上面建议的方式使用制表符完成。 例如,第一个建议可以通过输入import(包括后面的空格),然后按Tab键来完成:

    Explore some of Jupyter's most useful features

  5. 最后但并非最不重要的 Jupyter 笔记本基本功能是魔术命令。 这些命令由一个或两个百分号组成。 以%%开头的魔术将应用于整个单元格,而以%开头的魔术仅适用于该行。 在示例中看到时,这将是有意义的。

    滚动到Jupyter Magic Functions部分,然后运行包含%lsmagic%matplotlib inline:的单元格

    Explore some of Jupyter's most useful features

    %lsmagic列出了可用的选项。 我们将讨论并显示一些最有用的示例。 您可能会看到的最常见的魔术命令是%matplotlib inline,它允许 Matplotlib 图形显示在笔记本中,而无需显式使用plt.show()

    计时功能非常方便,分为两种:标准计时器(%time%%time)和用于测量多次迭代的平均运行时间的计时器(%timeit%%timeit)。

  6. 运行“计时器”部分中的单元格。 请注意使用一个和两个百分号之间的区别。

    即使使用 Python 内核(如您目前所做的那样),也可以使用魔术命令来调用其他语言。 内置选项包括 JavaScript,R,Pearl,Ruby 和 Bash。 Bash 特别有用,因为您可以使用 Unix 命令来查找当前位置(pwd),目录中的内容(ls),创建新文件夹(mkdir)以及写入文件内容(cat/head/tail)。

  7. 运行“使用笔记本中的 bash”部分中的第一个单元格。 此单元格将一些文本写入工作目录中的文件,打印目录内容,打印空行,然后在删除之前回写新创建文件的内容:

    Explore some of Jupyter's most useful features

  8. 运行以下仅包含lspwd的单元格。 请注意,我们不必显式使用 Bash 魔术命令来使它们起作用。

    有很多可以安装的外部魔术命令。 流行的是ipython-sql,它允许在单元格中执行 SQL 代码。

  9. 如果尚未安装ipython-sql,请立即安装。 打开一个新的终端窗口并执行以下代码:

    pip install ipython-sql

    Explore some of Jupyter's most useful features

  10. 运行&load_ext sql单元以将外部命令加载到笔记本中:

![Explore some of Jupyter's most useful features](img/image1_33.jpg)

这样就可以连接到远程数据库,以便可以直接在笔记本内部执行查询(并记录在文档中)。
  1. 运行包含 SQL 示例查询的单元格:
![Explore some of Jupyter's most useful features](img/image1_35.jpg)

在这里,我们首先连接到本地 sqlite 来源; 但是,该行可能指向本地或远程服务器上的特定数据库。 然后,我们执行一个简单的`SELECT`来显示如何将单元转换为运行 SQL 代码而不是 Python。
  1. 转到其他有用的魔术函数,我们将简要讨论一个有助于文档编制的函数。 该命令是%version_information,但是 Jupyter 并没有标配它。 就像我们刚刚看到的 SQL 一样,可以使用pip从命令行安装它。
如果尚未完成,请立即使用`pip`从终端安装版本文档工具。 打开一个新窗口并运行以下代码:

```py
pip install version_information
```

安装后,可以使用`%load_ext version_information`将其导入任何笔记本电脑。 最后,一旦加载,它就可以用于显示笔记本电脑中每个软件的版本。
  1. 运行加载并调用version_information命令的单元:
![Explore some of Jupyter's most useful features](img/image1_37.jpg)

将 Jupyter 笔记本转换为 Python 脚本

您可以将 Jupyter 笔记本转换为 Python 脚本。 这等效于将每个代码单元的内容复制并粘贴到单个.py文件中。 Markdown 部分也包含在注释中。

可以从NotebookApp或在命令行中进行转换,如下所示:

jupyter nbconvert --to=python lesson-1-notebook.ipynb

Converting a Jupyter Notebook to a Python Script

例如,当您要使用pipreqs之类的工具确定笔记本的库要求时,此功能很有用。 该工具确定项目中使用的库,并将它们导出到requirements.txt文件中(可以通过运行pip install pipreqs进行安装)。

从包含.py文件的文件夹外部调用该命令。 例如,如果.py文件位于名为lesson-1的文件夹中,则可以执行以下操作:

pipreqs lesson-1/

Converting a Jupyter Notebook to a Python Script

lesson-1-workbook.ipynb的结果requirements.txt文件如下所示:

cat lesson-1/requirements.txt
matplotlib==2.0.2
numpy==1.13.1
pandas==0.20.3
requests==2.18.4
seaborn==0.8
beautifulsoup4==4.6.0
scikit_learn==0.19.0

子主题 D:Python 库

现在看到了 Jupyter 笔记本的所有基础知识,甚至还有一些更高级的功能,我们将注意力转移到本书中将要使用的 Python 库中。 通常,库会扩展默认的 Python 函数集。 常用标准库的示例是datetimetimeos。 这些之所以称为标准库,是因为它们是每个 Python 安装中的标准库。

对于使用 Python 的数据科学,最重要的库是外部的,这意味着它们不是 Python 的标准配置。

本书中将使用的外部数据科学库是 NumPy,Pandas,Seaborn,Matplotlib,Scikit-learn,Requests 和 Bokeh。 让我们简单介绍一下。

注意

使用行业标准导入库是个好主意,例如,通过import numpy as np;这样可以提高代码的可读性。 尽量避免执行from numpy import *之类的事情,因为您可能会无意间覆盖函数。 此外,将模块通过点(.)链接到库通常很不错,以提高代码的可读性。

  • NumPy 提供了多维数据结构(数组),可以在其中执行的操作要比标准 Python 数据结构(例如,列表)快得多。 这部分是通过使用 C 在后台执行操作来完成的。NumPy 还提供了各种数学和数据操作功能。
  • Pandas 是 Python 对 R DataFrame的回答。 它以 2D 表格结构存储数据,其中列代表不同的变量,行代表样本。 Pandas 提供了许多方便的数据整理工具,例如填写 NaN 条目和计算数据的统计描述。 使用 Pandas DataFrame将是本书的重点。
  • Matplotlib 是一款受 MATLAB 平台启发的绘图工具。 熟悉 R 的可以将其视为 ggplot 的 Python 版本。 它是用于绘制图形的最受欢迎的 Python 库,并允许进行高级别的自定义。
  • Seaborn 是作为 Matplotlib 的扩展,其中包括对数据科学有用的各种绘图工具。 一般来说,与使用诸如 Matplotlib 和 Scikit-learn 之类的库手动创建相同的东西相比,这样做可以更快地完成分析。
  • Scikit-learn 是最常用的机器学习库。 它提供了一流的算法和非常优雅的 API,其中实例化了模型,然后使与数据匹配。 它还提供了对预测分析有用的数据处理模块和其他工具。
  • Requests 是用于发出 HTTP 请求的转到库。 它使从网页获取 HTML 以及与 API 交互变得很简单。 为了解析 HTML,许多人选择 BeautifulSoup4,我们还将在本书中进行介绍。
  • Bokeh 是一个交互式可视化库。 它的功能类似于 Matplotlib,但是允许我们将悬停,缩放,单击以及使用其他交互式工具添加到绘图中。 它还使我们能够在 Jupyter 笔记本内部渲染和玩游戏。

介绍了这些库之后,让我们回到笔记本并通过运行import语句加载它们。 这将使我们进入第一个分析,最后我们开始使用数据集。

导入外部库并设置绘图环境

  1. 打开lesson 1 Jupyter 笔记本,然后滚动到Subtopic D: Python Libraries部分。

    就像常规 Python 脚本一样,可以随时将库导入到笔记本中。 最佳做法是将您使用的大多数包放在文件顶部。 有时在笔记本中途加载东西是有意义的,这完全可以。

  2. 运行单元来导入外部库并设置绘图选项:

    Import Jupyter Notebooksplotting environment, setting upthe external libraries and set up the plotting environment

    对于一个不错的笔记本设置,设置各种选项以及顶部的导入通常很有用。 例如,可以执行以下操作来将图形外观更改为比 Matplotlib 和 Seaborn 默认设置更美观的外观:

    import matplotlib.pyplot as plt
    %matplotlib inline
    import seaborn as sns
    # See here for more options: https://matplotlib.org/users/customizing.html
    %config InlineBackend.figure_format='retina'
    sns.set() # Revert to matplotlib defaults
    plt.rcParams['figure.figsize'] = (9, 6)
    plt.rcParams['axes.labelpad'] = 10
    sns.set_style("darkgrid")

到目前为止,本书已经介绍了使用 Jupyter 笔记本进行数据科学的基础知识。 我们首先探索平台并找到围绕界面的方法。 然后,我们讨论了最有用的功能,其中包括制表符补全和魔术功能。 最后,我们介绍了将在本书中使用的 Python 库。

下一部分将非常互动,因为我们将使用 Jupyter 笔记本一起执行我们的第一个分析。

我们的第一个分析-波士顿住房数据集

到目前为止,本课程重点介绍 Jupyter 的功能和基本用法。 现在,我们将其付诸实践,并进行一些数据探索和分析。

我们将在本节中看到的数据集是所谓的波士顿住房数据集。 它包含有关波士顿市区各个地区房屋的美国人口普查数据。 每个样本对应一个唯一的区域,并具有大约十二个小节。 我们应该将样本视为行,将度量视为列。 该数据于 1978 年首次发布,非常小,仅包含约 500 个样本。

现在,我们对数据集的上下文有所了解,让我们为探索和分析制定一个粗略的计划。 如果适用,该计划将适应正在研究的相关问题。 在中,目标不是回答问题,而是演示 Jupyter 的实际操作并举例说明一些基本的数据分析方法。

我们进行此分析的一般方法是执行以下操作:

  • 使用 Pandas DataFrame将数据加载到 Jupyter 中
  • 了解定量特征
  • 寻找模式并提出问题
  • 回答问题

子主题 A:使用 Pandas DataFrame将数据加载到 Jupyter 中

通常,数据存储在表中,这意味着可以将其保存为逗号分隔的变量CSV)文件。 使用 Pandas 库,可以将这种格式以及许多其他格式作为DataFrame对象读入到 Python 中。 其他常见格式包括制表符分隔的变量TSV),SQL 表和 JSON 数据结构。 实际上,Pandas 支持所有这些。 但是,在此示例中,我们不会以这种方式加载数据,因为可以直接通过 Scikit-learn 获得数据集。

注意

加载数据进行分析后,重要部分是确保数据干净。 例如,我们通常需要处理丢失的数据,并确保所有列都具有正确的数据类型。 我们在本节中使用的数据集已经清理完毕,因此我们无需担心。 但是,我们将在第二课中看到更混乱的数据,并探讨处理这些数据的技术。

加载波士顿住房数据集

  1. lesson 1 Jupyter 笔记本中,滚动到Our First Analysis: The Boston Housing DatasetSubtopic A

    可以使用load_boston方法从sklearn.datasets模块访问波士顿住房数据集。

  2. 运行本节的前两个单元以加载波士顿数据集并查看datastructures类型:

    Load the Boston housing dataset

    第二个单元格的输出告诉我们这是一个 Scikit-learn Bunch对象。 让我们获得更多有关此的信息,以了解我们正在处理的内容。

  3. 运行下一个单元格,从 Scikit-learn utils导入基础对象,并在我们的笔记本中打印文档字符串:

    Load the Boston housing dataset

    读取生成的文档字符串表明它基本上是一本字典,并且基本上可以这样对待。

  4. 通过运行下一个单元格来打印字段名称(即字典的键)。

    我们发现这些字段是不言自明的:['DESCR', 'target', 'data', 'feature_names']

  5. 运行下一个单元以打印包含在boston['DESCR']中的数据集描述。

    请注意,在此调用中,我们明确希望打印该字段值,以使笔记本以比字符串表示形式更可读的格式呈现内容(也就是说,如果我们只键入boston['DESCR']而没有将其包装在print语句)。 然后,我们将数据集信息视为先前总结的:

    Boston House Prices dataset
    ===========================
    Notes
    ------
    Data Set Characteristics:  
        :Number of Instances: 506 
        :Number of Attributes: 13 numeric/categorical predictive
        :Median Value (attribute 14) is usually the target
       :Attribute Information (in order):
            - CRIM     per capita crime rate by town
    …
    …
            - MEDV     Median value of owner-occupied homes in $1000's
        :Missing Attribute Values: None

    这里特别重要的是特征说明(在Attribute Information下)。 在分析过程中,我们将使用作为参考。

    注意

    有关完整的代码,请参考Lesson 1文件夹中的Lesson 1.txt文件。

    现在,我们将创建一个包含数据的 Pandas DataFrame。 这出于以下几个原因是有好处的:我们的所有数据都将包含在一个对象中,可以使用有用且计算效率高的DataFrame方法,而其他诸如 Seaborn 之类的库都具有可以很好地与DataFrame集成的工具。

    在的情况下,我们将使用标准的构造器方法创建DataFrame

  6. 运行导入了 Pandas 的单元格,并为pd.DataFrame检索文档字符串:

    Load the Boston housing dataset

    该文档字符串显示了DataFrame输入参数。 我们要为数据输入boston['data'],并为标头使用boston['feature_names']

  7. 运行接下来的几个单元格以打印数据,其形状和特征名称:

    Load the Boston housing dataset

    查看输出,我们看到我们的数据在 2D NumPy 数组中。 运行命令boston['data'].shape,分别返回长度(样本数)和特征数作为第一和第二输出。

  8. 通过运行以下命令将数据加载到 Pandas DataFrame df中:

    df = pd.DataFrame(data=boston['data'], columns=boston['feature_names'])

    在机器学习中,正在建模的变量称为目标变量; 这就是您要预测的给定目标。 对于此数据集,建议的目标是MEDV,即房屋价值中位数(以 1,000 美元计)。

  9. 运行下一个单元格以查看目标的形状:

    Load the Boston housing dataset

    我们看到与特征具有相同的长度,这正是我们所期望的。 因此,可以将其作为新列添加到DataFrame中。

  10. 通过使用以下命令运行单元格,将目标变量添加到df

```py
df['MEDV'] = boston['target']
```
  1. 为了将目标与我们的特征区分开来,将其存储在DataFrame的前端可能会有所帮助。
通过使用以下命令运行单元格,将目标变量移至`df`的前面:

```py
y = df['MEDV'].copy()
del df['MEDV']
df = pd.concat((y, df), axis=1)
```

在这里,我们引入了一个虚拟变量`y`来保存目标列的副本,然后再将其从`DataFrame`中删除。 然后,我们使用 Pandas 连接函数将其与沿第 1 轴(而不是第 0 轴,后者组合行)的其余`DataFrame`组合在一起。

### 注意

您经常会看到点标记用于引用`DataFrame`列。 例如,以前我们可以完成`y = df.MEDV.copy()`。 但是,这不适用于删除列。 `del df.MEDV`会引发错误。
  1. 现在,数据已全部加载完毕,让我们看一下DataFrame。 我们可以通过df.head()df.tail()来查看数据,而len(df)可以确保样本数量符合我们的预期。
在接下来的几个单元格中运行,以查看`df`的头,尾和长度:

![Load the Boston housing dataset](img/image1_055.jpg)

![Load the Boston housing dataset](img/image1_057.jpg)

每行都标有一个索引值,如表左侧的粗体所示。 默认情况下,它们是一组整数,从 0 开始,每行递增一个。
  1. 打印df.dtypes将显示每一列中包含的数据类型。
运行下一个单元格以查看每一列的数据类型。

对于此数据集,我们看到每个字段都是浮点数,因此很可能是连续变量,包括目标。 这意味着预测目标变量是一个回归问题。
  1. 我们要做的下一件事是通过处理所有丢失的数据来清理数据,Pandas 会自动将其设置为NaN值。 可以通过运行df.isnull()来识别它们,该函数返回与df形状相同的布尔型DataFrame。 要获取每列的NaN数,我们可以执行df.isnull().sum()
运行下一个单元格以计算每列中`NaN`值的数量:

![Load the Boston housing dataset](img/image1_059.jpg)

对于此数据集,我们看到没有`NaN`,这意味着我们在清理数据方面没有立即要做的工作并且可以继续。
  1. 为了简化分析,在探索之前我们要做的最后一件事是删除一些列。 我们不会理会这些内容,而是会更详细地关注其余部分。
通过运行包含以下代码的单元格来删除一些列:

```py
for col in ['ZN', 'NOX', 'RAD', 'PTRATIO', 'B']:
    del df[col]
```

子主题 B:数据探索

由于这是我们从未见过的全新数据集,因此这里的首要目标是了解数据。 我们已经看到了数据的文本描述,这对于定性理解很重要。 现在,我们将计算定量描述。

探索波士顿住房数据集

  1. 在 Jupyter 笔记本中导航到Subtopic B: Data exploration,并运行包含df.describe()的单元格:

    Explore Boston housing datasetexploringthe Boston housing dataset

    这将计算各种属性,包括每列的平均值,标准差,最小值和最大值。 该表提供了有关所有内容分配方式的高级思路。 注意,我们通过在输出中添加.T对结果进行了转换。 这将交换行和列。

    继续进行分析,我们将指定一组要关注的列。

  2. 运行定义了这些“焦点列”的单元格:

    cols = ['RM', 'AGE', 'TAX', 'LSTAT', 'MEDV']
  3. 可以使用方括号从df中选择此列的子集。 通过运行df[cols].head()显示DataFrame的此子集:

    Explore Boston housing datasetexploringthe Boston housing dataset

    提醒一下,让我们回顾一下这些列的含义。 从数据集文档中,我们有以下内容:

            - RM       average number of rooms per dwelling
            - AGE      proportion of owner-occupied units built prior to 1940
            - TAX      full-value property-tax rate per $10,000
            - LSTAT    % lower status of the population
            - MEDV     Median value of owner-occupied homes in $1000's

    为了在此数据中查找模式,我们可以开始使用pd.DataFrame.corr计算成对相关性。

  4. 通过运行包含以下代码的单元格,为我们选择的列计算成对相关性:

    df[cols].corr()

    Explore Boston housing datasetexploringthe Boston housing dataset

    此结果表显示了每组值之间的相关性得分。 较大的正面分数表示强烈的正面(即,朝着同一方向)相关。 如预期的那样,我们在对角线上看到最大值 1。

    注意

    皮尔逊系数定义为两个变量之间的协方差,除以它们的标准差的乘积:

    Explore Boston housing datasetexploringthe Boston housing dataset

    协方差定义如下:

    Explore Boston housing datasetexploringthe Boston housing dataset

n是样本数,x[i]y[i]是要累加的各个样本,X_barY_bar是每组的平均值。

与其费力地看着前面的表格,不如用热图可视化它。 使用 Seaborn 可以轻松做到这一点。
  1. 如本课程前面所述,运行下一个单元格以初始化绘图环境。 然后,要创建热图,请运行包含以下代码的单元格:

    import matplotlib.pyplot as plt
    import seaborn as sns
    %matplotlib inline
    ax = sns.heatmap(df[cols].corr(),
                     cmap=sns.cubehelix_palette(20, light=0.95, dark=0.15))
    ax.xaxis.tick_top() # move labels to the top
    plt.savefig('../figures/lesson-1-boston-housing-corr.png',
                bbox_inches='tight', dpi=300)

    Explore Boston housing datasetexploringthe Boston housing dataset

    我们称sns.heatmap,并将成对相关矩阵作为输入。 我们在此处使用自定义调色板来覆盖 Seaborn 的默认设置。 该函数返回一个matplotlib.axes对象,该对象由变量ax引用。 然后将最终图形作为高分辨率 PNG 保存到figures文件夹。

  2. 对于数据集探索练习的最后一步,我们将使用 Seaborn pairplot函数将您的数据可视化。

    使用 Seaborn 的pairplot函数可视化DataFrame。 运行包含以下代码的单元格:

    sns.pairplot(df[cols], 
                 plot_kws={'alpha': 0.6},
                 diag_kws={'bins': 30})

    Explore Boston housing datasetexploringthe Boston housing dataset

以前使用热图可视化相关性的简单概述,此图使我们可以更详细地查看这些关系。

查看对角线上的直方图,我们看到以下内容:

  • aRMMEDV具有最接近正态分布的形状。
  • bAGE偏向左侧,LSTAT偏向右侧(这似乎是违反直觉的,但偏斜是根据均值的位置,相对于最大值定义的)。
  • c:对于TAX,我们发现大量分布在 700 左右。这从散点图中也很明显。

仔细观察右下角的MEDV直方图,我们实际上会看到类似于TAX的东西,其中有一个上限为 50,000 美元的大上限。 回想一下当我们执行df.describe()时,MDEV的最小值和最大值分别为 5k 和 50k。 这表明数据集中的房屋中位价上限为 50k。

子主题 C:使用 Jupyter 笔记本的预测分析的简介

继续我们对波士顿住房数据集的分析,我们可以看到它给我们带来了回归问题,在该问题中,我们根据给定的特征预测了一个连续的目标变量。 特别是,我们将预测中位数房屋价值(MEDV)。 我们将训练仅采用一项特征作为输入进行预测的模型。 这样,模型将在概念上易于理解,并且我们可以将更多精力放在 Scikit-learn API 的技术细节上。 然后,在下一课中,您将更轻松地处理相对复杂的模型。

使用 Seaborn 和 Scikit-learn 的线性模型

  1. 在 Jupyter 笔记本中滚动至Subtopic C: Introduction to predictive analytics,然后在上方查看我们在上一节中创建的对图。 特别是,请查看左下角的散点图:

    Linear models with Seaborn and scikit-learn

    请注意,每间房屋的房间数(RM)和低阶层人口的百分比(LSTAT)与房屋中位数(MDEV)。 让我们提出以下问题:给定这些变量,我们如何预测MDEV

    为了帮助回答这个问题,让我们首先使用 Seaborn 可视化关系。 我们将与最佳拟合线性模型一起绘制散点图。

  2. 通过运行包含以下内容的单元,绘制散点图以及线性模型:

    fig, ax = plt.subplots(1, 2)
    sns.regplot('RM', 'MEDV', df, ax=ax[0],
                scatter_kws={'alpha': 0.4}))
    sns.regplot('LSTAT', 'MEDV', df, ax=ax[1],
                scatter_kws={'alpha': 0.4}))

    Linear models with Seaborn and scikit-learn

    最佳拟合线是通过最小化普通最小二乘误差函数来计算的,当我们调用regplot函数时,Seaborn 会自动执行。 还要注意线条周围的阴影区域,代表 95% 的置信区间。

    注意

    通过获取垂直于最佳拟合线的仓中数据的标准差,有效地确定沿最佳拟合线的每个点的置信区间,可以计算出这 95% 的置信区间。 在实践中,这涉及 Seaborn 引导数据,该过程是通过随机采样替换产生新数据的过程。 自举的样本数是根据数据集的大小自动确定的,但也可以通过传递n_boot参数来手动设置。

  3. Seaborn 也可以用于绘制这些关系的残差。 通过运行包含以下内容的单元来绘制残差:

    fig, ax = plt.subplots(1, 2)
    ax[0] = sns.residplot('RM', 'MEDV', df, ax=ax[0],
                          scatter_kws={'alpha': 0.4})
    ax[0].set_ylabel('MDEV residuals $(y-\hat{y})$')
    ax[1] = sns.residplot('LSTAT', 'MEDV', df, ax=ax[1],
                          scatter_kws={'alpha': 0.4})
    ax[1].set_ylabel('')

    Linear models with Seaborn and scikit-learn

    这些残差图上的每个点都是该样本(y)与线性模型预测(ŷ)之间的差。 大于零的残差是模型会低估的数据点。 同样,小于零的残差是数据点,可能会被模型高估。

    这些图中的模式可以指示次优建模。 在前面的每种情况下,我们都在正区域看到对角线排列的散射点。 这些是由MEDV的 50,000 美元上限引起的。 RM数据很好地聚集在 0 周围,表明拟合良好。 另一方面,LSTAT似乎低于 0。

  4. 从可视化继续,可以通过计算均方误差来量化拟合。 现在,我们将使用 Scikit-learn 进行此操作。 通过运行包含以下内容的单元格,定义一个计算最佳拟合线和均方误差的函数:

    def get_mse(df, feature, target='MEDV'):
        # Get x, y to model
        y = df[target].values
        x = df[feature].values.reshape(-1,1)
    ...
    ...
    error = mean_squared_error(y, y_pred)
        print('mse = {:.2f}'.format(error))
        print()

    注意

    有关完整的代码,请参考Lesson 1文件夹中的Lesson 1.txt文件。

    get_mse函数中,我们首先分别将变量yx分配给目标MDEV和从属特征。 通过调用values属性将它们强制转换为 NumPy 数组。 从属特征数组将重塑为 Scikit-learn 期望的格式; 仅在对一维特征空间建模时才需要这样做。 然后实例化模型并将其拟合到数据上。 对于线性回归,拟合包括使用普通最小二乘法(最小化每个样本的平方误差之和)来计算模型参数。 最后,在确定参数之后,我们预测目标变量并使用结果来计算 MSE。

  5. 通过运行包含以下内容的单元格,为RMLSTAT调用get_mse函数:

    get_mse(df, 'RM')
    get_mse(df, 'LSTAT')

    Linear models with Seaborn and scikit-learn

比较 MSE,结果发现LSTAT的误差略低。 但是,回头看散点图,似乎对于LSTAT使用多项式模型,我们可能会取得更大的成功。 在下一个活动中,我们将通过使用 Scikit-learn 计算一个三阶多项式模型来对此进行测试。

暂时忘掉我们的波士顿住房数据集,请考虑另一种可能使用多项式回归的现实情况。 以下示例是对天气数据进行建模。 在以下图表中,我们看到加拿大不列颠哥伦比亚省温哥华的温度(线)和降水量(条形图):

Linear models with Seaborn and scikit-learn

这些字段中的任何一个都可能很适合四阶多项式。 例如,如果您有兴趣预测连续日期范围内的温度或降水,这将是一个非常有价值的模型。

您可以在此处找到此数据源

活动 B:建立三阶多项式模型

将我们的注意力转移回波士顿住房数据集,我们想建立一个三阶多项式模型来与线性模型进行比较。 回想一下我们要解决的实际问题:在低阶层人口百分比的情况下,预测房屋中位数。 这种模式可以使潜在的波士顿购房者受益,他们关心他们的社区中有多少是低阶层。

给定LSTAT值,使用 Scikit-learn 拟合多项式回归模型来预测房屋中位数(MEDV)。 我们希望建立一个模型,该模型具有较低的均方误差(MSE)。

  1. 滚动到 Jupyter 笔记本中Subtopic C底部的空白单元格。 这些可以在Activity标题下的线性模型 MSE 计算单元下找到。

    注意

    在完成活动时,应使用代码填充这些空白单元格。 您可能需要在新单元格已填满时插入它们。 请根据需要这样做!

  2. 假定我们的数据包含在DataFrame``df中,我们将首先使用以下内容提取依赖特征和目标变量:

    y = df['MEDV'].values
    x = df['LSTAT'].values.reshape(-1,1)

    这与我们之前对线性模型所做的相同。

  3. 通过使用print(x[:3])打印前几个样本来检查x的外观:

    Activity B: Building a Third-Order Polynomial Model

    请注意,数组中的每个元素本身就是一个长度为 1 的数组。这是reshape(-1,1)的功能,它是 Scikit-learn 期望的形式。

  4. 接下来,我们将把x转换为“多项式特征”。 这样做的原理可能不会立即显而易见,但将在稍后进行解释。

    从 Scikit-learn 导入适当的转换工具并实例化三次多项式特征转换器:

    from sklearn.preprocessing import PolynomialFeatures
    poly = PolynomialFeatures(degree=3)
  5. 在这一点上,我们仅具有特征转换器的一个实例。 现在,让我们通过运行fit_transform方法来使用它来转换LSTAT特征(存储在变量x中)。

    通过运行以下代码来构建多项式特征集:

    x_poly = poly.fit_transform(x)
  6. 通过使用print(x_poly[:3])打印前几个样本来检查x_poly是什么样的。.

    Activity B: Building a Third-Order Polynomial Model

    x不同,现在每行中的数组的长度为 4,其中的值已计算为x[0]x[1]x[2]x[3]

    我们现在将使用此数据来拟合线性模型。 将特征标记为abcd,我们将计算系数α[0]α[1]α[2]α[3]的线性模型:

    Activity B: Building a Third-Order Polynomial Model

    我们可以插入abcd的定义,以获得以下多项式模型,其中系数与以前相同:

    Activity B: Building a Third-Order Polynomial Model

  7. 在计算 MSE 时,我们将以与以前相同的方式导入LinearRegression类并构建线性分类模型。 运行以下命令:

    from sklearn.linear_model import LinearRegression
    clf = LinearRegression()
    clf.fit(x_poly, y)
  8. 使用以下代码提取系数并打印多项式模型:

    a_0 = clf.intercept_ + clf.coef_[0] # intercept
    a_1, a_2, a_3 = clf.coef_[1:] 		# other coefficients
    msg = 'model: y = {:.3f} + {:.3f}x + {:.3f}x^2 + {:.3f}x^3'\
    		.format(a_0, a_1, a_2, a_3)
    print(msg)

    Activity B: Building a Third-Order Polynomial Model

    为了获得实际的模型截距,我们必须添加intercept_coef_[0]属性。 然后,高阶系数由coef_的剩余值给出。

  9. 通过运行以下代码,确定每个样本的预测值并计算残差:

    y_pred = clf.predict(x_poly)
    resid_MEDV = y - y_pred
  10. 通过运行print(resid_MEDV[:10])打印一些残值:

![Activity B: Building a Third-Order Polynomial Model](img/image1_129.jpg)

我们将尽快绘制这些图以与线性模型残差进行比较,但首先我们将计算 MSE。
  1. 运行以下代码以打印三阶多项式模型的 MSE:
```py
from sklearn.metrics import mean_squared_error
error = mean_squared_error(y, y_pred)
print('mse = {:.2f}'.format(error))
```

![Activity B: Building a Third-Order Polynomial Model](img/image1_131.jpg)

可以看出,与线性模型(38.5)相比,多项式模型的 **MSE** 明显更少。 通过取平方根,可以将该误差度量转换为以美元为单位的平均误差。 对多项式模型执行此操作,我们发现的平均误差中位数房屋价值仅为 5,300 美元。

现在,我们将通过绘制最佳拟合的多项式线和数据来可视化模型。
  1. 通过运行以下命令,将多项式模型与样本一起绘制:
```py
fig, ax = plt.subplots()
# Plot the samples
ax.scatter(x.flatten(), y, alpha=0.6)
# Plot the polynomial model
x_ = np.linspace(2, 38, 50).reshape(-1, 1)
x_poly = poly.fit_transform(x_)
y_ = clf.predict(x_poly)
ax.plot(x_, y_, color='red', alpha=0.8)
ax.set_xlabel('LSTAT'); ax.set_ylabel('MEDV');
```

![Activity B: Building a Third-Order Polynomial Model](img/image1_133.jpg)

在这里,我们通过在`x`值数组上计算多项式模型预测来绘制红色曲线。 `x`值数组是使用`np.linspace`创建的,导致 50 个值均匀排列在 2 和 38 之间。

现在,我们将绘制对应的残差。 尽管我们之前曾使用 Seaborn 进行过开发,但我们必须手动进行操作才能显示 Scikit-learn 模型的结果。 由于我们已经较早地计算了残差(作为`resid_MEDV`变量的参考),因此我们只需要在散点图上绘制此值列表即可。
  1. 通过运行以下命令绘制残差:
```py
fig, ax = plt.subplots(figsize=(5, 7))
ax.scatter(x, resid_MEDV, alpha=0.6)
ax.set_xlabel('LSTAT')
ax.set_ylabel('MEDV Residual $(y-\hat{y})$')
plt.axhline(0, color='black', ls='dotted');
```

![Activity B: Building a Third-Order Polynomial Model](img/image1_135.jpg)

与线性模型`LSTAT`残差图相比,多项式模型残差似乎更紧密地聚集在`y = 0`周围。 注意,`y`是样本`MEDV`,`ŷ`是预测值。 仍然存在清晰的模式,例如`x = 7`和`y = -7`附近的群集,这表明模型不是最佳的。

使用多项式模型成功建模数据后,让我们通过查看分类特征来结束本节。 特别是,我们将构建一组分类特征,并使用它们来更详细地探索数据集。

子主题 D:使用分类特征的细分分析

通常,我们发现数据集包含连续字段和分类字段。 在这种情况下,我们可以通过使用分类字段对连续变量进行分段来了解我们的数据并找到模式。

举一个具体的例子,假设您正在评估广告序列的投资回报率。 您可以访问的数据包含一些计算出的投资回报率ROI)度量的度量。 每天计算这些值并记录,您正在分析上一年的数据。 您的任务是寻找以数据为依据的见解,以改善广告序列。 查看 ROI 的每日时间序列,您会看到每周的数据波动。 按星期几细分,您会发现以下 ROI 分布(其中 0 代表一周的第一天,而 6 代表最后一天)。

Subtopic D: Using Categorical Features for Segmentation Analysis

此清楚地表明,该广告序列在一周开始时获得了最大的投资回报率,随后逐渐减少。 因此,建议可能是减少下周的广告支出。 为了继续寻找见解,您还可以想象对按月分组的 ROI 重复相同的过程。

由于在我们正在使用的波士顿房屋数据集中没有任何分类字段,因此我们将通过有效离散连续字段来创建一个分类字段。 在我们的案例中,这将涉及将数据分为“低”,“中”和“高”类别。 重要的是要注意,我们并不是简单地创建分类数据字段来说明本节中的数据分析概念。 可以看到,这样做可以从数据中揭示洞察力,否则这些洞察力将很难被发现或完全不可用。

从连续变量创建分类字段,并进行分段可视化

  1. 向上滚动到 Jupyter 笔记本中的对图,我们在其中比较了MEDVLSTATTAXAGERM

    Create categorical fieldscreatingcategorical fields from continuous variables and make segmented visualizations

    查看包含AGE的面板。 提醒一下,此特征定义为在 1940 年之前建造的自住单位比例。 我们将将此特征转换为分类变量。 转换后,我们将能够按照年龄类别对每个面板按颜色进行细分,以重新绘制该图形。

  2. 向下滚动至Subtopic D: Building and exploring categorical features,然后单击进入第一个单元格。 输入并执行以下命令以绘制AGE累积分布:

    sns.distplot(df.AGE.values, bins=100,
    			hist_kws={'cumulative': True},
    			kde_kws={'lw': 0})
    plt.xlabel('AGE')
    plt.ylabel('CDF')
    plt.axhline(0.33, color='red')
    plt.axhline(0.66, color='red')
    plt.xlim(0, df.AGE.max());

    Create categorical fieldscreatingcategorical fields from continuous variables and make segmented visualizations

    注意,我们设置kde_kws={'lw': 0}是为了绕过上图中绘制核密度估计值的过程。

    从图中的看,只有很少的样本具有较低的AGE,而有更多的样本具有较高的AGE。 这通过最右边的分布的陡度来表示。

    红线表示分布中的 1/3 和 2/3 点。 观察分布分布与这些水平线相交的地方,我们可以看到,只有约 33% 的样本的AGE小于 55,而 33% 的样本的AGE大于 90! 换句话说,三分之一的住房社区在 1940 年之前建造房屋的比例不到 55%。这些社区被认为是相对较新的社区。 另一方面,另外三分之一的住房社区在 1940 年之前建造了超过 90% 的房屋。这些房屋被认为是非常古老的。

    我们将使用红色水平线截取分布的位置作为将特征划分为类别的指导:相对较新相对较旧较旧

  3. 将分段点设置为 50 和 85,通过运行以下代码来创建新的分类特征:

    def get_age_category(x):
    	if x < 50:
    		return 'Relatively New'
    	elif 50 <= x < 85:
    		return 'Relatively Old'
    	else:
    	return 'Very Old'
    df['AGE_category'] = df.AGE.apply(get_age_category)

    在这里,我们使用非常方便的 Pandas 方法apply,该方法将函数应用于给定的列或一组列。 在本例中为get_age_category时,所应用的函数应采用一个表示一行数据的参数,并为新列返回一个值。 在这种情况下,要传递的数据行只是一个值,即样本的AGE

    注意

    apply方法之所以出色,是因为它可以解决各种问题并允许易于阅读的代码。 但是,向量化方法(例如pd.Series.str)通常可以更快地完成同一件事。 因此,建议尽可能避免使用它,尤其是在处理大型数据集时。 在接下来的课程中,我们将看到一些向量化方法的示例。

  4. 通过在新单元格中键入df.groupby('AGE_category').size()并运行它,检查我们将每个年龄组归类了多少个样本:

    Create categorical fieldscreatingcategorical fields from continuous variables and make segmented visualizations

    查看结果,可以看出两个类别的人数相当相等,而“非常老”的一类人大约大 40%。 我们有兴趣保持类的大小可比,以使每个类都有很好的表示,并且可以直接从分析中进行推断。

    注意

    并非总是可以将样本均匀地分配给类,在现实世界中,找到高度不平衡的类是很常见的。 在这种情况下,请务必牢记,对于人数不足的类别很难做出具有统计意义的声明。 类不平衡的预测分析可能特别困难。 以下博客文章提供了有关在进行机器学习时处理不平衡类的方法的出色总结

    让我们看看通过新函数AGE_category进行细分时目标变量的分布情况。

  5. 通过运行以下代码制作提琴图:

    sns.violinplot(x='MEDV', y='AGE_category', data=df,
    				order=['Relatively New', 'Relatively Old', 'Very Old']);

    Create categorical fieldscreatingcategorical fields from continuous variables and make segmented visualizations

    提琴图显示了每个年龄类别的房屋中值分布的核密度估计。 我们看到它们都类似于正态分布。 “非常老”组的房价中位数样本最低,并且宽度相对较大,而其他组则更紧密地围绕其平均值。 青年组偏向高端,这可以从右半部分的放大和白点在分布主体内的粗黑线中的位置明显看出。

    这个白点代表平均值,粗黑线跨越了大约 50% 的总体(填充到白点两侧的第一个分位数)。 黑色的细线代表箱线图的胡须,覆盖 95% 的人口。 通过将inner='point'传递给sns.violinplot(),可以修改此内部可视化以显示各个数据点。 现在开始吧。

  6. 重做提琴图,将inner='point'参数添加到sns.violinplot调用中:

    Create categorical fieldscreatingcategorical fields from continuous variables and make segmented visualizations

    为了进行测试,最好制作这样的图,以查看基础数据如何连接到视觉。 例如,我们可以看到相对新细分市场的房价中位数如何不低于约$ 16,000,因此因此分配尾部实际上不包含任何数据。 由于我们的数据集较小(仅约 500 行),我们可以看到每个细分市场都是这种情况。

  7. 重做先前的对图,但现在为每个AGE类别包括颜色标签。 这可以通过简单地传递hue参数来完成,如下所示:

    cols = ['RM', 'AGE', 'TAX', 'LSTAT', 'MEDV', 'AGE_category']
    sns.pairplot(df[cols], hue='AGE_category',
    			hue_order=['Relatively New', 'Relatively Old', 'Very Old'],
    			plot_kws={'alpha': 0.5}, diag_kws={'bins': 30});

    Create categorical fieldscreatingcategorical fields from continuous variables and make segmented visualizations

    查看直方图上的,对于RMTAX,每个段的基础分布显得相似。 另一方面,LSTAT分布看起来更加不同。 我们可以再次使用提琴图来更详细地关注它们。

  8. 制作一个提琴图,比较每个AGE_category段的LSTAT分布:

    Create categorical fieldscreatingcategorical fields from continuous variables and make segmented visualizations

MEDV提琴图不同,在每个提琴图中,分布图的宽度大致相同,而这里的宽度随AGE的增加而增加。 以旧房屋为主的社区(“非常旧”的部分)的居民数量很少,甚至很多,而相对较新的社区更可能是较高阶级的人群,超过 95% 的样本的低阶级百分比低于“非常旧”的社区。 这是有道理的,因为相对而言,新街区会更昂贵。

总结

在本课程中,您已经了解了 Jupyter 中数据分析的基础。

我们从 Jupyter 的用法说明和功能开始,例如魔术功能和制表符补全。 然后,过渡到特定于数据科学的材料,我们介绍了使用 Python 进行数据科学最重要的库。

在课程的后半部分,我们在现场 Jupyter 笔记本中进行了探索性分析。 在这里,我们使用了视觉辅助工具,例如散点图,直方图和提琴图,以加深我们对数据的理解。 我们还执行了简单的预测建模,这是本书下一课的重点。

在下一课中,我们将讨论如何进行预测分析,在准备用于建模的数据时应考虑的事项以及如何使用 Jupyter 笔记本实现和比较各种模型。