IBM-数据科学-VII-笔记-全-

IBM 数据科学 VII 笔记(全)

001:问题定义

在本节课中,我们将学习数据分析的基本概念,并通过一个具体场景——帮助朋友汤姆确定其二手车的合理售价——来理解如何定义数据分析问题。


数据分析的重要性

在我们开始讨论具体问题之前,首先需要理解数据分析的重要性。

数据在我们周围无处不在。无论是科学家手动收集的数据,还是每次点击网站或移动设备时自动生成的数字数据,我们都被数据包围。

但数据本身并不等同于信息。数据分析,乃至数据科学的核心,正是帮助我们从原始数据中解锁信息和洞察,从而回答我们的问题。

因此,数据分析扮演着至关重要的角色。它帮助我们:

  • 从数据中发现有用信息。
  • 回答问题。
  • 甚至预测未来或未知的事物。

问题场景引入

现在,让我们从一个具体场景开始。

假设我们有一个名叫汤姆的朋友。汤姆想要卖掉他的汽车。但问题是,他不知道应该为他的车定价多少。

汤姆希望尽可能以高价卖出他的车。但同时,他也希望设定一个合理的价格,以便有人愿意购买。因此,他设定的价格应该能够反映这辆车的价值。

那么,我们如何帮助汤姆确定他汽车的最佳售价呢?


像数据科学家一样思考

让我们像数据科学家一样思考,并清晰地定义他面临的问题。

以下是我们可以开始思考的一些关键问题:

  • 是否存在关于其他汽车价格及其特征的数据?
  • 汽车的哪些特征会影响其价格?是颜色、品牌吗?
  • 马力是否也会影响售价?或者还有其他因素?

作为一名数据分析师或数据科学家,这些都是我们可以着手探索的问题。

为了回答这些问题,我们将需要一些数据。在接下来的视频中,我们将深入探讨如何理解数据、如何将其导入Python,以及如何开始从数据中获取一些基本洞察。


本节总结

本节课中,我们一起学习了数据分析的目的与重要性,并通过“帮助汤姆为二手车定价”的实际案例,初步体验了如何像数据科学家一样定义问题、提出关键疑问,为后续的数据收集与分析工作奠定了基础。

002:数据理解 🚗

在本节课中,我们将学习如何理解一个用于数据分析的数据集。我们将以二手车价格数据集为例,介绍数据集的基本结构、各列的含义,并明确数据分析的目标。


数据集概览

本节课使用的数据集是Jeffrey C. Schlimmer提供的一个开放数据集。该数据集采用CSV格式,其特点是用逗号分隔每个值,这使得它能够轻松导入到大多数工具或应用程序中。

每一行代表数据集中的一个数据记录。在本模块的实践练习中,你将能够下载并使用这个CSV文件。

数据格式与结构

你注意到第一行有什么不同吗?有时,第一行是标题行,包含26列中每一列的列名。但在本例中,第一行只是另一行数据。

以下是关于26列中每一列含义的文档说明。列的数量很多,我将只介绍其中几个列名,你也可以查看幻灯片底部的链接以自行查阅详细描述。

以下是数据集中的部分关键属性及其含义:

  • symboling:对应车辆的保险风险等级。车辆最初会根据其价格被分配一个风险系数符号。如果一辆车的风险更高,这个符号会通过向上调整等级来修正。值为+3表示该汽车风险很高,-3则表示可能非常安全。
  • normalized-losses:指每辆受保车辆每年的相对平均损失赔付额。该值针对特定尺寸分类(如双门小型旅行车、运动型专用车等)内的所有汽车进行了标准化,代表每辆车每年的平均损失。其值范围在65到256之间。
  • 其他属性相对容易理解。如果你想查看更多详细信息,请参考幻灯片底部的链接。

分析目标:预测价格

在我们理解了每个特征的含义之后,我们会注意到第26个属性是price(价格)。这是我们的目标值或标签。

换句话说,这意味着价格是我们希望从数据集中预测的值,而预测因子应该是列出的所有其他变量,如symboling、normalized-losses、make(品牌)等等。

因此,本项目的目标是根据其他汽车特征来预测价格。

需要快速说明的是,这个数据集实际上来自1985年,因此其中车型的价格可能看起来有点低。但请记住,本练习的目标是学习如何分析数据。


在本节课中,我们一起学习了二手车价格数据集的基本情况,包括其CSV格式、数据结构、关键列的含义,并明确了数据分析的核心目标是利用其他特征来预测汽车价格。理解数据是进行有效分析的第一步。

003:Python数据科学核心包介绍

在本节课中,我们将学习使用Python进行数据分析时所需的核心库。这些库提供了强大的工具和函数,使我们能够高效地处理、分析和可视化数据,而无需从零开始编写大量代码。


🧩 Python库是什么?

一个Python库是函数和方法的集合,它允许你执行许多操作而无需编写任何代码。

库通常包含内置模块,提供可以直接使用的不同功能。此外,还有功能广泛的库,提供广泛的服务。

我们将Python数据分析库分为三组。


🔬 第一组:科学计算库

上一部分我们了解了库的基本概念,本节中我们来看看第一组核心库——科学计算库。它们为数据处理和数值计算提供了基础。

以下是主要的科学计算库:

  • Pandas:提供用于高效数据操作和分析的数据结构和工具。它提供了对结构化数据的便捷访问。Pandas的主要工具是一个由列和行标签组成的二维表,称为 DataFrame。它旨在提供简单的索引功能。
  • NumPy:该库使用数组作为其输入和输出。它可以扩展到矩阵对象,开发者只需进行少量代码修改即可执行快速的数组处理。
  • SciPy:包含用于解决一些高级数学问题的函数(如本幻灯片所列),以及数据可视化功能。


🎨 第二组:数据可视化库

使用数据可视化方法是与他人交流、展示分析有意义结果的最佳方式。这些库使你能够创建图表和地图。

以下是主要的数据可视化库:

  • Matplotlib:这是最著名的数据可视化库包。它非常适合制作图形和图表,并且图表具有高度可定制性。
  • Seaborn:这是另一个高级可视化库,它基于Matplotlib。它可以非常轻松地生成各种图表,例如热力图、时间序列图和小提琴图。

🤖 第三组:机器学习算法库

通过机器学习算法,我们能够使用数据集开发模型并获得预测。算法库处理从基础到复杂的机器学习任务。

以下是两个重要的机器学习库:

  • Scikit-learn:该库包含统计建模工具,包括回归、分类、聚类等。这个库建立在NumPy、SciPy和Matplotlib之上。
  • Statsmodels:这也是一个Python模块,允许用户探索数据、估计统计模型和执行统计检验。


📝 总结

本节课中,我们一起学习了Python数据分析的三大类核心库:科学计算库(如Pandas, NumPy, SciPy)、数据可视化库(如Matplotlib, Seaborn)以及机器学习算法库(如Scikit-learn, Statsmodels)。理解这些库的用途是开始高效数据分析的第一步。

004:Python数据导入导出

在本节课中,我们将学习如何使用Python的pandas包来读取和写入数据。数据获取是数据分析的第一步,掌握如何高效地将数据加载到Python环境中至关重要。我们将从理解数据格式和文件路径开始,逐步学习如何读取CSV文件、查看数据、修改列名,以及如何将处理后的数据导出保存。

数据获取概述

数据获取是一个从各种来源加载和读取数据到笔记本的过程。使用Python的pandas包读取数据时,需要考虑两个重要因素:格式文件路径

理解数据格式与路径

上一节我们介绍了数据获取的基本概念,本节中我们来看看决定数据读取的两个关键因素。

格式指的是数据的编码方式。我们通常可以通过查看文件名的后缀来识别不同的编码方案。

以下是一些常见的编码格式:

  • CSV
  • JSON
  • XLSX
  • HDF

路径则告诉我们数据存储的位置。数据通常存储在我们正在使用的计算机本地,或者存储在互联网上。

在我们的案例中,我们找到了一个二手车数据集,它来自幻灯片上显示的网址。

读取CSV格式数据

当我们访问该网址时,会看到类似这样的数据。每一行代表一个数据点,每个数据点关联着大量属性。由于属性之间用逗号分隔,我们可以推断数据格式是CSV,即逗号分隔值。

此时,这些数据对人类来说只是一串数字,意义不大。但一旦我们读入这些数据,就可以尝试理解它。在pandas中,read_csv方法可以将以逗号分隔列的文件读入一个pandas数据框。

使用pandas读取数据可以快速通过三行代码完成。

首先,导入pandas库:

import pandas as pd

然后,定义一个包含文件路径的变量:

path = “ https://archive.ics.uci.edu/ml/machine-learning-databases/autos/imports-85.data ”

接着,使用read_csv方法导入数据:

df = pd.read_csv(path)

处理无表头数据及数据预览

然而,read_csv方法默认假设数据包含表头。我们的二手车数据没有列标题,因此需要通过设置header=None来指定read_csv不分配表头。

df = pd.read_csv(path, header=None)

读取数据集后,最好查看一下数据框,以获得更直观的感受,并确保一切按预期进行。

由于打印整个数据集可能耗费太多时间和资源,为了节省时间,我们可以使用dataframe.head()来显示数据框的前N行。

df.head(5)

类似地,dataframe.tail()显示数据框的底部N行。

df.tail(5)

这里我们打印出了前五行数据。看起来数据集读取成功。我们可以看到,pandas自动将列标题设置为整数列表,因为我们在读取数据时设置了header=None

为数据框添加列名

没有有意义的列名,处理数据框会很困难。不过,我们可以在pandas中分配列名。

在我们的案例中,我们发现列名存储在一个单独的在线文件中。我们首先将列名放入一个名为headers的列表中。

headers = [“symboling”, “normalized-losses”, “make”, “fuel-type”, ...] # 此处应为完整的列名列表

然后,我们设置df.columns = headers,用这个列表替换默认的整数标题。

df.columns = headers

如果我们使用上一节介绍的head方法来检查数据集,会看到正确的标题已插入每列的顶部。

导出数据到CSV文件

在某个时间点,当你对数据框完成操作后,可能希望将pandas数据框导出到一个新的CSV文件。

你可以使用to_csv方法来实现。为此,需要指定文件路径,其中包含你想要写入的文件名。

例如,如果你想将数据框df保存为automobile.csv到你的电脑上,可以使用以下语法:

df.to_csv(“automobile.csv”)

支持的其他数据格式

本课程我们只涉及读取和保存CSV文件。然而,pandas也支持导入和导出大多数具有不同数据集格式的数据文件类型。

读取和保存其他数据格式的代码语法与读取或保存CSV文件非常相似。

以下列表展示了针对不同格式的读写方法:

  • 读取JSON: pd.read_json()
  • 保存为JSON: df.to_json()
  • 读取Excel: pd.read_excel()
  • 保存为Excel: df.to_excel()
  • 读取HDF5: pd.read_hdf()
  • 保存为HDF5: df.to_hdf()

课程总结

本节课中我们一起学习了使用Python的pandas库进行数据导入和导出的核心技能。我们从理解数据格式和路径开始,详细演练了如何读取无表头的CSV文件、预览数据、为数据框添加有意义的列名,以及如何将处理后的数据保存为新文件。最后,我们还了解到pandas支持多种数据格式,其操作方法大同小异。掌握这些基础操作是进行后续数据分析的坚实第一步。

005:Python数据科学核心包

在本节课中,我们将要学习使用Python进行数据分析时所需的核心库。这些库提供了强大的工具和功能,使我们能够高效地处理、分析和可视化数据,而无需从零开始编写大量代码。

什么是Python库?

一个Python库是一个函数和方法的集合,它允许你在不编写任何代码的情况下执行大量操作。

库通常包含内置模块,提供不同的功能,你可以直接使用。此外,还有功能广泛的库,提供广泛的服务。

我们将Python数据分析库分为三组。

第一组:科学计算库

上一节我们介绍了Python库的基本概念,本节中我们来看看第一组核心库——科学计算库。这些库是数据处理和分析的基础。

Pandas 🐼

Pandas提供了用于高效数据操作和分析的数据结构和工具。它提供了对结构化数据的快速访问。Pandas的主要工具是一个由列和行标签组成的二维表,称为DataFrame

它旨在提供简单的索引功能。

NumPy 🔢

NumPy库使用数组作为其输入和输出。它可以扩展到矩阵对象,并且通过少量的代码更改,开发人员可以执行快速的数组处理。

SciPy 🔬

SciPy包含用于处理一些高级数学问题的函数,以及数据可视化功能。

第二组:数据可视化库

使用数据可视化方法是与他人沟通、展示分析有意义结果的最佳方式。这些库使你能够创建图形、图表和地图。

Matplotlib 📈

Matplotlib包是最著名的数据可视化库。它非常适合制作图形和图表。这些图表也具有高度可定制性。

Seaborn 🎨

另一个高级可视化库是Seaborn。它基于Matplotlib。它可以非常轻松地生成各种图表,例如热图、时间序列图和小提琴图。

第三组:机器学习算法库

通过机器学习算法,我们能够使用数据集开发模型并获得预测。算法库处理从基础到复杂的机器学习任务。以下是两个重要的包。

Scikit-learn 🤖

Scikit-learn库包含统计建模工具,包括回归、分类、聚类等。这个库建立在NumPy、SciPy和Matplotlib之上。

Statsmodels 📊

Statsmodels也是一个Python模块,允许用户探索数据、估计统计模型和执行统计检验。


本节课中我们一起学习了Python数据分析的三大核心库组:科学计算库(Pandas, NumPy, SciPy)、数据可视化库(Matplotlib, Seaborn)以及机器学习算法库(Scikit-learn, Statsmodels)。理解这些库的功能和用途是高效进行数据分析的关键第一步。

006:Pandas数据分析入门 🔍

在本节课中,我们将学习一些简单的Pandas方法,这些方法是所有数据科学家和分析师在使用Python进行数据分析时必须掌握的。我们将重点介绍如何检查数据类型、查看数据分布以及识别潜在的数据问题。


数据探索:检查数据类型

上一节我们介绍了数据加载的基本步骤。本节中,我们来看看如何探索数据集。

Pandas内置了多种方法,可用于理解特征的数据类型或查看数据在数据集中的分布情况。使用这些方法可以快速获得数据集的概览,并指出潜在问题,例如特征的数据类型错误,这些问题可能需要在后续步骤中解决。

数据有多种类型。Pandas中存储的主要类型是objectfloatintdatetime。这些数据类型名称与原生Python中的类型名称略有不同。

以下是Pandas数据类型与Python原生数据类型的对比:

Pandas 类型 Python 原生类型 描述
object str 文本或混合类型
int64 int 整数
float64 float 浮点数
datetime64 datetime 日期和时间

一些类型非常相似,例如数值数据类型intfloat。Pandas的object类型功能类似于Python中的string,只是名称不同。而datetime类型对于处理时间序列数据非常有用。

检查数据集中的数据类型主要有两个原因。

首先,Pandas会根据从原始数据表读取的编码自动分配类型。由于多种原因,这种分配可能不正确。例如,如果汽车价格列(我们预期它包含连续的数值)被分配了object数据类型,这就会很棘手。更自然的情况是它应该具有float类型。因此,我们可能需要手动将数据类型更改为float

第二个原因是,它让有经验的数据科学家能够了解哪些Python函数可以应用于特定列。例如,一些数学函数只能应用于数值数据。如果将这些函数应用于非数值数据,可能会导致错误。

当对数据集应用.dtypes方法时,会返回一个包含每列数据类型的Series。一个优秀数据科学家的直觉会告诉我们,大多数数据类型是合理的。

例如,汽车的品牌是名称,因此此信息应为object类型。

列表中的最后一行可能存在问题。由于“bore”是发动机的一个尺寸维度,我们应期望使用数值数据类型。然而,这里却使用了object类型。在后面的章节中,我们将需要纠正这些类型不匹配的问题。


数据探索:查看统计摘要

现在,我们想检查每列的统计摘要,以了解每列数据的分布情况。统计指标可以告诉数据科学家是否存在数学问题,例如极端异常值和大的偏差。数据科学家可能需要在后续处理这些问题。

要获取快速统计数据,我们使用.describe()方法。它返回列中的条目数(count)、列值的平均值(mean)、列标准差(std)、最大值、最小值以及每个四分位数的边界。

默认情况下,DataFrame.describe()函数会跳过不包含数字的行和列。也可以让describe方法适用于object类型的列。为了启用对所有列的摘要,我们可以在describe函数括号内添加参数include='all'

现在,结果显示了对所有26列的摘要,包括对象类型的属性。我们看到,对于object类型列,评估了一组不同的统计信息,如uniquetopfreq

以下是这些统计量的含义:

  • unique:列中不同对象的数量。
  • top:出现频率最高的对象。
  • freqtop对象在列中出现的次数。

表中的一些值显示为NaN,代表“Not a Number”。这是因为无法针对该特定列的数据类型计算该特定统计指标。

您可以使用的另一个检查数据集的方法是DataFrame.info()函数。此函数显示数据帧的前30行和后30行。


总结

本节课中,我们一起学习了Pandas数据分析的入门知识。我们介绍了如何检查数据集的数据类型,理解了Pandas与Python原生类型的区别,并探讨了检查数据类型的两个主要原因。我们还学习了如何使用.describe()方法获取数据的统计摘要,包括数值列和对象类型列的不同统计信息。这些方法是数据探索的基础,能帮助我们快速了解数据概况并发现潜在问题,为后续的数据清洗和分析做好准备。

007:Python数据库访问

在本节课中,我们将学习如何使用Python访问数据库。数据库是数据科学家的重要工具。完成本模块后,你将能够解释使用Python连接数据库的基本概念。

🔗 数据库访问概述

上一节我们介绍了数据分析的背景,本节中我们来看看如何使用Python与数据库进行交互。

一个典型的用户通过编写在Jupyter Notebook(一种基于网页的编辑器)中的Python代码来访问数据库。Python程序通过一种机制与数据库管理系统(DBMS)进行通信。Python代码使用API调用来连接数据库。

我们将解释SQL API和Python DB API的基础知识。

🛠️ SQL API 基础

应用程序编程接口(API)是一组你可以调用的函数,用于访问某种类型的服务。SQL API由库函数调用组成,作为DBMS的应用程序编程接口,用于将SQL语句传递给DBMS。应用程序调用API中的函数,并调用其他函数从DBMS检索查询结果和状态信息。

下图展示了一个典型SQL API的基本操作流程:

应用程序通过一个或多个API调用来开始其数据库访问,这些调用将程序连接到DBMS。为了向DBMS发送SQL语句,程序在缓冲区中将语句构建为文本字符串,然后进行API调用以将缓冲区内容传递给DBMS。

应用程序进行API调用来检查其DBMS请求的状态并处理错误。

应用程序通过一个断开与数据库连接的API调用来结束其数据库访问。

🐍 Python DB API 简介

Python DB API是用于访问关系型数据库的Python标准API。它是一个标准,允许你编写一个适用于多种关系型数据库的单一程序,而无需为每种数据库编写单独的程序。因此,如果你学会了DB API函数,就可以将这些知识应用于使用Python连接任何数据库。

Python DB API中的两个主要概念是连接对象游标对象

  • 连接对象:用于连接到数据库并管理事务。
  • 游标对象:用于运行查询。你打开一个游标对象,然后运行查询。游标的工作方式类似于文本处理系统中的光标,你可以在结果集中向下滚动并将数据获取到应用程序中。游标用于遍历数据库的结果。

以下是连接对象常用的方法:

  • cursor():使用连接返回一个新的游标对象。
  • commit():用于将任何挂起的事务提交到数据库。
  • rollback():使数据库回滚到任何挂起事务的开始状态。
  • close():用于关闭数据库连接。

💻 实践:使用DB API查询数据库

让我们通过一个Python应用程序来实践如何使用DB API查询数据库。

以下是操作步骤:

  1. 导入数据库模块并建立连接:首先,从相应的数据库模块导入connect API,并使用该函数打开与数据库的连接。你需要传入数据库名称、用户名和密码等参数。connect函数返回一个连接对象。
    import sqlite3  # 示例:导入SQLite模块
    conn = sqlite3.connect('example.db')  # 建立连接
    

  1. 创建游标对象:在连接对象上创建一个游标对象。游标用于运行查询和获取结果。

    cursor = conn.cursor()
    
  2. 执行查询并获取结果:使用游标运行SQL查询,然后使用游标获取查询结果。

    cursor.execute('SELECT * FROM my_table')
    results = cursor.fetchall()
    for row in results:
        print(row)
    
  3. 关闭连接:当系统完成查询后,通过关闭连接来释放所有资源。

    conn.close()
    

请记住,始终关闭连接以避免未使用的连接占用资源,这一点非常重要。

📝 课程总结

本节课中,我们一起学习了使用Python访问数据库的核心知识。我们介绍了SQL API的基本概念和工作流程,重点讲解了Python DB API标准及其两个核心对象:连接对象和游标对象。最后,我们通过一个简单的代码示例,实践了连接数据库、执行查询和关闭连接的完整流程。掌握这些基础是使用Python进行高效数据操作的关键一步。

感谢观看本视频。

008:Python数据导入与导出

在本节课中,我们将学习如何使用Python的pandas包来读取和导出数据。掌握数据导入是进行后续所有数据分析步骤的基础。

数据获取概述

数据获取是一个从各种来源加载和读取数据到笔记本的过程。使用Python的pandas包读取数据时,需要考虑两个重要因素:数据格式文件路径

理解数据格式与路径

上一节我们介绍了数据获取的基本概念,本节中我们来看看格式和路径的具体含义。

格式指的是数据的编码方式。我们通常可以通过查看文件名的后缀来识别不同的编码方案。

以下是一些常见的编码格式:

  • CSV
  • JSON
  • XLSX
  • HDF

路径则告诉我们数据存储的位置。数据通常存储在我们正在使用的计算机上,或者存储在互联网上。

在我们的案例中,我们找到了一个二手车数据集,它来自幻灯片上显示的网址。当Jerry在网页浏览器中输入该网址时,他看到了类似这样的内容。每一行代表一个数据点,每个数据点都关联着大量属性。由于属性之间用逗号分隔,我们可以推测数据格式是CSV,即“逗号分隔值”。目前,这些只是数字,对人类来说意义不大。但一旦我们读入这些数据,就可以尝试理解它。

在pandas中,read_csv方法可以将以逗号分隔列的文件读入一个pandas DataFrame。

使用Pandas读取CSV数据

了解了数据的基本信息后,我们来看看如何用代码实现数据读取。

在pandas中,读取数据可以快速通过三行代码完成。

以下是读取数据的基本步骤:

  1. 首先,导入pandas库。
    import pandas as pd
    
  2. 然后,定义一个包含文件路径的变量。
    file_path = “path/to/your/data.csv”
    
  3. 接着,使用read_csv方法导入数据。
    df = pd.read_csv(file_path)
    

然而,read_csv方法默认假设数据包含表头(即列名)。我们的二手车数据没有列标题,因此需要通过设置header=None来指定read_csv不分配表头。

df = pd.read_csv(file_path, header=None)

查看与检查数据

成功读取数据集后,最好查看一下DataFrame,以获得更直观的感受,并确保一切按预期进行。

由于打印整个数据集可能耗费太多时间和资源,为了节省时间,我们可以使用DataFrame.head()方法来显示DataFrame的前N行。

df.head(5) # 显示前5行

类似地,DataFrame.tail()方法显示DataFrame的底部N行。

df.tail(5) # 显示后5行

这里我们打印出了前五行数据。看起来数据集读取成功。我们可以看到,由于我们在读取数据时设置了header=None,pandas自动将列标题设置为整数列表。

为数据添加列名

没有有意义的列名,处理DataFrame会很困难。不过,我们可以在pandas中分配列名。

在我们当前的案例中,我们发现列名存储在一个单独的在线文件中。

我们首先将列名放入一个名为headers的列表中。

headers = [“column1”, “column2”, “column3”, …] # 替换为实际的列名列表

然后,我们设置df.columns = headers,用这个列表替换默认的整数标题。

df.columns = headers

如果我们使用上一节介绍的head方法来检查数据集,会看到正确的标题已插入每列的顶部。

导出数据到CSV文件

在某些时候,在对DataFrame进行操作之后,您可能希望将pandas DataFrame导出到一个新的CSV文件中。

您可以使用to_csv方法来实现。为此,需要指定文件路径,其中包含您要写入的文件名。

例如,如果您想将DataFrame df保存为automobile.csv到您的计算机上,可以使用以下语法:

df.to_csv(“automobile.csv”)

支持的其他数据格式

本课程我们只涉及读取和保存CSV文件;然而,pandas也支持导入和导出大多数具有不同数据集格式的数据文件类型。

读取和保存其他数据格式的代码语法与读取或保存CSV文件非常相似。

以下列表展示了针对不同格式的读写方法:

  • JSON: pd.read_json()df.to_json()
  • Excel: pd.read_excel()df.to_excel()
  • HDF5: pd.read_hdf()df.to_hdf()

课程总结

本节课中,我们一起学习了使用Python的pandas库进行数据导入与导出的核心操作。我们了解了数据格式和路径的重要性,掌握了使用read_csv读取CSV文件(包括处理无表头数据)的方法,学会了使用headtail查看数据,以及如何为DataFrame添加有意义的列名。最后,我们还学习了使用to_csv导出数据,并了解到pandas支持多种其他数据格式的读写。这些技能是进行有效数据分析的第一步。

009:Pandas数据探索基础方法

在本节课中,我们将学习使用Pandas库进行数据分析时,数据科学家和分析师必须掌握的几个基础方法。这些方法能帮助我们快速理解数据集的结构、数据类型以及数据分布,为后续的数据清洗和分析工作打下基础。


🔍 数据探索的重要性

上一节我们介绍了如何加载数据。本节中,我们来看看如何对已加载的数据集进行初步探索。

Pandas内置了多种方法,可用于理解特征的数据类型或查看数据集中的数据分布。使用这些方法可以获得数据集的概览,并指出潜在问题,例如特征的数据类型错误,这些问题可能需要在后续步骤中解决。


📝 数据类型概述

数据有多种类型。Pandas中存储的主要类型是objectfloatintdatetime。这些数据类型的名称与原生Python中的类型名称略有不同。

下表展示了它们之间的差异与相似之处:

Pandas 类型 类似 Python 类型 描述
object str 文本或混合类型
int64 int 整数
float64 float 浮点数
datetime64 datetime 日期时间

有些类型非常相似,例如数值数据类型intfloat。Pandas的object类型功能类似于Python中的string,只是名称不同。而datetime类型对于处理时间序列数据非常有用。


✅ 检查数据类型的两个原因

检查数据集中的数据类型主要有两个原因。

第一个原因是数据类型的自动分配可能不正确。 Pandas会根据从原始数据表读取的编码自动分配类型。由于多种原因,这种分配可能出错。例如,我们期望包含连续数值的“汽车价格”列,如果被分配为object类型就会很奇怪。将其设为float类型更为自然。因此,我们可能需要手动将数据类型更改为float

第二个原因是它让有经验的数据科学家了解可以对特定列应用哪些Python函数。 例如,某些数学函数只能应用于数值数据。如果将这些函数应用于非数值数据,可能会导致错误。


🛠️ 使用.dtypes方法

当对数据集应用.dtypes方法时,会返回一个包含每列数据类型的Series。优秀数据科学家的直觉告诉我们,大多数数据类型应该是合理的。

例如,汽车的品牌(Make)是名称,因此该信息应为object类型。

列表中的最后一行(bore)可能有问题。由于bore是发动机的一个尺寸维度,我们应期望使用数值数据类型。然而,这里却使用了object类型。在后面的章节中,我们需要纠正这些类型不匹配的问题。


📊 使用.describe()方法检查统计摘要

现在,我们想检查每列的统计摘要,以了解每列的数据分布情况。统计指标可以告诉数据科学家是否存在数学问题,例如极端异常值和大的偏差。数据科学家可能需要在后续处理这些问题。

要获取快速统计数据,我们使用.describe()方法。它默认返回数值列的以下统计信息:

  • count:列中非空值的数量
  • mean:列的平均值
  • std:列的标准差
  • min:最小值
  • 25%:第一四分位数
  • 50%:中位数
  • 75%:第三四分位数
  • max:最大值

默认情况下,DataFrame.describe()函数会跳过不包含数字的行和列。也可以让describe方法对object类型的列起作用。为了启用对所有列的摘要,我们可以在describe()函数括号内添加参数include='all'

现在,结果显示所有26列的摘要,包括对象类型的属性。我们看到,对于object类型的列,评估的是一组不同的统计信息,如uniquetopfreq

  • unique:列中不同对象的数量。
  • top:出现频率最高的对象。
  • freq:最高频对象在列中出现的次数。

表中的某些值显示为NaN,代表“Not a Number”。这是因为该特定的统计指标无法针对该特定列的数据类型进行计算。


ℹ️ 使用.info()方法

您可以使用的另一个检查数据集的方法是DataFrame.info()函数。此函数显示数据帧的前30行和后30行,并提供每列的非空值数量及数据类型等概览信息。


🎯 总结

本节课中,我们一起学习了使用Pandas进行数据探索的基础方法。我们了解了检查数据类型的重要性,学会了使用.dtypes查看类型,使用.describe()获取统计摘要,以及使用.info()快速浏览数据框结构。这些步骤是任何数据分析项目的起点,能帮助我们快速识别数据中的潜在问题,为后续的数据清洗和建模做好准备。

010:使用Python访问数据库 🗄️

在本节课中,我们将学习如何使用Python连接和操作数据库。数据库是数据科学家的重要工具,掌握Python访问数据库的方法能让你更高效地处理和分析数据。

概述:Python与数据库的交互

上一节我们介绍了数据分析的基础工具,本节中我们来看看如何让Python与数据库系统进行通信。

一个典型的用户通过编写在Jupyter Notebook(一种基于网页的编辑器)中的Python代码来访问数据库。Python程序通过一种机制与数据库管理系统(DBMS)进行通信。具体来说,Python代码通过API调用来连接数据库。

我们将解释SQL API和Python DB API的基础知识。

SQL API 基础

应用程序编程接口(API)是一组函数,你可以调用它们来获取某种服务。SQL API由库函数调用组成,作为DBMS的应用程序编程接口,用于将SQL语句传递给DBMS。应用程序调用API中的函数,并调用其他函数从DBMS检索查询结果和状态信息。

下图展示了一个典型SQL API的基本操作流程:

  1. 连接数据库:应用程序通过一个或多个API调用来开始其数据库访问,这些调用将程序连接到DBMS。
  2. 发送SQL语句:为了向DBMS发送SQL语句,程序在缓冲区中将语句构建为文本字符串,然后进行API调用以将缓冲区内容传递给DBMS。
  3. 检查状态与处理错误:应用程序进行API调用来检查其DBMS请求的状态并处理错误。
  4. 断开连接:应用程序通过一个API调用结束其数据库访问,该调用使其与数据库断开连接。

Python DB API 简介

Python DB API是Python用于访问关系型数据库的标准API。它是一个标准,允许你编写一个适用于多种关系型数据库的单一程序,而无需为每种数据库编写单独的程序。因此,如果你学会了DB API函数,就可以将这些知识应用于使用Python连接任何数据库。

Python DB API中两个核心概念是连接对象游标对象

  • 连接对象:用于连接到数据库并管理事务。
  • 游标对象:用于执行查询。你打开一个游标对象,然后运行查询。游标的工作方式类似于文本处理系统中的光标,你可以在结果集中向下滚动并将数据获取到应用程序中。游标用于扫描数据库的结果。

以下是连接对象常用的方法:

  • cursor():返回一个使用该连接的新游标对象。
  • commit():用于将任何挂起的事务提交到数据库。
  • rollback():使数据库回滚到任何挂起事务的开始状态。
  • close():用于关闭数据库连接。

实战演练:使用DB API查询数据库

上一节我们了解了核心概念,现在让我们通过一个Python应用程序示例,一步步学习如何使用DB API查询数据库。

以下是操作的基本步骤:

  1. 导入数据库模块并建立连接
    首先,从相应的数据库模块中导入connect API,并使用它来打开一个到数据库的连接。你需要调用connect()函数并传入参数(通常是数据库名称、用户名和密码)。该函数返回一个连接对象。

    import sqlite3  # 示例使用sqlite3模块
    conn = sqlite3.connect('example.db')  # 连接到一个SQLite数据库文件
    
  2. 创建游标并执行查询
    接着,在连接对象上创建一个游标对象。游标用于运行查询和获取结果。

    cursor = conn.cursor()
    cursor.execute("SELECT * FROM some_table")
    
  3. 获取查询结果
    使用游标来获取查询的结果。

    results = cursor.fetchall()  # 获取所有结果行
    for row in results:
        print(row)
    
  4. 关闭连接
    当系统完成查询后,通过关闭连接来释放所有资源。记住,始终关闭连接以避免未使用的连接占用资源,这一点非常重要。

    conn.close()
    

总结

本节课中我们一起学习了使用Python访问数据库的核心知识。我们首先了解了Python程序通过API与数据库通信的基本机制,然后介绍了SQL API和Python标准DB API的作用。我们重点学习了Python DB API的两个核心对象:连接对象(用于建立和管理连接)和游标对象(用于执行查询和获取结果)。最后,我们通过一个简单的代码示例,完整演练了连接数据库、执行查询、获取结果和关闭连接的整个流程。掌握这些基础将为你使用Python进行更复杂的数据操作和分析打下坚实的基础。

011:Python数据预处理 📊

在本节课中,我们将学习数据预处理技术。数据预处理是数据分析的必要步骤,它将原始数据转换为适合进一步分析的格式。这个过程也常被称为数据清洗或数据整理。我们将介绍几个核心主题,包括缺失值处理、数据格式标准化、数据归一化、数据分箱以及分类变量转换。

概述 📋

数据预处理是将原始数据映射或转换为另一种格式的过程,目的是为后续分析做好准备。在Python中,我们通常使用pandas库沿数据列进行操作,每一行代表一个样本,例如数据库中的一辆二手车。

识别与处理缺失值 🔍

上一节我们介绍了数据预处理的基本概念。本节中,我们来看看如何处理数据中的缺失值。缺失值是指数据条目为空的情况。

以下是处理缺失值的常用方法:

  • 识别缺失值:使用 df.isnull()df.isna() 来检查数据框中的缺失值。
  • 删除缺失值:使用 df.dropna() 删除包含缺失值的行或列。
  • 填充缺失值:使用 df.fillna(value) 用特定值(如均值、中位数或众数)填充缺失值。

数据格式标准化 🔧

处理完缺失值后,数据可能仍存在格式不统一的问题。本节我们将学习如何标准化数据格式。数据可能来自不同源头,具有不同的格式、单位或约定。

Python pandas提供了一些方法来将值标准化为相同的格式、单位或约定。

以下是数据格式标准化的常见操作:

  • 数据类型转换:使用 df[‘column’].astype(‘type’) 转换列的数据类型,例如将字符串转换为数值。
  • 字符串操作:使用 .str 访问器进行大小写转换、去除空格等操作,例如 df[‘column’].str.lower()
  • 单位转换:通过数学运算统一单位,例如将英里转换为公里。

数据归一化(中心化与缩放) ⚖️

数据格式统一后,不同数值型数据列的范围可能差异很大,直接比较通常没有意义。数据归一化是一种将所有数据带入相似范围的方法,以便进行更有意义的比较。

具体来说,我们将重点介绍中心化和缩放技术。

以下是两种常见的归一化方法:

  • 简单缩放(Simple Feature Scaling):将每个值除以该列的最大值。公式为:X_new = X_old / X_max
  • 最小-最大缩放(Min-Max Scaling):将数据缩放到一个固定的范围,通常是[0, 1]。公式为:X_new = (X_old - X_min) / (X_max - X_min)
  • Z分数标准化(Z-score Standardization):使数据符合标准正态分布(均值为0,标准差为1)。公式为:X_new = (X_old - μ) / σ,其中μ是均值,σ是标准差。

数据分箱 📦

归一化有助于比较不同尺度的数据。接下来,我们学习数据分箱技术。分箱将一组数值划分为更大的类别,它对于数据组之间的比较特别有用。

以下是数据分箱的基本步骤:

  • 等宽分箱:将数据范围划分为N个等宽的区间。可以使用pandas的 pd.cut 函数。
  • 等频分箱:将数据划分为N个组,每个组包含大致相同数量的样本。可以使用pandas的 pd.qcut 函数。
  • 自定义分箱:根据业务逻辑或知识定义分箱边界。

分类变量转换 🔠

最后,我们将讨论分类变量,并展示如何将分类值转换为数值变量,以便于进行统计建模。

在Python中,我们通常使用以下方法:

  • 标签编码(Label Encoding):为每个类别分配一个唯一的整数。可以使用 sklearn.preprocessing.LabelEncoder
  • 独热编码(One-Hot Encoding):为每个类别创建一个新的二进制列(0或1)。可以使用pandas的 pd.get_dummies(df)

总结 🎯

本节课中,我们一起学习了数据预处理的五个核心步骤:识别与处理缺失值、标准化数据格式、通过中心化与缩放进行数据归一化、数据分箱以及分类变量转换。掌握这些技术是进行有效数据分析的基础,它们能帮助我们将杂乱的原始数据转化为干净、一致且适合建模的格式。记住,在Python的pandas库中,操作通常是沿着数据列进行的。

012:缺失值处理

在本节课中,我们将学习数据分析中一个普遍存在的问题:缺失值。我们将探讨当数据集中出现缺失值时,可以采取哪些策略来处理它们,并学习如何在Python中具体实施这些策略。

什么是缺失值?

当某个观测样本的某个特征没有存储数据值时,我们就说这个特征存在缺失值。在数据集中,缺失值通常以问号、0或空白单元格的形式出现。

例如,在下面的数据中,“normalized-losses”特征就有一个缺失值,它被表示为NaN(Not a Number)。

如何处理缺失数据?

处理缺失值的方法有很多,这些方法与使用的工具(如Python、R等)无关。每种情况都不同,需要具体分析,但通常可以考虑以下几种典型方案。

以下是处理缺失数据的几种主要策略:

  1. 追溯原始数据:联系数据收集者,尝试找回缺失的实际值。
  2. 删除数据:直接移除包含缺失值的数据。
  3. 替换数据:用估算的值来填充缺失的部分。
  4. 基于背景知识估算:利用对数据的额外了解进行更精确的猜测。
  5. 保留缺失值:在某些情况下,选择保留缺失值。

上一节我们介绍了缺失值的概念和通用处理策略,本节中我们来看看其中两种最常用方法的具体操作:删除和替换。

方法一:删除缺失值

如果包含缺失数据的观测样本不多,通常删除这些特定的数据条目是最好的选择。删除数据时,我们希望采取对整体数据影响最小的方式。

你可以选择删除整个包含缺失值的变量(列),或者只删除包含缺失值的单个数据条目(行)。

在Python中删除缺失值

Pandas库提供了一个内置方法dropna()来删除包含缺失值的数据。

使用dropna()方法时,你需要指定axis参数:

  • axis=0:删除包含缺失值的
  • axis=1:删除包含缺失值的

示例:假设“price”列存在缺失值,而二手车价格是我们后续分析要预测的目标,因此必须删除没有标价的行。

这可以通过一行代码完成:

df.dropna(subset=["price"], axis=0, inplace=True)
  • subset=["price"]:指定只在“price”列检查缺失值。
  • axis=0:删除行。
  • inplace=True:这个参数非常重要,它允许修改直接作用于原DataFrame上。如果设置为False(默认值),则操作会返回一个新的DataFrame,而不会改变原始数据。

inplace=True等价于将操作结果赋值回原变量:df = df.dropna(...)。在不确定操作效果时,可以先不使用inplace=True来预览结果。

方法二:替换缺失值

替换数据是更好的方法,因为它不会浪费任何数据。然而,它的准确性较低,因为我们需要用猜测值来填补缺失数据。

一种标准的替换技术是用整个变量的平均值来替换缺失值。

示例:假设我们想用平均值替换“normalized-losses”列的缺失值。首先计算该列(排除缺失值后)的平均值,比如是4500。然后,将所有NaN替换为这个平均值。

在Python中替换缺失值

Pandas库的replace()方法可以用来将缺失值替换为新计算的值。

步骤

  1. 计算目标列的平均值。
  2. 使用replace()方法,指定要被替换的值(np.nan)和替换成的值(计算出的平均值)。

# 1. 计算平均值
avg_norm_loss = df["normalized-losses"].mean()
# 2. 替换缺失值
df["normalized-losses"].replace(np.nan, avg_norm_loss, inplace=True)

这是一种简化的替换方法。当然,还有其他技术,例如用分组平均值(而不是整个数据集的平均值)来替换缺失值。

处理分类变量

但是,如果值不能求平均怎么办?例如对于“fuel-type”(燃料类型)这样的分类变量,其值不是数字,不存在“平均燃料类型”。

在这种情况下,一种可能性是使用众数(即最常见的值)来替换,比如“gasoline”(汽油)。

其他注意事项

有时,我们可能基于对缺失数据的额外了解,找到另一种猜测方式。例如,数据收集者可能知道缺失值往往是旧车,而旧车的“normalized-losses”显著高于平均水平。

当然,最后,在某些情况下,你可能选择简单地保留缺失值。出于某种原因,即使某些特征缺失,保留该观测样本也可能有用。

课程总结

本节课中我们一起学习了如何处理数据中的缺失值。我们主要探讨了两种在Python中的实现方法:

  1. 删除包含缺失值的行或列,使用df.dropna()方法。
  2. 替换缺失值为估算值(如平均值、众数),使用df.replace()方法。

但请不要忘记处理缺失数据的其他途径:你始终可以尝试寻找更高质量的数据集或数据源。在某些分析中,保留缺失值本身也是一种有效的信息处理方式。

013:Python数据格式化

在本节课中,我们将学习如何处理不同格式、单位和表示方式的数据,并介绍pandas库中帮助我们解决这些问题的相关方法。

数据通常由不同的人从不同的地方收集,可能以不同的格式存储。数据格式化是指将数据转换为一种通用的表达标准,使用户能够进行有意义的比较。作为数据集清洗的一部分,数据格式化确保数据一致且易于理解。

例如,人们可能使用不同的表达方式来代表纽约市,例如“NYC”、“New York”、“N.Y.”等。有时,这种不干净的数据是有用的。例如,如果你想观察人们倾向于如何书写“纽约”,那么这正是你所需的数据。或者,如果你在寻找检测欺诈的方法,也许“N.Y.”这种写法比完整拼写“New York”更可能预示着异常。但更多时候,我们只是希望将它们视为相同的实体或格式,以便后续进行统计分析。

🔄 数据格式转换示例:油耗单位转换

参考我们的二手车数据集,其中有一个名为“City Miles per gallon”的特征,指的是汽车每加仑燃油消耗的英里数。

然而,你可能生活在使用公制单位的国家。因此,你可能希望将这些值转换为公制版本,即“升每100公里”。

要将“英里每加仑”转换为“升每100公里”,我们需要用235除以“City Miles per gallon”列中的每个值。

在Python中,这可以轻松地用一行代码完成。你取该列并将其设置为等于235除以整个列的值。在第二行代码中,使用数据框的rename方法将列名从“City Miles per gallon”重命名为“City lit per 100 km”。

以下是转换和重命名的代码示例:

df['City lit per 100 km'] = 235 / df['City Miles per gallon']
df.rename(columns={'City Miles per gallon': 'City lit per 100 km'}, inplace=True)

📝 数据类型识别与转换

由于多种原因,包括将数据集导入Python时,数据类型可能被错误地设置。例如,这里我们注意到“price”特征的数据类型被指定为“object”,尽管预期的数据类型应该是整数或浮点数类型。

对于后续分析来说,探索特征的数据类型并将其转换为正确的数据类型非常重要。否则,后续开发的模型可能会表现异常,完全有效的数据最终可能被当作缺失数据处理。

pandas中有许多数据类型。“object”可以是字母或单词,“int64”是整数,“float”是实数。还有许多其他类型,我们在此不讨论。

要在Python中识别特征的数据类型,我们可以使用数据框的dtypes方法,并检查数据框中每个变量的数据类型。

在数据类型错误的情况下,可以使用dataframe.astype()方法将数据类型从一种格式转换为另一种格式。

例如,对“price”列使用astype('int'),你可以将“object”列转换为整数类型变量。

以下是数据类型检查和转换的代码示例:

# 检查数据类型
print(df.dtypes)

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/1a0c8d4ce99f6c882f5a772ba23b35a4_23.png)

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/1a0c8d4ce99f6c882f5a772ba23b35a4_24.png)

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/1a0c8d4ce99f6c882f5a772ba23b35a4_25.png)

# 转换数据类型
df['price'] = df['price'].astype('int')

📋 核心方法总结

以下是本节课介绍的核心pandas方法:

  • df.dtypes:用于检查数据框中各列的数据类型。
  • df.rename():用于重命名数据框的列。
  • df.astype():用于将数据列转换为指定的数据类型。

🎯 课程总结

在本节课中,我们一起学习了数据格式化的重要性,它有助于确保数据的一致性和可比性。我们通过一个具体的例子,演示了如何将油耗单位从“英里每加仑”转换为“升每100公里”。我们还探讨了识别和纠正错误数据类型的方法,这是数据清洗和预处理中的关键步骤,能够为后续的数据分析和建模打下坚实的基础。

014:Python数据格式化 📊

在本节课中,我们将要学习如何处理具有不同格式、单位和约定的数据,以及如何使用pandas库中的方法来应对这些问题。

数据通常由不同的人从不同的地方收集,可能以不同的格式存储。数据格式化意味着将数据带入一个通用的表达标准,使用户能够进行有意义的比较。

作为数据集清洗的一部分,数据格式化确保数据保持一致且易于理解。

数据格式化的必要性 🔍

上一节我们介绍了数据格式化的基本概念,本节中我们来看看为什么需要它。

例如,人们可能使用不同的表达方式来代表纽约市,例如“NYC”、“N.Y.C.”或“New York”。有时,这种不干净的数据是有用的。例如,如果你想研究人们倾向于如何书写“纽约”,那么这正是你想要的数据。或者,如果你想寻找发现欺诈的方法,也许“N.Y.”比完整写出“New York”更可能预示着异常。但更多时候,我们只是希望将它们都视为相同的实体或格式,以便于后续的统计分析。

单位转换示例:油耗计算 ⛽

以下是单位转换的一个具体例子。

参考我们的二手车数据集,其中有一个名为“City Miles per gallon”的特征,指的是汽车以每加仑英里数为单位的油耗。

然而,你可能生活在使用公制单位的国家。因此,你可能希望将这些值转换为公制版本,即“升每100公里”。

要将每加仑英里数转换为升每100公里,我们需要用235除以“city miles per gallon”列中的每个值。

在Python中,这可以轻松地用一行代码完成。你取该列并将其设置为等于235除以整个列的值。在第二行代码中,使用数据框的rename方法将列名从“city miles per gallon”重命名为“city lit per100 km”。

数据类型识别与转换 🔧

上一节我们处理了单位转换,本节中我们来看看数据类型的处理。

由于多种原因,包括将数据集导入Python时,数据类型可能被错误地设置。例如,这里我们注意到“price”特征被分配的数据类型是object,尽管预期的数据类型应该是整数或浮点类型。

对于后续分析来说,探索特征的数据类型并将其转换为正确的数据类型非常重要。否则,后续开发的模型可能会表现异常,完全有效的数据最终可能被当作缺失数据处理。

pandas中有许多数据类型。object可以是字母或单词。int64是整数,float是实数。还有许多其他类型,我们在此不讨论。

要在Python中识别特征的数据类型,我们可以使用dataframe.dtypes方法,并检查数据框中每个变量的数据类型。

在数据类型错误的情况下,可以使用dataframe.astype()方法将数据类型从一种格式转换为另一种格式。

例如,对“price”列使用astype('int'),你可以将object类型的列转换为整数类型的变量。

总结 📝

本节课中我们一起学习了数据格式化的概念及其重要性。我们探讨了如何统一不同格式的数据表达,并通过具体示例演示了如何进行单位转换(如油耗计算)和数据类型识别与转换。掌握这些技能是进行有效数据清洗和准备高质量数据集的关键步骤,为后续的数据分析和建模工作打下坚实基础。

015:Python数据归一化 📊

在本节课中,我们将要学习数据归一化,这是数据预处理中一项重要的技术。

概述

数据归一化是确保不同特征(变量)具有可比性的关键步骤。当数据集中不同特征的数值范围差异很大时,直接进行分析可能会导致结果偏差。归一化通过调整数值范围,使所有特征对后续分析模型的影响更加均衡。

为什么需要归一化?🤔

上一节我们介绍了数据归一化的概念,本节中我们来看看为什么需要它。

观察二手车数据集,我们发现特征“长度”的范围在150到250之间,而特征“宽度”和“高度”的范围则在50到100之间。我们希望归一化这些变量,使它们的取值范围保持一致。

这种归一化可以使后续的统计分析更加容易。通过统一变量间的范围,归一化使得不同特征之间能够进行更公平的比较。

此外,出于计算原因,确保它们具有相同的影响也很重要。

一个关键示例

以下是另一个帮助理解归一化重要性的例子。

考虑一个包含两个特征的数据集:“年龄”和“收入”。其中,年龄范围是0到100岁。

而收入范围则是0到20,000甚至更高。收入大约是年龄的1000倍,范围从20,000到500,000。因此,这两个特征处于完全不同的数量级。

当我们进行进一步分析时,例如线性回归,由于“收入”的数值更大,它本质上会对结果产生更大的影响。但这并不一定意味着它作为预测因子就更重要。数据的这种特性会使线性回归模型偏向于更重视“收入”而非“年龄”。

为了避免这种情况,我们可以将这两个变量归一化到0到1之间的值。

比较右侧归一化后的两个表格。现在,两个变量对我们后续构建的模型具有相似的影响力。

常见的归一化方法

有几种方法可以归一化数据。这里将概述三种常用技术。

以下是三种主要的归一化方法:

  1. 简单特征缩放
    该方法将每个值除以该特征的最大值。
    公式X_new = X_old / X_max
    这使得新值的范围在0和1之间。

  1. 最小-最大归一化
    该方法取每个值X_old,减去该特征的最小值,然后除以该特征的范围(最大值减最小值)。
    公式X_new = (X_old - X_min) / (X_max - X_min)
    同样,得到的新值范围在0和1之间。

  1. Z分数标准化
    在该公式中,对于每个值,你减去μ(该特征的平均值),然后除以标准差σ
    公式X_new = (X_old - μ) / σ
    得到的值围绕0上下波动,通常范围在-3到+3之间,但也可能更高或更低。

在Python中实现归一化

上一节我们介绍了三种归一化方法的理论,本节中我们来看看如何在Python中应用它们。

我们将以数据集中的“长度”特征为例,演示三种归一化方法。

首先,使用简单特征缩放方法,即用该特征的值除以其最大值。
使用Pandas的.max()方法,只需一行代码即可完成。

df[‘length’] / df[‘length’].max()

接下来,对“长度”特征应用最小-最大方法。我们用每个值减去该列的最小值,然后除以该列的范围(最大值减最小值)。

(df[‘length’] - df[‘length’].min()) / (df[‘length’].max() - df[‘length’].min())

最后,应用Z分数方法对“长度”特征进行归一化。这里我们对“长度”特征应用.mean().std()方法。
.mean()方法将返回数据集中该特征的平均值,.std()方法将返回数据集中该特征的标准差。

(df[‘length’] - df[‘length’].mean()) / df[‘length’].std()

总结

本节课中我们一起学习了数据归一化。我们了解了为什么当特征尺度不同时需要进行归一化,它如何确保模型公平地对待所有特征。我们介绍了三种主要的归一化技术:简单特征缩放、最小-最大归一化和Z分数标准化,并学习了如何使用Python的Pandas库来实现它们。掌握数据归一化是进行有效数据分析和构建稳健机器学习模型的重要基础。

016:Python数据分箱 📊

在本节课中,我们将要学习数据分箱这一数据预处理方法。数据分箱能够将数值分组,有时可以提升预测模型的准确性,并帮助我们更好地理解数据分布。

上一节我们介绍了数据预处理的基本概念,本节中我们来看看数据分箱的具体应用。

什么是数据分箱? 📦

数据分箱是指将数值分组到不同的“箱子”中。例如,可以将年龄分为0-5岁、6-10岁、11-15岁等组别。

有时,数据分箱能够提升预测模型的准确性。此外,我们有时会将一组数值分到数量更少的箱子中,以便更好地理解数据分布。

数据分箱示例 🚗

以汽车价格为例,价格是一个属性,范围从5000到45500。

使用分箱方法,我们可以将价格分为三个箱子:低价、中价和高价。

在实际的汽车数据集中,价格是一个数值变量,范围从5188到45400,共有201个不同的值。我们可以将它们分为三个箱子:低价车、中价车和高价车。

在Python中实现数据分箱 🐍

在Python中,我们可以轻松实现数据分箱。我们希望创建三个等宽的箱子,因此需要四个等间距的数字作为分隔点。

首先,我们使用NumPy的linspace函数来生成一个数组bins,该数组包含在指定价格区间内等间距的四个数字。

以下是实现代码:

import numpy as np
import pandas as pd

# 假设 price 是一个包含价格的Pandas Series
# 计算等间距的分箱边界
bins = np.linspace(min(price), max(price), 4)

我们创建一个列表group_names,其中包含不同的分箱名称。

group_names = [‘Low’, ‘Medium’, ‘High’]

然后,我们使用Pandas的cut函数将数据值分段并排序到各个箱子中。

price_binned = pd.cut(price, bins, labels=group_names, include_lowest=True)

可视化分箱结果 📊

分箱完成后,你可以使用直方图来可视化数据在分箱后的分布。

以下是我们基于价格特征应用分箱后绘制的直方图。从图中可以清楚地看出,大多数汽车属于低价类别,只有很少的汽车属于高价类别。

import matplotlib.pyplot as plt

# 绘制直方图
plt.hist(price_binned, bins=3, edgecolor=‘black’)
plt.xlabel(‘Price Category’)
plt.ylabel(‘Frequency’)
plt.title(‘Distribution of Car Prices After Binning’)
plt.show()

总结 📝

本节课中我们一起学习了数据分箱的概念及其在Python中的实现方法。我们了解到,数据分箱是一种将数值数据分组的技术,有助于提升模型性能并更好地理解数据分布。通过使用NumPy的linspace函数和Pandas的cut函数,我们可以轻松地对数据进行分箱处理,并通过直方图直观地展示分箱结果。

017:数据归一化 📊

在本节课中,我们将要学习数据归一化,这是数据预处理中一项重要的技术。

当我们观察二手车数据集时,会注意到数据中“长度”特征的范围在150到250之间,而“宽度”和“高度”特征的范围则在50到100之间。我们可能希望将这些变量归一化,使它们的取值范围保持一致。这种归一化可以使后续的某些统计分析更加容易。

通过使变量间的范围保持一致,归一化能够实现不同特征之间更公平的比较,确保它们具有相同的影响力。这对于计算过程也很重要。

为什么需要归一化?🤔

上一节我们提到了数据范围不一致的问题,本节中我们通过一个例子来深入理解为什么归一化如此重要。

考虑一个包含“年龄”和“收入”两个特征的数据集。其中,年龄的范围是0到100岁,而收入的范围则是0到20,000甚至更高。收入的值大约是年龄的1000倍,其范围可能在20,000到500,000之间。因此,这两个特征处于完全不同的数量级。

当我们进行进一步分析时,例如线性回归,由于“收入”特征的数值更大,它本质上会对结果产生更大的影响。但这并不一定意味着它作为一个预测因子就更重要。数据的这种特性会使线性回归模型偏向于给予“收入”比“年龄”更重的权重。

为了避免这种情况,我们可以将这两个变量归一化到0到1的范围内。比较右侧归一化后的两个表格,现在两个变量对我们后续构建的模型具有相似的影响力。

数据归一化的方法 🛠️

我们已经理解了归一化的必要性,接下来看看如何实现它。以下是三种常见的数据归一化技术。

简单特征缩放
这种方法将每个值除以该特征的最大值。这使得新值的范围在0到1之间。
公式为:X_new = X_old / X_max

最小-最大归一化
这种方法从每个值中减去该特征的最小值,然后除以该特征的范围(最大值减最小值)。结果值同样在0到1之间。
公式为:X_new = (X_old - X_min) / (X_max - X_min)

Z分数标准化
在这种方法中,对于每个值,先减去该特征的平均值(μ),再除以标准差(σ)。结果值通常围绕0分布,范围大致在-3到+3之间,但也可能更高或更低。
公式为:X_new = (X_old - μ) / σ

在Python中实现归一化 💻

理论介绍完毕,现在让我们动手实践,看看如何在Python中应用这些归一化方法。我们将以数据集中的“长度”特征为例。

首先,使用简单特征缩放方法,将每个值除以该特征的最大值。使用Pandas的.max()方法,只需一行代码即可完成。

df[‘length’] / df[‘length’].max()

接下来,应用最小-最大方法。从该列的每个值中减去最小值,然后除以该列的范围(最大值减最小值)。

(df[‘length’] - df[‘length’].min()) / (df[‘length’].max() - df[‘length’].min())

最后,对长度特征应用Z分数方法进行归一化。这里我们对长度特征应用.mean().std()方法。.mean()方法返回数据集中该特征的平均值,.std()方法返回数据集中该特征的标准差。

(df[‘length’] - df[‘length’].mean()) / df[‘length’].std()

总结 📝

本节课中我们一起学习了数据归一化。我们首先理解了为什么当数据特征处于不同量级时需要进行归一化,以确保模型分析的公平性和准确性。接着,我们介绍了三种核心的归一化技术:简单特征缩放、最小-最大归一化和Z分数标准化,并给出了它们的数学公式。最后,我们使用Python的Pandas库,通过具体的代码示例演示了如何对数据集中的特征实施这些归一化操作。掌握数据归一化是进行有效数据分析和构建稳健机器学习模型的重要一步。

018:Python分类变量量化 🔢

在本节课中,我们将学习如何将数据集中的分类变量(如字符串或对象类型)转换为定量变量(数值类型)。这是数据预处理的关键步骤,因为大多数统计模型和机器学习算法只能处理数值型数据。

概述 📋

上一节我们介绍了数据清洗的基本概念。本节中我们来看看一个特定的预处理任务:分类变量的量化。分类变量包含非数值的类别信息,例如“汽油”或“柴油”。为了在分析中使用这些信息,我们必须将它们转换为数值形式。

为什么需要量化分类变量? 🤔

大多数统计模型无法将对象或字符串作为输入。为了进行模型训练,它们只接受数字作为输入。

在汽车数据集中,“燃料类型”这个特征是一个分类变量,它有两个值:“汽油”或“柴油”,它们以字符串格式存在。为了进行进一步的分析,我们必须将这些变量转换为某种数字格式。

解决方案:独热编码(One-Hot Encoding) ⚙️

我们通过为原始特征中每个唯一的元素添加新的特征来进行编码。以“燃料类型”特征为例,它有两个唯一值:“汽油”和“柴油”。我们创建两个新特征:“gas”和“diesel”。

当某个值出现在原始特征中时,我们在新特征中将对应的值设为1,其余特征设为0。

在燃料示例中:

  • 对于汽车B,燃料值是“柴油”。因此,我们将“diesel”特征设为1,“gas”特征设为0。
  • 对于汽车D,燃料值是“汽油”。因此,我们将“gas”特征设为1,“diesel”特征设为0。

这种技术通常被称为独热编码

在Pandas中,我们可以使用 get_dummies() 方法来将分类变量转换为虚拟变量(哑变量)。

在Python中实现独热编码 💻

在Python中,将分类变量转换为虚拟变量很简单。遵循示例,pd.get_dummies() 方法获取“燃料类型”列并创建数据框 dummy_variable_1

以下是实现此操作的代码:

import pandas as pd

# 假设 df 是包含‘fuel-type’列的DataFrame
dummy_variable_1 = pd.get_dummies(df['fuel-type'])

get_dummies() 方法会自动生成一个数字列表,每个数字对应变量的一个特定类别。

总结 🎯

本节课中我们一起学习了分类变量量化的核心方法——独热编码。我们了解到,由于机器学习模型需要数值输入,将字符串类型的分类数据(如“汽油”、“柴油”)转换为数值是必不可少的步骤。通过Pandas库的 pd.get_dummies() 函数,我们可以轻松地为每个类别创建一个新的二进制特征(0或1),从而将分类信息有效地转化为模型可以理解的格式。这是构建高效数据管道和成功训练模型的基础技能之一。

019:数据分箱

在本节课中,我们将学习数据分箱这一数据预处理方法。数据分箱能够将数值分组到不同的区间中,有时可以提升预测模型的准确性,并帮助我们更好地理解数据分布。


什么是数据分箱?🧩

数据分箱是指将数值分组到不同的“箱子”中。例如,可以将年龄分为0-5岁、6-10岁、11-15岁等区间。有时,分箱能够提升预测模型的准确性。此外,我们有时会将一组数值分到更少的箱子中,以便更好地理解数据分布。


数据分箱示例:汽车价格 🚗

以汽车价格为例,价格属性的范围从5000到45500。

使用分箱方法,我们将价格分为三个区间:低价、中价和高价。

在实际的汽车数据集中,价格是一个数值变量,范围从5188到45400,共有201个不同的值。我们可以将它们分为三个区间:低价车、中价车和高价车。


在Python中实现等宽分箱 ⚙️

在Python中,我们可以轻松实现分箱。我们希望创建三个等宽的箱子,因此需要四个等间距的数字作为分隔点。

首先,我们使用NumPy的linspace函数生成一个数组bins,该数组包含在指定价格区间内等间距的四个数字。

import numpy as np
bins = np.linspace(min_price, max_price, 4)

接着,我们创建一个列表group_names,其中包含不同的箱子名称。

group_names = ['Low', 'Medium', 'High']

然后,我们使用Pandas的cut函数将数据值分段并排序到各个箱子中。

import pandas as pd
df['price-binned'] = pd.cut(df['price'], bins, labels=group_names, include_lowest=True)

可视化分箱后的数据分布 📈

分箱完成后,你可以使用直方图来可视化数据在分箱后的分布情况。

以下是我们根据价格特征应用分箱后绘制的直方图。从图中可以清楚地看出,大多数汽车属于低价区间,只有很少的汽车属于高价区间。

import matplotlib.pyplot as plt
plt.hist(df['price-binned'], bins=3)
plt.xlabel('Price Group')
plt.ylabel('Count')
plt.title('Price Bins')
plt.show()

总结 🎯

本节课我们一起学习了数据分箱的概念及其在数据预处理中的应用。我们通过一个汽车价格的示例,演示了如何在Python中使用等宽分箱方法,并通过直方图可视化了分箱后的数据分布。掌握数据分箱技术,有助于你更好地理解和处理数值型数据。

020:Python分类变量量化 📊

在本节课中,我们将学习如何将分类变量(Categorical Variables)转换为定量变量(Quantitative Variables)。这是数据预处理中的一个关键步骤,因为大多数统计模型和机器学习算法只能处理数值型数据。

概述

许多统计模型无法直接处理对象或字符串格式的输入,它们只接受数字作为输入。因此,我们需要将数据集中的分类变量(例如“汽油”或“柴油”)转换为数值格式,以便进行进一步的分析和模型训练。

为什么需要量化分类变量?

在汽车数据集中,“燃料类型”(fuel type)是一个分类变量,它有两个取值:“汽油”(Gas)和“柴油”(Diesel),这两个值都是字符串格式。为了进行后续分析,我们必须将这些变量转换为某种数值格式。

独热编码(One-Hot Encoding)方法

上一节我们了解了转换的必要性,本节中我们来看看最常用的转换方法:独热编码

其原理是:为原始特征中每一个唯一的元素创建一个新的二进制特征(0或1)。以“燃料类型”特征为例,它有两个唯一值:“汽油”和“柴油”。因此,我们创建两个新特征:gasdiesel

当某个值在原始特征中出现时,我们就在对应的新特征中将其值设为1,其他新特征则设为0。

以下是具体示例:

  • 对于汽车B,其燃料值为“柴油”。因此,我们将 diesel 特征设为1,gas 特征设为0。
  • 对于汽车D,其燃料值为“汽油”。因此,我们将 gas 特征设为1,diesel 特征设为0。

在Pandas库中,我们可以使用 get_dummies() 方法轻松实现分类变量到虚拟变量(Dummy Variables)的转换。

在Python中使用Pandas实现

了解了独热编码的原理后,现在让我们看看如何在Python中具体操作。

在Python中,使用Pandas转换分类变量非常简单。参考以下示例代码:

dummy_variable_1 = pd.get_dummies(df["fuel-type"])

get_dummies() 方法会自动为变量的每个特定类别生成一个由0和1组成的列表(即新特征)。

总结

本节课中,我们一起学习了数据预处理中的一个重要技巧:将分类变量量化为数值变量。我们重点介绍了独热编码的原理,并演示了如何使用Pandas的 get_dummies() 方法在Python中轻松实现这一转换。掌握这个方法,能为后续的数据分析和机器学习模型训练打下坚实的基础。

021:探索性数据分析

在本节课中,我们将学习如何使用Python进行探索性数据分析的基础知识。探索性数据分析是理解数据集、发现变量间关系以及识别关键特征的重要步骤。


🎯 什么是探索性数据分析?

探索性数据分析,简称EDA,是一种分析数据的方法,旨在总结数据的主要特征,更好地理解数据集,揭示不同变量之间的关系,并提取对我们试图解决的问题至关重要的变量。

在本模块中,我们试图回答的主要问题是:哪些特征对汽车价格的影响最大? 为了回答这个问题,我们将介绍几种有用的探索性数据分析技术。


📈 描述性统计

上一节我们介绍了探索性数据分析的目标,本节中我们来看看描述性统计。描述性统计用于描述数据集的基本特征,获取样本的简短摘要以及数据的度量。

以下是描述性统计通常包含的内容:

  • 中心趋势度量:如均值、中位数、众数。
  • 离散程度度量:如标准差、方差、极差。
  • 数据分布形状:如偏度、峰度。

在Python中,我们可以使用Pandas库的describe()方法快速获取数值型数据的描述性统计摘要:

import pandas as pd
# 假设df是一个DataFrame
summary = df.describe()
print(summary)


🔍 数据分组(Group By)

了解了数据的基本统计特征后,我们来看看如何对数据进行分组。使用group by操作是数据分析中的基础技术,它可以帮助我们根据某个或某几个分类变量对数据进行分组,然后对每个组进行聚合计算,从而转换和深入理解数据集。

以下是group by操作的基本步骤:

  1. 分割(Splitting):根据指定键(一个或多个列)将数据分割成不同的组。
  2. 应用(Applying):对每个独立的数据组应用一个函数(如求和、求平均、计数等)。
  3. 合并(Combining):将各组的计算结果合并成一个新的数据结构。

例如,我们想按汽车品牌(brand)分组,并计算每个品牌的平均价格:

# 按‘brand’列分组,并计算‘price’列的平均值
grouped_data = df.groupby(‘brand’)[‘price’].mean()
print(grouped_data)

📊 变量间的相关性

在通过分组深入了解了数据的子集特征后,一个核心问题是:不同变量之间是否存在关联?相关性分析正是用来衡量两个变量之间线性关系强度和方向的统计方法。

相关性系数(r)的取值范围在-1到1之间

  • r = 1:表示完全正相关。
  • r = -1:表示完全负相关。
  • r = 0:表示没有线性相关性。

在Pandas中,我们可以使用.corr()方法轻松计算数据框中所有数值列之间的相关系数矩阵:

# 计算DataFrame中所有数值列的相关性矩阵
correlation_matrix = df.corr()
print(correlation_matrix)


🔥 高级相关性分析:皮尔逊相关与热力图

上一节我们介绍了基本的相关系数计算,本节中我们来看看更高级的相关性分析方法。我们将重点介绍皮尔逊相关系数,并学习如何使用相关性热力图来直观地展示变量间的关系。

皮尔逊相关系数是最常用的相关性度量,它衡量的是两个连续变量之间的线性关系。其公式为:

r = Σ[(xi - x̄)(yi - ȳ)] / √[Σ(xi - x̄)² Σ(yi - ȳ)²]

其中,xi和yi是单个样本点,x̄和ȳ是样本均值。

为了更直观地解读庞大的相关系数矩阵,我们可以使用热力图(Heatmap)进行可视化。热力图使用颜色深浅来代表相关系数的大小,使得强相关和弱相关的变量对一目了然。我们可以使用Seaborn库来绘制:

import seaborn as sns
import matplotlib.pyplot as plt

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/32e8835271a54932e3a95afa82dbb07c_10.png)

# 计算相关性矩阵
corr = df.corr()
# 绘制热力图
plt.figure(figsize=(10, 8))
sns.heatmap(corr, annot=True, cmap=‘coolwarm’, fmt=‘.2f’)
plt.title(‘Correlation Heatmap’)
plt.show()


✅ 总结

本节课中我们一起学习了探索性数据分析的核心内容。我们从理解EDA的目标出发,学习了如何使用描述性统计来概括数据特征,掌握了通过group by对数据进行分组和聚合的方法。接着,我们探讨了如何计算和解释变量间的相关性,并最终引入了皮尔逊相关系数和相关性热力图这两种高级工具,以更深入、更直观地揭示数据内部的关系。掌握这些技术是进行有效数据分析和构建数据驱动解决方案的关键基础。

022:描述性统计

在本节课中,我们将学习描述性统计的基本概念及其在数据分析中的应用。描述性统计是数据探索的第一步,它能帮助我们快速了解数据的基本特征和分布情况。

概述:为什么需要描述性统计?

开始分析数据之前,首先探索数据非常重要,这比直接构建复杂模型更有效。一种简单的方法是计算数据的描述性统计量。

描述性统计分析有助于描述数据集的基本特征,获取样本的简要概括和数据度量。接下来,我们将介绍几种有用的方法。

使用Pandas的describe函数

我们可以使用Pandas库中的describe函数来实现这一目标。将该函数应用于数据框后,它会自动计算所有数值变量的基本统计量。

以下是describe函数输出的关键统计指标:

  • 均值(Mean):数据的平均值。
  • 数据点总数(Count):非空数据点的数量。
  • 标准差(Std):数据离散程度的度量。
  • 分位数(Quartiles):包括25%(下四分位数)、50%(中位数)和75%(上四分位数)。
  • 极值(Min/Max):数据的最小值和最大值。

在这些统计计算中,任何NaN(非数字)值都会被自动跳过。这个函数能让你更清楚地了解不同变量的分布情况。

处理分类变量

数据集中也可能包含分类变量。这些变量可以被划分为不同的类别或组,并具有离散值。

例如,在我们的数据集中,“驱动系统”(drive system)就是一个分类变量,它包含“前轮驱动”、“后轮驱动”和“四轮驱动”等类别。

以下是汇总分类数据的方法:

一种汇总分类数据的方法是使用value_counts函数。我们可以更改列名以便于阅读。

执行后,我们看到:

  • 前轮驱动类别有118辆车。
  • 后轮驱动类别有75辆车。
  • 四轮驱动类别有8辆车。

使用箱线图可视化数值数据

箱线图是可视化数值数据的绝佳方式,因为它可以展示数据的各种分布特征。

箱线图显示的主要特征包括:

  • 中位数(Median):表示中间数据点的位置。
  • 上四分位数(Upper Quartile):表示第75百分位数的位置。
  • 下四分位数(Lower Quartile):表示第25百分位数的位置。
  • 四分位距(Interquartile Range, IQR):上四分位数与下四分位数之间的数据范围。

接下来是上下极端值。它们的计算方式如下:

  • 上极端值上四分位数 + 1.5 * IQR
  • 下极端值下四分位数 - 1.5 * IQR

最后,箱线图还将异常值显示为出现在上下极端值之外的独立点。通过箱线图,你可以轻松识别异常值,并观察数据的分布和偏度。

箱线图的组间比较

箱线图便于进行组间比较。在这个例子中,使用箱线图,我们可以看到“驱动轮”特征的不同类别在“价格”特征上的分布。

我们发现,后轮驱动与其他类别之间的价格分布有明显区别,但前轮驱动和四轮驱动的价格几乎无法区分。

分析连续变量与散点图

我们的数据中经常会出现连续变量。这些数据点是包含在一定范围内的数字。例如,在我们的数据集中,“价格”和“发动机排量”就是连续变量。

如果我们想理解发动机排量与价格之间的关系呢?发动机排量能否预测汽车的价格?

一个好的可视化方法是使用散点图。散点图中的每个观测值都表示为一个点。

这个图表展示的是两个变量之间的关系。

  • 预测变量(Predictor Variable):用于预测结果的变量。在本例中,我们的预测变量是发动机排量。
  • 目标变量(Target Variable):你试图预测的变量。在本例中,我们的目标变量是价格,因为这将是结果。

在散点图中,我们通常将预测变量设置在X轴(水平轴),将目标变量设置在Y轴(垂直轴)。因此,在本例中,我们将发动机排量绘制在X轴,将价格绘制在Y轴。

我们在这里使用了Matplotlib库的scatter函数,传入X和Y变量。需要注意的是,始终标记坐标轴并编写图表总标题非常重要,这样你才能清楚自己在观察什么。

那么,变量“发动机排量”与“价格”的关系如何?从散点图中我们看到,随着发动机排量上升,汽车价格也上升。

这初步表明这两个变量之间存在正向的线性关系。

总结

本节课我们一起学习了描述性统计的核心概念。我们介绍了如何使用Pandas的describe函数快速获取数值数据的统计摘要,以及如何使用value_counts处理分类数据。我们还深入探讨了箱线图的构成及其在识别异常值、比较组间差异方面的强大功能。最后,我们学习了如何使用散点图来可视化并初步判断两个连续变量(如发动机排量与价格)之间的关系。掌握这些基础的数据探索技巧,是进行更深入数据分析的关键第一步。

023:Python分组操作 📊

在本节课中,我们将要学习如何使用Pandas库进行数据分组操作。分组是数据分析中的一项核心技能,它允许我们根据数据的类别将数据集划分为多个子集,进而对每个子集进行独立的分析和计算。通过分组,我们可以更深入地理解数据中的模式和关系。

概述

假设我们想要了解不同类型的驱动系统(前驱、后驱和四驱)与车辆价格之间是否存在任何关系。如果存在关系,哪种驱动系统能为车辆增加最多的价值?为了回答这些问题,我们需要将数据按照驱动系统的类型进行分组,并比较不同组别之间的结果。

在Pandas中,这可以通过使用 groupby 方法来实现。

分组基础

groupby 方法用于处理分类变量。它将数据根据该变量的不同类别划分为多个子集。你可以根据单个变量进行分组,也可以通过传入多个变量名来根据多个变量进行分组。

例如,我们想要找出车辆的平均价格,并观察它们在不同车身样式和驱动系统类型之间的差异。以下是实现这一目标的步骤。

首先,我们选取我们感兴趣的三个数据列,这通过代码的第一行完成。

# 选取感兴趣的列
data_subset = df[['drive-wheels', 'body-style', 'price']]

接着,我们根据驱动系统和车身样式对筛选后的数据进行分组,这通过代码的第二行完成。

# 根据驱动系统和车身样式分组,并计算平均价格
grouped_data = data_subset.groupby(['drive-wheels', 'body-style']).mean()

由于我们关注的是平均价格在不同类别间的差异,我们可以在行末添加 .mean() 来计算每个组的平均值。

现在,数据被分组到各个子类别中,并且只显示每个子类别的平均价格。

根据我们的数据,我们可以看到后轮驱动的敞篷车和后轮驱动的硬顶车具有最高的价值,而四轮驱动的掀背车价值最低。

数据透视表

这种形式的表格并不容易阅读,也不易于可视化。为了更容易理解,我们可以使用 pivot 方法将这个表格转换为数据透视表。

在上一个表格中,驱动系统和车身样式都列在列中。数据透视表将一个变量显示在列上,另一个变量显示在行上。只需一行代码,并使用Pandas的 pivot 方法,我们就可以将车身样式变量旋转到列上,而驱动系统则显示在行上。

# 将分组数据转换为数据透视表
pivot_table = grouped_data.pivot(index='drive-wheels', columns='body-style')

价格数据现在变成了一个矩形网格,更容易进行可视化。这类似于通常在Excel电子表格中完成的操作。

热力图

表示数据透视表的另一种方法是使用热力图。热力图接收一个矩形数据网格,并根据网格点上的数据值分配颜色强度。这是一种在多个变量上绘制目标变量的绝佳方式,通过这种方式,我们可以获得这些变量与目标变量之间关系的视觉线索。

在这个例子中,我们使用Matplotlib的 pcolor 方法来绘制热力图,并将之前的数据透视表转换为图形形式。

import matplotlib.pyplot as plt

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/f08b98c2b04dd15e26907c35301a5d15_48.png)

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/f08b98c2b04dd15e26907c35301a5d15_49.png)

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/f08b98c2b04dd15e26907c35301a5d15_51.png)

# 绘制热力图
plt.pcolor(pivot_table, cmap='RdBu')
plt.colorbar()
plt.show()

我们指定了红蓝配色方案。在输出图中,每种车身样式类型沿X轴编号,每种驱动系统类型沿Y轴编号。平均价格根据其值以不同的颜色绘制。根据颜色条,我们看到热力图的上半部分似乎有更高的价格,而下半部分价格较低。

总结

在本节课中,我们一起学习了如何使用Pandas进行数据分组操作。我们首先介绍了 groupby 方法的基本概念,它允许我们根据分类变量将数据分成子集。接着,我们通过一个具体示例,展示了如何根据多个变量分组并计算平均值。然后,我们探讨了如何将分组结果转换为更易读的数据透视表,并最终使用热力图进行可视化,以直观地展示变量之间的关系。这些技能对于深入分析和理解复杂数据集至关重要。

024:相关性分析

在本节课中,我们将学习相关性分析的基本概念,了解如何衡量不同变量之间的相互依赖程度,并通过实际案例掌握如何使用Python进行相关性分析。

概述:什么是相关性?

相关性是一种统计指标,用于衡量不同变量之间相互依赖的程度。

换句话说,当我们观察两个变量随时间的变化时,如果一个变量发生变化,另一个变量会如何随之改变。例如,吸烟与肺癌之间存在相关性,因为吸烟会增加患肺癌的风险。

另一个例子是雨伞和降雨量之间的相关性。降雨量越大,使用雨伞的人就越多。如果不下雨,人们通常不会携带雨伞。因此,我们可以说雨伞和降雨量是相互依赖的,根据定义,它们是相关的。

需要明确的是,相关性并不意味着因果关系。我们可以说雨伞和降雨量是相关的,但没有足够的信息断定是雨伞导致了降雨,还是降雨导致了雨伞的使用。在数据科学中,我们通常更关注相关性本身。

正相关示例:发动机大小与价格

上一节我们介绍了相关性的基本概念,本节中我们来看看一个具体的正相关示例:汽车发动机大小与价格之间的关系。

为了分析这两个变量,我们可以使用散点图并添加一条回归线(线性线),以直观展示两者之间的关系。

该图表的主要目的是观察发动机大小是否对价格产生影响。在这个例子中,穿过数据点的直线非常陡峭,这表明两个变量之间存在正向的线性关系。随着发动机尺寸值的增加,价格值也随之上升,且直线的斜率为正。因此,发动机大小与价格之间存在正相关。

我们可以使用Seaborn库的regplot函数来创建这个散点图。

import seaborn as sns
sns.regplot(x='engine-size', y='price', data=df)

负相关示例:高速公路油耗与价格

了解了正相关后,现在让我们看看负相关的例子:高速公路每加仑行驶里程(油耗)对汽车价格的影响。

从图中可以看出,当高速公路油耗值上升时,价格值下降。因此,高速公路油耗与价格之间存在负向的线性关系。尽管这种关系是负向的,但直线的斜率仍然较陡,这意味着高速公路油耗仍然是预测价格的一个有效指标。这两个变量被称为具有负相关性。

弱相关或无相关示例

最后,我们来看一个弱相关或无相关的例子。例如,峰值转速(RPM)的低值和高值都对应着低价格和高价格。因此,我们无法使用峰值转速来可靠地预测价格值。

总结

本节课中,我们一起学习了相关性分析的核心概念。我们了解到相关性是衡量变量间相互依赖程度的统计指标,并区分了正相关、负相关以及弱相关。通过汽车数据集的具体示例,我们使用散点图和回归线可视化了发动机大小与价格的正相关关系,以及高速公路油耗与价格的负相关关系。重要的是要记住,相关性并不等同于因果关系。在数据科学实践中,理解变量间的相关性是进行有效分析和预测的基础。

025:Python分组操作

在本节课中,我们将学习如何使用Pandas库进行数据分组操作。分组是数据分析中的一项核心技能,它允许我们根据数据的类别将数据集划分为多个子集,进而对每个子集进行独立的分析和计算。通过分组,我们可以更清晰地观察不同类别数据之间的差异和关系。

概述:为什么需要分组?

假设我们想了解不同类型的驱动系统(前驱、后驱和四驱)与车辆价格之间是否存在关系。如果存在关系,哪种驱动系统能为车辆增加最多的价值?为了回答这些问题,我们需要将数据按照驱动系统的类型进行分组,然后比较不同组之间的结果。

在Pandas中,这可以通过groupby方法实现。

分组操作基础

groupby方法用于处理分类变量。它将数据根据该变量的不同类别划分为多个子集。你可以根据单个变量进行分组,也可以通过传入多个变量名来根据多个变量进行分组。

以下是分组操作的基本步骤:

  1. 选择需要分析的数据列。
  2. 使用groupby方法指定分组依据的列。
  3. 对分组后的数据应用聚合函数(如求平均值、求和等)。

实践:计算平均价格

让我们通过一个例子来具体说明。假设我们想找出车辆的平均价格,并观察不同车身样式和驱动系统类型之间的价格差异。

首先,我们选取感兴趣的三列数据:drive-wheels(驱动系统)、body-style(车身样式)和price(价格)。

df_selected = df[['drive-wheels', 'body-style', 'price']]

接着,我们根据drive-wheelsbody-style对筛选后的数据进行分组。

df_grouped = df_selected.groupby(['drive-wheels', 'body-style'])

由于我们关注的是平均价格,我们在分组后对每个组应用mean()函数来计算平均值。

df_grouped_mean = df_grouped.mean()

现在,数据被分组为多个子类别,并且只显示每个子类别的平均价格。从结果中我们可以看到,根据我们的数据,后驱敞篷车和后驱硬顶车的价值最高,而四驱掀背车的价值最低。

从分组表到透视表

上述分组结果以表格形式呈现,但可能不够直观,也不易于可视化。为了更容易理解,我们可以使用pivot方法将这个表格转换为透视表。

在之前的表格中,drive-wheelsbody-style都列在列中。透视表则将其中一个变量显示在列上,另一个变量显示在行上。

通过一行代码,使用Pandas的pivot方法,我们可以将body-style变量作为列,将drive-wheels变量作为行。

df_pivot = df_grouped_mean.pivot(index='drive-wheels', columns='body-style')

现在,价格数据变成了一个矩形网格,更易于观察。这类似于Excel电子表格中常用的数据透视表。

可视化:热力图

另一种表示透视表的方法是使用热力图。热力图接收一个矩形数据网格,并根据网格点上的数据值为其分配颜色强度。这是一种在多个变量上绘制目标变量的绝佳方式,可以直观地获取这些变量与目标变量之间关系的线索。

在本例中,我们使用Matplotlib的pcolor方法来绘制热力图,将之前的透视表转换为图形形式。

plt.pcolor(df_pivot, cmap='RdBu')
plt.colorbar()
plt.show()

我们指定了红-蓝配色方案。在输出图中,X轴编号代表不同类型的车身样式,Y轴编号代表不同类型的驱动系统。平均价格根据其值以不同颜色绘制。根据颜色条,我们可以看到热力图的上半部分价格似乎更高,而下半部分价格较低。

总结

本节课我们一起学习了Pandas中的分组操作。我们首先了解了分组的概念及其在数据分析中的重要性。接着,我们通过一个具体示例,演示了如何使用groupby方法根据多个变量对数据进行分组,并计算每个组的统计量(如平均值)。然后,我们学习了如何将分组结果转换为更直观的透视表,并最终通过热力图进行可视化展示,从而更清晰地揭示数据中隐藏的模式和关系。掌握这些技能将帮助你更有效地探索和理解数据集。

026:相关性统计

在本节课中,我们将学习相关性统计方法。相关性用于衡量两个连续数值变量之间关系的强度和方向。我们将重点介绍皮尔逊相关系数,并学习如何解读其计算结果,包括相关系数和P值。最后,我们将通过一个汽车数据的例子,演示如何计算相关性并利用热力图进行可视化分析。


🔍 皮尔逊相关系数

上一节我们介绍了相关性统计的概念,本节中我们来看看最常用的皮尔逊相关系数。这是一种衡量两个连续数值变量之间线性关系强度的方法。

皮尔逊相关方法会给出两个值:相关系数P值

相关系数的解读

相关系数的取值范围在-1到1之间。

  • 相关系数接近1:表示存在强正相关。即一个变量增加时,另一个变量也倾向于增加。
  • 相关系数接近-1:表示存在强负相关。即一个变量增加时,另一个变量倾向于减少。
  • 相关系数接近0:表示两个变量之间没有线性相关

P值的解读

P值用于衡量我们对计算出的相关系数的确信程度。

以下是P值的解读指南:

  • P值 < 0.001:为我们对计算出的相关系数提供了强确信度
  • 0.001 ≤ P值 < 0.05:提供了中等确信度
  • 0.05 ≤ P值 < 0.1:提供了弱确信度
  • P值 ≥ 0.1无法确信存在相关性。

相关系数接近1或-1,并且P值小于0.001时,我们可以说存在强相关性。


🚗 实例分析:马力与价格的相关性

了解了皮尔逊相关系数的原理后,我们通过一个实例来应用它。本例中,我们将分析汽车的马力与价格之间的相关性。

使用Python的scipy.stats包可以轻松计算皮尔逊相关系数。

# 示例代码:使用scipy.stats计算皮尔逊相关系数和P值
from scipy import stats
stats.pearsonr(horsepower, price)

计算结果显示,相关系数约为0.8(接近1),P值远小于0.001

因此,我们可以得出结论:马力与汽车价格之间存在强正相关,并且我们对此结论有很高的确信度。


🗺️ 相关性热力图

在分析了两个变量之后,我们可以将视野扩大到所有变量。通过计算数据集中所有数值变量两两之间的皮尔逊相关系数,可以创建一张相关性热力图。

热力图使用颜色深浅来表示相关系数的大小,从而直观展示任意两个变量之间关系的强度。

在生成的热力图中,我们可以看到一条深红色的对角线。这条线上的值都显示出高度相关性,这是合理的,因为对角线表示的是每个变量与自身的相关性,其值始终为1

这张相关性热力图为我们提供了不同变量之间相互关系的概览,最重要的是,它清晰地展示了各个变量与目标变量“价格”之间的关系。


📝 总结

本节课中我们一起学习了相关性统计的核心知识。我们介绍了皮尔逊相关系数,它用于衡量两个连续变量间的线性关系(r接近±1表示强相关,接近0表示无相关)。同时,我们学习了P值的意义,它决定了我们对相关性结论的确信程度(P < 0.001表示强确信)。最后,我们通过Python代码进行了实战计算,并利用热力图对所有变量间的相关性进行了可视化分析,这能帮助我们快速发现数据中的重要关系模式。

027:两分类变量关联分析(卡方检验)

在本节课中,我们将学习如何判断两个分类变量之间是否存在关联关系。

当我们处理两个分类变量之间的关系时,无法使用连续变量的相关性分析方法。我们必须采用卡方检验来评估关联性。

🔍 卡方检验概述

上一节我们提到了分析分类变量关联的特殊性,本节中我们来看看卡方检验的基本原理。

卡方检验旨在检验观察到的分布是否由偶然因素导致。

它衡量观察到的数据分布与变量独立时的预期分布的拟合程度。

📝 重要概念解析

在进入具体示例之前,我们先了解一些重要概念。

卡方检验的原假设是变量之间相互独立。

该检验将观察到的数据与模型在数据随机分布到不同类别时的预期值进行比较。

每当观察到的数据不符合预期值模型时,变量之间存在依赖关系的可能性就越大,从而证明原假设不成立。

卡方检验不告诉你两个变量之间存在何种类型的关系,只表明关系是否存在。

🚗 示例:汽车数据集分析

我们将使用汽车数据集,假设我们想测试燃料类型和进气方式之间的关系,这些都是分类变量。

燃料类型是汽车的燃料类型,汽油或柴油。进气方式是指汽车是标准进气还是涡轮增压。

为此,我们将找出每个类别中汽车的观察计数。

这可以通过使用pandas库创建交叉表来完成。

交叉表是显示两个或多个变量之间关系的表格。

当表格仅显示两个分类变量之间的关系时,交叉表也称为列联表。

在我们的案例中,交叉表或列联表向我们展示了每个类别的计数。

以下是具体的类别:

  • 标准进气、柴油燃料的汽车
  • 标准进气、汽油燃料的汽车
  • 涡轮增压、柴油燃料的汽车
  • 涡轮增压、汽油燃料的汽车

🧮 卡方公式与计算

卡方公式如下:观察值(即每组的计数)减去预期值,平方后除以预期值,然后求和。

公式: χ² = Σ [(观测值 - 期望值)² / 期望值]

预期值基于给定的总计计算。也就是说,如果我们不知道观察值,各个单元格的值会是多少。

要计算标准进气、柴油燃料汽车的预期值,我们取行总计20乘以列总计106,再除以总计数205。

这将得到16.39。如果我们对涡轮增压、汽油燃料的汽车进行同样的计算,我们将取行总计185乘以列总计37,再除以总计数205,得到33.39。

如果我们对所有类别重复相同的过程,就会得到这些值。

如果我们取行总计、列总计和总计数,得到的总计将与观察值的总计相同。

现在,回到这个公式,如果我们对所有(观察值减去预期值)的平方除以预期值求和,将得到卡方值33.2。在卡方表中,我们查找自由度等于1的行,找到最接近29.6的值。这里,我们可以看到29.6将落在P值小于0.05的范围内。因此,我们可以说P值小于0.05。由于P值小于0.05,我们拒绝两个变量独立的原假设,从而得出结论:燃料类型和进气方式之间存在关联。

💻 使用Python实现

要在Python中实现这一点,我们将使用SciPy统计包中的卡方列联函数。

该函数将输出卡方检验值29.6。第二个值是P值,非常接近0,以及自由度1。如果你还记得,卡方表没有给出确切的P值,而是给出了它所在的范围。Python将给出确切的P值。我们可以看到与之前幻灯片相同的结果。

它还输出了我们手动计算的预期值。

由于P值接近0,我们拒绝两个变量独立的原假设,并得出结论:有证据表明燃料类型和进气方式之间存在关联。

📚 课程总结

本节课中,我们一起学习了如何使用卡方检验来分析两个分类变量之间的关联关系。我们了解了卡方检验的原理、公式计算,并通过汽车数据集的实例,演示了如何手动计算以及使用Python的SciPy库快速执行检验并解读结果。关键点在于,卡方检验帮助我们判断变量是否独立,当P值小于显著性水平(如0.05)时,我们有理由认为变量间存在关联。

028:相关性分析

在本节课中,我们将要学习相关性分析。相关性是数据分析中的一个核心概念,它帮助我们理解不同变量之间是否存在关联,以及这种关联的强度和方向。通过本课的学习,你将能够识别并解释变量间的相关关系,并理解其与因果关系的区别。

🔗 什么是相关性?

上一节我们介绍了数据分析的基本流程,本节中我们来看看一个关键的统计度量:相关性。

相关性是一种统计指标,用于衡量不同变量在多大程度上是相互依存的。换句话说,当我们观察两个变量随时间的变化时,如果一个变量发生变化,这种变化会如何影响另一个变量。

例如,吸烟与肺癌之间存在相关性,因为吸烟会提高患肺癌的几率。

🌂 相关性与因果关系

理解相关性后,一个至关重要的点是区分相关性与因果关系。

相关性并不意味着因果关系。我们可以说雨伞和降雨是相关的,但我们没有足够的信息断定是雨伞导致了降雨,还是降雨导致了人们使用雨伞。在数据科学中,我们通常更多地处理相关性,而非急于下因果结论。

📈 正相关示例:发动机大小与价格

现在,让我们通过具体例子来观察相关性。我们将可视化两个变量:发动机大小和汽车价格。

我们将使用散点图并添加一条称为回归线的直线来可视化这两个变量,这条线指示了两者之间的关系。

这个图表的主要目标是观察发动机大小是否对价格有影响。在这个例子中,你可以看到穿过数据点的直线非常陡峭,这表明两个变量之间存在正线性关系。随着发动机尺寸值的增加,价格值也随之上升,且直线的斜率为正。因此,发动机大小与价格之间存在正相关

我们可以使用Seaborn库的regplot函数来创建这个散点图。核心代码如下:

import seaborn as sns
sns.regplot(x='engine-size', y='price', data=df)

📉 负相关示例:高速公路油耗与价格

接下来,我们看看另一个例子:高速公路每加仑英里数(油耗)与汽车价格的关系。

从图中可以看出,当高速公路油耗值上升时,价格值下降。因此,高速公路油耗与价格之间存在负线性关系。虽然这种关系是负向的,但直线的斜率依然陡峭,这意味着高速公路油耗仍然是预测价格的一个良好指标。这两个变量被称为具有负相关

➰ 弱相关示例:峰值转速与价格

最后,我们来看一个弱相关的例子:峰值转速(RPM)与价格。

在这个例子中,无论是低峰值转速还是高峰值转速,都对应着低价格和高价格。因此,我们无法有效地使用峰值转速来预测价格值。这表明两者之间的相关性非常弱。

📝 本节总结

本节课中我们一起学习了相关性分析。我们了解到:

  • 相关性是衡量变量间相互依存程度的统计指标。
  • 相关性不等于因果关系。
  • 正相关意味着一个变量增加时,另一个也增加。
  • 负相关意味着一个变量增加时,另一个减少。
  • 通过散点图和回归线可以直观地判断相关性的方向和强度。

掌握相关性分析是理解数据中变量关系的重要一步,为后续的建模和预测分析奠定基础。

029:相关性统计

在本节课中,我们将学习如何衡量连续数值变量之间关系的强度,即相关性统计。我们将重点介绍皮尔逊相关系数,并学习如何解读其结果,包括相关系数和P值。最后,我们将通过一个汽车数据的例子,演示如何计算相关性并利用热力图进行可视化分析。


🔍 皮尔逊相关系数简介

上一节我们介绍了数据分析的基本概念,本节中我们来看看如何量化变量之间的关系。衡量连续数值变量之间相关性强度的一种方法是使用皮尔逊相关系数。

皮尔逊相关系数方法会给出两个值:相关系数P值


📈 如何解读相关系数

那么,我们如何解读这些值呢?对于相关系数:

  • 一个接近 1 的值意味着存在强正相关
  • 一个接近 -1 的值意味着存在强负相关
  • 一个接近 0 的值意味着变量之间没有相关性

🎯 如何解读P值

接下来,P值会告诉我们对于计算出的相关性有多大的把握。

以下是P值解读的准则:

  • P值 小于 0.001,表明我们对计算出的相关系数有很强的把握
  • P值 介于 0.001 和 0.05 之间,表明我们有中等的把握
  • P值 介于 0.05 和 0.1 之间,表明我们有较弱的把握
  • P值 大于 0.1,则表明我们完全不能确定存在相关性。

当相关系数接近1或-1,且P值小于0.001时,我们可以说存在强相关性。下图展示了具有不同相关性值的数据。


🚗 实战示例:汽车数据相关性分析

在这个例子中,我们想看看变量“马力”和“汽车价格”之间的相关性。使用scipy.stats包可以非常简便地计算皮尔逊相关系数。

# 示例代码:使用 scipy.stats 计算皮尔逊相关系数
from scipy import stats
stats.pearsonr(df['horsepower'], df['price'])

我们可以看到,相关系数大约为0.8,这个值接近1,因此存在强正相关。我们还可以看到P值非常小,远小于0.001。因此我们可以得出结论:我们确信存在强正相关。


🗺️ 相关性热力图分析

将所有的变量都考虑进来,我们现在可以创建一个热力图,来指示每对变量之间的相关性。配色方案表示皮尔逊相关系数,即两个变量之间相关性的强度。

我们可以看到一条深红色的对角线,表明这条对角线上的所有值都高度相关。这很容易理解,因为仔细观察,对角线上的值是所有变量与自身的相关性,其值总是为1

这个相关性热力图很好地概述了不同变量之间是如何相互关联的,最重要的是,这些变量与“价格”是如何关联的。


📝 课程总结

本节课中,我们一起学习了相关性统计的核心方法。我们介绍了皮尔逊相关系数及其两个关键输出:相关系数(衡量关系强度与方向)和P值(衡量结果的统计显著性)。通过汽车数据的实例,我们实践了如何使用Python计算相关性,并学会了通过热力图来直观展示多个变量之间的复杂关系。理解相关性是发现数据中潜在模式和关系的重要一步。

030:两分类变量关联分析(卡方检验)

在本节课中,我们将学习如何判断两个分类变量之间是否存在关联关系。

概述

当我们处理两个分类变量之间的关系时,无法使用适用于连续变量的相关性分析方法。此时,我们需要采用卡方检验来评估关联性。

什么是卡方检验?🔍

上一节我们介绍了分析分类变量关联的必要性,本节中我们来看看核心工具——卡方检验。

卡方检验旨在检验观察到的分布是否可能由随机因素导致。

它衡量的是:如果变量之间是独立的,观测数据的分布与期望分布的拟合程度如何。

卡方检验的核心概念

在进入具体示例之前,让我们先了解一些重要概念。

卡方检验的原假设是:变量之间是独立的。

该检验将观测数据与模型在“数据随机分布于不同类别”这一假设下的期望值进行比较。

任何时候,只要观测数据与期望值模型不符,变量之间存在依赖关系的可能性就越大,从而证明原假设不成立。

需要明确的是,卡方检验只能告诉你变量间是否存在关系,而无法说明关系的具体类型。

实战示例:汽车数据集

我们将使用一个汽车数据集,假设我们想测试燃料类型进气方式之间的关系,这两个都是分类变量。

燃料类型分为汽油或柴油。进气方式分为标准或涡轮增压。

创建列联表

要进行检验,我们首先需要统计每个类别中的汽车数量。

这可以通过使用Pandas库创建一个交叉表来完成。交叉表是显示两个或多个变量之间关系的表格。

当表格只显示两个分类变量之间的关系时,交叉表也被称为列联表

在我们的案例中,列联表显示了每个类别的计数:

  • 标准进气、柴油燃料的汽车数量
  • 标准进气、汽油燃料的汽车数量
  • 涡轮增压、柴油燃料的汽车数量
  • 涡轮增压、汽油燃料的汽车数量

卡方公式与计算

卡方检验的公式如下:

χ² = Σ [ (观测值 - 期望值)² / 期望值 ]

其中,期望值是基于给定的行总计和列总计计算得出的。也就是说,如果我们不知道观测值,单个单元格的期望值会是多少。

以下是计算期望值的方法:

要计算“标准进气、柴油燃料”的期望值,我们取该行的总计(20),乘以该列的总计(168),再除以总计数(205)。

期望值 = (行总计 × 列总计) / 总计数

这将得到16.39。如果我们对“涡轮增压、汽油燃料”进行同样的计算,取行总计185,乘以列总计37,再除以总计数205,得到33.39。

对所有类别重复此过程,即可得到所有期望值。请注意,期望值的行总计、列总计和总计数与观测值的相应总计保持一致。

现在,回到卡方公式。如果我们对所有类别的 (观测值 - 期望值)² / 期望值 进行求和,将得到一个卡方值29.6。

结果解读

在卡方分布表中,我们查找自由度为1(行)时,最接近29.6的值。可以发现,29.6对应的P值小于0.05。

由于P值小于0.05,我们拒绝“两个变量独立”的原假设。因此,我们得出结论:燃料类型和进气方式之间存在关联。

使用Python实现卡方检验 🐍

要在Python中实现此检验,我们将使用scipy.stats包中的chi2_contingency函数。

该函数将输出卡方检验值29.6。第二个值是P值,它非常接近0。第三个值是自由度,为1。

如果你还记得,卡方分布表没有给出确切的P值,而是给出了一个范围。Python则会给出精确的P值。我们可以看到结果与之前幻灯片中的计算结果一致。

该函数还会打印出我们之前手动计算过的期望值。

由于P值接近0,我们拒绝“两个变量独立”的原假设,并得出结论:有证据表明燃料类型和进气方式之间存在关联。

总结

本节课中,我们一起学习了如何使用卡方检验来分析两个分类变量之间的关联性。我们了解了卡方检验的原理、假设和计算公式,并通过一个汽车数据集的实例,演示了如何手动计算以及如何使用Python的scipy.stats.chi2_contingency函数快速完成检验和结果解读。记住,卡方检验是判断分类变量是否相关的有力工具。

031:模型开发

在本节课中,我们将学习如何通过模型开发来预测汽车价格。我们将探讨线性回归、模型评估方法以及如何利用数据特征提升预测准确性。


🎯 模型开发概述

模型或估计器可被视为一个数学方程,用于根据一个或多个输入值预测目标值。

该过程涉及将一个或多个自变量(特征)与因变量(目标)关联起来。例如,输入汽车的高速公路每加仑英里数作为特征,模型输出的因变量即为价格。

通常,数据越相关,模型预测越准确。


🔍 数据的重要性

为了理解为何更多数据至关重要,请考虑以下情况:假设有两辆几乎完全相同的汽车,但粉色汽车的售价显著低于红色汽车。

如果您模型的独立变量或特征中不包含颜色信息,模型将为这两辆车预测相同的价格,而实际上粉色汽车可能售价低得多。

因此,除了收集更多数据,尝试不同类型的模型也是提高预测准确性的关键。


📈 回归模型类型

在本课程中,您将学习以下三种回归模型:

  1. 简单线性回归
  2. 多元线性回归
  3. 多项式回归

📊 模型评估方法

我们将使用可视化方法评估模型,并介绍多项式回归和管道技术。

对于样本内评估,一个常用的指标是均方误差,其公式为:

[
MSE = \frac{1}{n} \sum_{i=1}^{n} (Y_i - \hat{Y}_i)^2
]

其中,( n ) 是样本数量,( Y_i ) 是实际值,( \hat{Y}_i ) 是预测值。


🛠️ 预测与决策制定

通过学习这些方法,您将能够进行预测并支持决策制定。例如,您可以确定一辆二手车的公平市场价值。


✅ 课程总结

本节课中,我们一起学习了模型开发的基本概念,包括如何将特征与目标变量关联、理解数据量的重要性,并初步了解了简单线性回归、多元线性回归和多项式回归等模型。我们还介绍了使用均方误差进行模型评估的方法,为后续的实际预测和决策制定奠定了基础。

032:线性回归与多元线性回归

在本节课中,我们将学习线性回归与多元线性回归的基本概念。我们将了解如何使用一个或多个自变量来预测因变量,并通过Python代码实现这些模型。


🧠 线性回归与多元线性回归概述

线性回归使用一个自变量进行预测。多元线性回归使用多个自变量进行预测。


📈 简单线性回归

简单线性回归(SLR)是一种帮助我们理解两个变量之间关系的方法。这两个变量是预测变量(自变量X)和目标变量(因变量Y)。我们希望找到这两个变量之间的线性关系。

线性关系的公式如下:

Y = B₀ + B₁X

其中,参数B₀是截距,参数B₁是斜率。当我们拟合或训练模型时,我们会得到这些参数。这一步涉及大量数学计算,因此我们不会重点讨论这一部分。

让我们来澄清预测步骤。


🚗 简单线性回归示例

很难确定一辆车的价格,但高速公路每加仑英里数可以在车主手册中找到。如果我们假设这些变量之间存在线性关系,我们可以利用这种关系建立一个模型来确定汽车的价格。

如果高速公路每加仑英里数是20,我们可以将这个值输入模型,得到22000美元的预测价格。

为了确定这条线,我们从数据集中选取数据点(此处用红色标记)。然后,我们使用这些训练点来拟合我们的模型。训练点的结果就是参数。

我们通常将数据点存储在两个数据框或NumPy数组中。我们想要预测的值称为目标,存储在数组Y中。我们将自变量存储在数据框或数组X中。每个样本对应于每个数据框或数组中的不同行。


🎲 模型中的噪声

在许多情况下,许多因素会影响人们为汽车支付的价格,例如品牌或车龄。这种不确定性是通过假设在直线上的点上添加一个小的随机值来考虑的。这被称为噪声。

左侧的图显示了噪声的分布。纵轴显示添加的值,横轴说明添加该值的概率。通常,会添加一个小的正值或小的负值。有时会添加较大的值,但在大多数情况下,添加的值接近0。


🔄 模型训练与预测过程总结

我们可以这样总结整个过程:我们有一组训练点。我们使用这些训练点来拟合或训练模型,并获得参数。然后我们在模型中使用这些参数。现在我们有了一个模型。我们在Y上使用帽子符号表示模型是一个估计值。

我们可以使用这个模型来预测我们未见过的值。例如,我们没有高速公路每加仑英里数为20的汽车。我们可以使用我们的模型来预测这辆车的价格。但别忘了,我们的模型并不总是正确的。

我们可以通过比较预测值与实际值来看到这一点。我们有一个高速公路每加仑英里数为10的样本,但预测值与实际值不匹配。如果线性假设是正确的,这种误差是由于噪声造成的,但也可能有其他原因。


🐍 在Python中拟合模型

要在Python中拟合模型,首先我们从scikit-learn导入线性模型。

from sklearn import linear_model

然后使用构造函数创建一个线性回归对象。我们定义预测变量和目标变量。然后使用fit方法拟合模型并找到参数B₀和B₁。输入是特征和目标。我们可以使用predict方法获得预测。输出是一个数组。该数组的样本数与输入X相同。

截距B₀是对象lm的一个属性。

lm.intercept_

斜率B₁也是对象lm的一个属性。

lm.coef_

价格与高速公路每加仑英里数之间的关系由以下粗体方程给出:

价格 = 38423.31 - 821.73 × 高速公路每加仑英里数

这与我们之前讨论的方程类似。


🔢 多元线性回归

多元线性回归用于解释一个连续目标变量Y与两个或更多预测变量X之间的关系。

如果我们有四个预测变量,那么B₀是截距(X=0时的值),B₁是X₁的系数或参数,B₂是X₂的系数或参数,依此类推。

如果只有两个变量,那么我们可以将数值可视化。考虑以下函数。变量X₁和X₂可以在二维平面上可视化。让我们在下一张幻灯片中做一个例子。


📊 多元线性回归可视化示例

该表包含预测变量X₁和X₂的不同值。每个点的位置放置在二维平面上,并相应地进行颜色编码。预测变量X₁和X₂的每个值将被映射到一个新值Ŷ。Ŷ的新值在垂直方向上映射,其高度与Ŷ的值成比例。


🐍 拟合多元线性回归

我们可以如下拟合多元线性回归。我们可以提取四个预测变量并将它们存储在变量Z中。然后像以前一样使用fit方法训练模型,输入特征(自变量)和目标。我们也可以使用predict方法获得预测。在这种情况下,输入是一个具有四列的数组或数据框。行数对应于样本数。输出是一个数组,其元素数量与样本数相同。

截距是对象的一个属性,系数也是属性。将因变量名称替换为实际名称来可视化方程是有帮助的。这与我们之前讨论的形式相同。


📝 总结

在本节课中,我们一起学习了线性回归和多元线性回归。我们了解了如何使用一个或多个自变量来预测因变量,探讨了模型中的噪声概念,并通过Python代码示例演示了如何实现和评估这些模型。理解这些基础概念是进行更复杂数据分析的重要一步。

033:可视化模型评估

在本节课中,我们将学习如何使用可视化工具来评估回归模型。我们将介绍三种核心的可视化方法:回归图、残差图和分布图。这些图表能帮助我们直观地理解模型的预测效果、误差分布以及模型与数据的关系。


🔍 回归图

上一节我们介绍了模型评估的基本概念,本节中我们来看看第一种可视化工具——回归图。

回归图是估计两个变量之间关系、相关性强弱以及关系方向(正相关或负相关)的良好工具。在回归图中,横轴代表自变量,纵轴代表因变量。图中的每个点代表一个不同的数据点,而拟合线则代表模型的预测值。

有多种方法可以绘制回归图,其中一种简单的方法是使用 Seaborn 库中的 regplot 函数。

以下是绘制回归图的步骤:

  1. 首先导入 seaborn 库。
  2. 使用 regplot 函数。
    • 参数 x 是包含自变量(特征)的列名。
    • 参数 y 是包含因变量(目标)的列名。
    • 参数 data 是数据框的名称。

示例代码如下:

import seaborn as sns
sns.regplot(x='independent_variable', y='dependent_variable', data=df)

📉 残差图

了解了如何通过回归图观察整体关系后,我们接下来深入分析模型的误差,这就需要用到残差图。

残差图展示了实际值与预测值之间的误差。我们通过用预测值减去实际目标值来得到残差。然后,我们将残差值绘制在纵轴上,自变量作为横轴。

观察残差图可以为我们提供关于数据的洞察。我们期望看到的结果是:残差均值为0,围绕X轴均匀分布,且方差相似,没有明显的曲线模式。

以下是几种典型的残差图模式:

  • 理想的线性模式:残差随机、均匀地分布在零点线上下,表明线性模型是合适的。
  • 存在曲率的模式:残差误差的值随X变化。例如,在某些区域所有残差都为正,在另一些区域则为负,且误差较大。这表明残差不是随机分布的,线性假设可能不正确,暗示了非线性函数的存在。
  • 异方差模式:残差的方差随X的增加而增加。这表明我们的模型可能不正确。

我们可以使用 seaborn 来创建残差图。首先导入 seaborn,然后使用 residplot 函数。第一个参数是自变量(特征)序列,第二个参数是因变量(目标)序列。

示例代码如下:

import seaborn as sns
sns.residplot(x=feature_series, y=target_series)


📊 分布图

在分析了单变量的误差后,对于具有多个自变量的模型,我们可以使用分布图来更全面地比较预测值与实际值。

分布图用于比较预测值与实际值的分布。这些图对于可视化具有多个自变量或特征的模型极为有用。

让我们看一个简化的例子。我们检查纵轴,然后计算并绘制预测值大约等于1、2、3等值的点的数量。接着,我们对目标值重复这个过程。由于目标和预测值是连续值,而直方图适用于离散值,因此 pandas 会将它们转换为分布。纵轴经过缩放,使得分布下的面积等于一。

这是一个使用分布图的例子。因变量或特征是价格。模型得出的拟合值用蓝色表示,实际值用红色表示。通过比较,我们可以看出预测值在哪些区间更准确或更不准确。

以下是创建分布图的代码。实际值作为参数传入。因为我们想要的是分布图而不是直方图,所以需要将 hist 参数设置为 False。可以设置颜色和标签。预测值用于第二个图的绘制,其余参数相应设置。

示例代码如下:

import seaborn as sns
# 绘制实际值分布
sns.distplot(actual_values, hist=False, color="red", label="Actual Values")
# 绘制预测值分布
sns.distplot(predicted_values, hist=False, color="blue", label="Predicted Values")
plt.legend()


✅ 总结

本节课中我们一起学习了三种用于模型评估的可视化方法。回归图帮助我们直观理解变量间的整体关系;残差图让我们深入分析预测误差的模式,判断线性假设是否成立;分布图则能有效比较在多特征模型下预测值与实际值的整体分布情况。掌握这些可视化工具,将极大地提升我们诊断和解释回归模型的能力。

034:可视化模型评估 📊

在本节课中,我们将学习如何使用可视化工具来评估回归模型。我们将介绍三种关键的图形方法:回归图、残差图和分布图。这些工具能帮助我们直观地理解模型的性能、变量间的关系以及预测的准确性。


回归图 📈

上一节我们介绍了模型评估的基本概念,本节中我们来看看第一种可视化工具——回归图。

回归图是估计两个变量之间关系、相关性强弱以及关系方向(正相关或负相关)的良好方法。

在回归图中:

  • 横轴代表自变量
  • 纵轴代表因变量
  • 图中的每个点代表一个不同的数据点(目标值)。
  • 拟合的直线代表模型的预测值

有多种方法可以绘制回归图。一种简单的方法是使用 Seaborn 库中的 regplot 函数。

以下是绘制回归图的步骤:

首先,导入 seaborn 库,然后使用 regplot 函数。

  • 参数 x 是包含自变量(特征)的列名。
  • 参数 y 是包含因变量(目标)的列名。
  • 参数 data 是数据框的名称。

示例代码如下:

import seaborn as sns
sns.regplot(x='independent_variable', y='dependent_variable', data=df)


残差图 🔍

了解了如何可视化变量关系后,我们接下来看看如何评估预测的误差,即残差图。

残差图展示了实际值预测值之间的误差。

检查预测值和实际值,我们会发现一个差值。这个值是通过从预测值中减去实际目标值得到的。

然后,我们将这个差值(残差)绘制在纵轴上,自变量作为横轴。对第二个样本,我们重复这个过程:从预测值中减去目标值,然后相应地绘制该值。

观察残差图可以让我们深入了解数据。我们期望看到的结果是:残差均值为0,围绕X轴均匀分布,且方差相似,没有明显的曲线模式。

  • 理想的残差图:残差随机分散在0线上下,表明线性模型是合适的。
  • 存在曲率的残差图:误差值随X变化。例如,在某些区域所有残差都为正,在另一些区域为负,且误差较大。这表明残差不是随机分离的,线性假设可能不正确,暗示可能需要非线性函数。我们将在下一节处理这个问题。
  • 异方差残差图:残差的方差随X增加而增大。因此,我们的模型可能不正确。

我们可以使用 seaborn 来创建残差图。首先导入 seaborn,然后使用 residplot 函数。第一个参数是自变量(特征)序列,第二个参数是因变量(目标)序列。

示例代码如下:

import seaborn as sns
sns.residplot(x=feature_series, y=target_series)

在这种情况下,我们可能会看到残差存在曲率。


分布图 📉

在学习了评估线性假设和误差模式的工具后,最后我们来看一种用于比较预测值与实际值整体分布的强大工具——分布图。

分布图计算并绘制预测值与实际值的分布。这些图对于可视化具有多个自变量(特征)的模型极为有用。

让我们看一个简化的例子。我们检查纵轴,然后计算并绘制预测值大约等于1的数据点数量。接着,计算并绘制预测值大约等于2的数据点数量。我们重复这个过程,处理预测值大约等于3的数据点。

然后,我们对目标值重复这个过程。在这个例子中,所有目标值都大约等于2。目标和预测值是连续的,而直方图适用于离散值。因此,pandas 会将它们转换为分布图。纵轴经过缩放,使得分布下的面积等于一。

这是一个使用分布图的例子。因变量(特征)是价格。模型得出的拟合值用蓝色表示,实际值用红色表示。我们看到,价格在40000到50000范围内的预测值不准确。而价格在10000到20000范围内的预测值则更接近目标值。在这个例子中,我们使用了多个特征或自变量,与上一张幻灯片上的图相比,我们看到预测值更接近目标值。

以下是创建分布图的代码。实际值用作参数。我们需要一个分布图而不是直方图,因此将 hist 参数设置为 False。颜色设为红色,并包含标签。预测值用于第二个图,其余参数相应设置。

示例代码如下:

import seaborn as sns
# 绘制实际值分布
sns.distplot(actual_values, hist=False, color="red", label="Actual Values")
# 绘制预测值分布
sns.distplot(predicted_values, hist=False, color="blue", label="Predicted Values")
plt.legend()


总结 🎯

本节课中我们一起学习了三种用于模型评估的可视化方法:

  1. 回归图:用于直观展示自变量与因变量之间的线性关系及趋势。
  2. 残差图:用于诊断模型的误差是否符合线性回归的假设(如误差随机性、同方差性),从而判断模型是否合适。
  3. 分布图:用于直接比较预测值分布与实际值分布的吻合程度,尤其适用于多特征模型。

掌握这些可视化工具,将帮助你更直观、更有效地评估和解释回归模型的性能。

035:多项式回归与流水线

在本节课中,我们将学习多项式回归和流水线。当线性模型无法很好地拟合数据时,多项式回归提供了一种有效的替代方案。流水线则能帮助我们简化代码,将多个数据处理步骤有序地组合在一起。

🔍 多项式回归简介

上一节我们介绍了线性回归。本节中我们来看看多项式回归。

多项式回归是广义线性回归的一种特殊形式。这种方法对于描述曲线关系非常有益。

什么是曲线关系?

曲线关系是指通过将预测变量平方或设置更高阶项来获得的关系。我们通过变换数据来实现这一点。

以下是多项式回归的几种常见形式:

  • 二次多项式回归:模型中的预测变量被平方。我们用括号表示指数。公式为:y = β₀ + β₁x + β₂x²。这是一个二阶多项式回归,其函数图像呈现抛物线形状。

  • 三次多项式回归:模型中的预测变量被立方。公式为:y = β₀ + β₁x + β₂x² + β₃x³。这是一个三阶多项式回归。观察图像可以发现,函数具有更多的变化。

当二阶或三阶多项式仍未达到良好拟合时,还可以使用更高阶的多项式回归。改变多项式回归的阶数会显著改变图形的形状。回归的阶数选择至关重要,选择合适的值可以获得更好的拟合效果。

在所有情况下,变量与参数之间的关系始终是线性的。

🐍 Python中的多项式回归实现

让我们看一个基于数据生成多项式回归模型的例子。

在Python中,我们可以使用polyfit函数来实现。

# 示例:使用numpy的polyfit函数拟合一个三阶多项式
import numpy as np

# 假设x和y是已有的数据
# 拟合一个三阶多项式
model = np.polyfit(x, y, 3)
print(model)

我们可以打印出模型参数。该模型的符号形式由以下表达式给出:y = -1.557x³ + 204.8x² + 8965x + 1.37×10⁵

多维多项式回归

我们也可以进行多维多项式线性回归。表达式可能会变得复杂。以下是一个二维二阶多项式的一部分项示例。

NumPy的polyfit函数无法执行这种类型的回归。我们使用scikit-learn中的preprocessing库来创建一个多项式特征对象。

以下是创建和转换多项式特征的步骤:

  1. 构造器将多项式的阶数作为参数。
  2. 然后使用fit_transform方法将特征转换为多项式特征。

让我们看一个更直观的例子。

from sklearn.preprocessing import PolynomialFeatures

# 假设我们有一个二维特征数组X
# 创建一个2阶多项式特征对象
pr = PolynomialFeatures(degree=2)
# 转换原始特征
X_poly = pr.fit_transform(X)
print(X_poly.shape)  # 查看新特征的维度

考虑这里显示的特征。应用该方法后,我们转换了数据。现在我们拥有了一组新的特征,它们是原始特征的转换版本。

⚙️ 数据预处理与标准化

随着数据维度的增加,我们可能希望同时标准化多个特征。在scikit-learn中,我们可以使用preprocessing模块来简化许多任务。

例如,我们可以同时标准化每个特征。

以下是使用StandardScaler的步骤:

  1. 导入StandardScaler
  2. 创建并训练(拟合)该对象。
  3. 然后使用它来转换数据。
from sklearn.preprocessing import StandardScaler

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/c971fac86ce34a1f98bce910525d00e3_38.png)

# 创建标准化对象
scale = StandardScaler()
# 拟合数据(计算均值和标准差)
scale.fit(X)
# 转换数据
X_scale = scale.transform(X)

preprocessing库中提供了更多的归一化方法以及其他转换功能。

🚀 使用流水线简化流程

我们可以通过使用流水线库来简化代码。获得预测通常涉及许多步骤,例如归一化、多项式变换和线性回归。我们使用流水线来简化这个过程。

流水线按顺序执行一系列转换,最后一步进行预测。

以下是创建和使用流水线的步骤:

  1. 首先导入所有需要的模块,然后导入Pipeline库。
  2. 创建一个元组列表。元组中的第一个元素包含估计器/模型的名称,第二个元素包含模型构造函数。
  3. 将这个列表输入到Pipeline构造函数中。

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.linear_model import LinearRegression

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/c971fac86ce34a1f98bce910525d00e3_51.png)

# 创建步骤列表
steps = [
    ('scale', StandardScaler()),
    ('poly', PolynomialFeatures(degree=2)),
    ('model', LinearRegression())
]

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/c971fac86ce34a1f98bce910525d00e3_53.png)

# 创建流水线对象
pipe = Pipeline(steps)

# 训练流水线
pipe.fit(X_train, y_train)

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/c971fac86ce34a1f98bce910525d00e3_55.png)

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/c971fac86ce34a1f98bce910525d00e3_56.png)

# 进行预测
y_pred = pipe.predict(X_test)

我们现在有了一个流水线对象。我们可以通过对流水线对象应用fit方法来训练它。我们也可以用它来生成预测。

该方法会先标准化数据,然后执行多项式变换,最后输出预测结果。

📝 课程总结

本节课中,我们一起学习了多项式回归与流水线。我们了解到,当数据关系呈曲线时,多项式回归是线性模型的有力补充。通过引入高阶项,我们可以更好地拟合复杂的数据模式。同时,我们掌握了如何使用scikit-learn的流水线功能,将数据预处理、特征工程和模型训练等多个步骤封装成一个简洁、可重复的工作流,这极大地提高了代码的效率和可维护性。

036:样本内评估指标

在本节课中,我们将学习如何通过数值指标来评估回归模型的性能。我们将重点介绍两个核心的样本内评估指标:均方误差R平方。这些指标能帮助我们量化模型对数据的拟合程度。

上一节我们介绍了如何通过可视化方法评估模型。本节中,我们来看看如何用数值指标进行更精确的评估。

这些指标是一种数值化方法,用于确定模型对数据的拟合程度。

以下是两个常用于确定模型拟合度的重要指标:

  • 均方误差
  • R平方

📏 均方误差

均方误差衡量的是模型预测值与实际值之间的平均平方差。其计算公式为:

MSE = (1/n) * Σ (Y_i - Ŷ_i)²

其中:

  • Y_i 是第 i 个样本的实际值。
  • Ŷ_i 是第 i 个样本的预测值。
  • n 是样本总数。

计算MSE的步骤如下:

  1. 计算每个样本的预测误差:Y_i - Ŷ_i
  2. 将每个误差值平方。
  3. 将所有平方误差求和。
  4. 将总和除以样本数量 n,得到平均值。

在Python中,我们可以使用scikit-learn库方便地计算MSE:

from sklearn.metrics import mean_squared_error
mse = mean_squared_error(y_actual, y_predicted)

mean_squared_error 函数接收两个输入参数:目标变量的实际值数组和目标变量的预测值数组。

🔢 R平方

R平方,也称为决定系数,用于衡量数据点与拟合回归线的接近程度。它本质上是在比较我们的回归模型与一个简单模型(即数据点的平均值)的优劣。

如果自变量 X 是一个好的预测因子,那么我们的回归模型应该比仅仅使用平均值 Ȳ 预测得更好。

R平方的计算公式为:

R² = 1 - (MSE_regression / MSE_mean)

其中:

  • MSE_regression 是回归线的均方误差。
  • MSE_mean 是使用数据点平均值 Ȳ 作为预测值时的均方误差。

R平方的值通常在0到1之间。

理解R平方的值

  • R² 接近 1:表示回归线对数据的拟合非常好。此时,回归线的MSE远小于平均值的MSE,公式中的比值很小,使得R²接近1。
  • R² 接近 0:表示回归线的拟合效果不佳,其预测能力与直接使用数据平均值差不多。此时,回归线的MSE与平均值的MSE大小相近,比值接近1,导致R²接近0。

在Python中,我们可以通过线性回归模型的 score 方法来获取R平方值:

from sklearn.linear_model import LinearRegression
lm = LinearRegression()
lm.fit(X, y)
r_squared = lm.score(X, y)

从该示例得到的值(例如0.49695)可以解释为:大约49.695%的价格变化可以由这个简单线性模型来解释。

通常,R平方值介于0和1之间。如果你的R平方值为负数,这可能是由于过拟合造成的,我们将在下一个模块中讨论这个问题。

📝 总结

本节课中,我们一起学习了用于回归模型样本内评估的两个核心数值指标:

  1. 均方误差:衡量预测值与实际值之间的平均平方误差,值越小表示模型拟合越好。
  2. R平方:衡量模型解释数据变异性的比例,值越接近1表示模型拟合度越高。

理解并计算这些指标,是评估和比较不同回归模型性能的基础。

037:多项式回归与流水线

在本节课中,我们将学习多项式回归和流水线。当线性模型无法很好地拟合数据时,多项式回归是一种有效的替代方法。我们还将探讨如何使用流水线来简化代码流程。

🔍 多项式回归简介

上一节我们介绍了线性回归,本节中我们来看看多项式回归。当线性模型不是数据的最佳拟合时,我们可以使用另一种回归模型,即多项式回归。

多项式回归是广义线性回归的一个特例。这种方法对于描述曲线关系非常有益。

什么是曲线关系?曲线关系是通过对模型中的预测变量进行平方或设置更高阶项来获得的,即对数据进行变换。

📈 多项式回归的类型

以下是多项式回归的几种常见类型:

  • 二次多项式回归:模型可以是二次的,这意味着模型中的预测变量被平方。我们使用括号表示指数。这是一个二阶多项式回归,其函数图像为抛物线。
    • 公式示例y = β₀ + β₁x + β₂x²
  • 三次多项式回归:模型可以是三次的,这意味着预测变量被立方。这是三阶多项式回归。通过观察图像,我们可以看到函数有更多的变化。
    • 公式示例y = β₀ + β₁x + β₂x² + β₃x³
  • 更高阶多项式回归:当二阶或三阶多项式仍未达到良好拟合时,可以使用更高阶的多项式回归。通过图像我们可以看到,改变多项式回归的阶数会显著改变图形的形状。

回归的阶数选择非常重要,如果选择了合适的值,可以获得更好的拟合效果。在所有情况下,变量与参数之间的关系始终是线性的。

💻 Python中的多项式回归实现

让我们看一个数据示例,生成一个多项式回归模型。

在Python中,我们可以使用polyfit函数来实现。

在这个例子中,我们基于数据开发一个三阶多项式回归模型。我们可以打印出模型的符号形式,该模型由以下表达式给出:

y = -1.557x³ + 204.8x² + 8965x + 1.37 × 10⁵

我们也可以有多维多项式线性回归。表达式可能会变得复杂。这里展示的是一个二维二阶多项式的一些项。NumPy的polyfit函数无法执行这种类型的回归。

我们使用scikit-learn中的preprocessing库来创建一个多项式特征对象。构造函数将多项式的阶数作为参数。然后,我们使用fit_transform方法将特征转换为多项式特征。

让我们做一个更直观的例子。考虑这里显示的特征。应用该方法后,我们转换了数据。现在我们拥有了一组新的特征,它们是原始特征的转换版本。

🛠️ 数据预处理与标准化

随着数据维度的增加,我们可能希望在scikit-learn中标准化多个特征。我们可以使用preprocessing模块来简化许多任务。

例如,我们可以同时标准化每个特征。我们导入StandardScaler,训练该对象,然后使用fit方法拟合缩放器对象。接着,将数据转换为新的数据框或数组x_scale

预处理库中提供了更多的归一化方法以及其他转换方法。

⚙️ 使用流水线简化流程

我们可以通过使用流水线库来简化代码。获得预测需要许多步骤,例如归一化、多项式变换和线性回归。我们使用流水线来简化这个过程。

流水线按顺序执行一系列转换,最后一步执行预测。

首先,我们导入所有需要的模块。然后导入Pipeline库。我们创建一个元组列表,元组中的第一个元素包含估计器模型的名称,第二个元素包含模型构造函数。我们将列表输入到Pipeline构造函数中。

现在我们有了一个流水线对象。我们可以通过对流水线对象应用train方法来训练流水线。我们也可以进行预测。该方法会先归一化数据,然后执行多项式变换,最后输出预测结果。

📝 课程总结

本节课中,我们一起学习了多项式回归和流水线的概念与应用。我们了解到,当数据关系呈曲线时,多项式回归是比简单线性回归更有效的工具。同时,通过使用scikit-learn中的流水线,我们可以将数据预处理、特征转换和模型训练等多个步骤封装成一个简洁的流程,这大大提高了代码的可读性和可维护性。

038:预测与决策制定 📊

概述

在本节课中,我们将学习如何评估和验证回归模型的预测结果,并基于此进行决策。我们将探讨如何判断模型是否正确、如何解读预测值、以及使用哪些可视化与数值指标来评估模型性能。


模型预测与合理性检查

上一节我们介绍了如何训练模型,本节中我们来看看如何使用模型进行预测并判断其合理性。

首先,使用训练好的模型进行预测。回忆一下,我们使用 fit 方法训练模型。现在,我们想知道一辆高速公路油耗为30英里/加仑的汽车价格是多少。

将数值代入 predict 方法,我们得到预测价格为 $13771.30

这个结果看起来合理。例如,价格不是负数,也没有极高或极低。

我们可以通过检查 coef_ 属性来查看模型的系数。回忆一下,用于根据高速公路油耗预测价格的简单线性模型表达式为:

price = intercept + coef * highway_mpg

系数值对应高速公路油耗特征的倍数。因此,高速公路油耗每增加一个单位,汽车价格大约下降 $821。这个数值看起来也合理。


处理不合理的预测值

有时,模型会产生不合理的值。例如,如果我们绘制高速公路油耗在0到100范围内的模型预测图,会发现价格出现负值。

这可能是因为:

  1. 该范围内的数值不现实。
  2. 线性假设不正确。
  3. 我们没有该范围内汽车的数据。

在本例中,汽车不太可能有那么高的油耗范围,因此我们的模型看起来是有效的。

以下是生成指定范围内数值序列的方法:

import numpy as np
sequence = np.arange(1, 101, 1)
  • np.arange 函数用于生成序列。
  • 第一个参数是序列的起点。
  • 第二个参数是序列的终点加一。
  • 第三个参数是序列元素之间的步长,本例中为1。

我们可以使用这个序列的输出值来预测新值。输出是一个NumPy数组,但其中许多预测值是负数。


使用可视化方法评估模型

评估模型时,应首先尝试使用回归图进行可视化。请参阅实验部分了解如何绘制多项式回归图。

对于本例,自变量(高速公路油耗)的影响是明显的。数据趋势显示,随着自变量增加,因变量(价格)下降。该图还显示了一些非线性行为。

检查残差图时,我们发现残差呈现曲线,这暗示了数据存在非线性行为。

对于多元线性回归,分布图是一个很好的评估方法。例如,我们看到价格在30000到50000范围内的预测值不准确。

这表明非线性模型可能更合适,或者我们需要该范围内的更多数据。


使用数值指标评估模型

均方误差(MSE)或许是判断模型好坏最直观的数值指标。让我们看看不同的均方误差值如何影响模型。

第一张图的均方误差为 3495
第二张图的均方误差为 3652
最后一张图的均方误差为 12870

随着均方误差增大,目标点离预测线越来越远。

正如我们讨论过的,R平方是另一种流行的模型评估方法。它告诉你回归线对数据的拟合程度。R平方值的范围是0到1。

告诉我们,因变量的变异中有多大比例可以由自变量的回归来解释。

R平方等于1意味着因变量的所有变动都可以完全由自变量的变动来解释。

在R平方为 0.9986 的图中,我们看到红色目标点和蓝色预测线。模型看起来拟合得很好,这意味着超过99%的预测变量变异可以由自变量解释。

在R平方为 0.9226 的模型中,仍然存在很强的线性关系,模型拟合度仍然良好。

当R平方为 0.80.6 时,我们可以直观地看到数值分散在直线周围,但仍然接近直线。我们可以说,80%或60%的预测变量变异可以由自变量解释。

R平方为 0.61 意味着大约61%的观测变异可以由自变量解释。

R平方的可接受值取决于你研究的领域和具体用例。Falcon和Miller(1992)建议,可接受的R平方值至少应为 0.1


关于模型比较的注意事项

较低的均方误差是否意味着更好的拟合?不一定。

多元线性回归(MLR)模型的MSE将小于简单线性回归(SLR)模型的MSE,因为当模型中包含更多变量时,数据误差会减小。

同样,多项式回归的MSE也会小于常规线性回归的MSE。在下一节中,我们将探讨更准确的模型评估方法。


总结

本节课中,我们一起学习了如何对回归模型进行预测和评估决策。我们了解了检查预测结果合理性的重要性,并掌握了使用回归图、残差图和分布图进行可视化评估的方法。同时,我们学习了均方误差(MSE)和R平方这两个核心数值指标的含义与应用,认识到它们如何量化模型的拟合优度,并了解了在比较不同复杂度模型时解读这些指标的注意事项。

039:样本内评估指标

在本节课中,我们将学习如何通过数值指标来评估回归模型的性能。我们将重点介绍两个核心的样本内评估指标:均方误差(MSE)和决定系数(R²)。这些指标能帮助我们量化模型对数据的拟合程度。

上一节我们介绍了通过可视化方法评估模型,本节中我们来看看如何用数值进行更精确的评估。

📈 数值评估指标概述

这些指标是一种数值化方法,用于确定模型对数据的拟合程度。

以下是两个常用的重要指标:

  • 均方误差(Mean Squared Error, MSE)
  • 决定系数(R-squared)

🔢 均方误差(MSE)

MSE衡量的是预测值与实际值之间的平均平方误差。计算步骤如下:

  1. 计算每个数据点的误差:实际值(Y)减去预测值(Ŷ)。
  2. 将每个误差值平方。
  3. 对所有平方误差求平均值。

其公式为:
MSE = (1/n) * Σ (Yᵢ - Ŷᵢ)²

例如,若某点的实际值为150,预测值为50,则误差为100,平方后为10000。MSE是所有此类平方误差的平均值。

在Python中,我们可以使用scikit-learn库中的函数来计算MSE。

以下是计算MSE的代码示例:

from sklearn.metrics import mean_squared_error
mse = mean_squared_error(y_actual, y_predicted)

mean_squared_error函数接受两个输入:目标变量的实际值数组和预测值数组。

📊 决定系数(R²)

R²也称为判定系数,用于衡量数据点与拟合回归线的接近程度,即我们的模型相比简单基准模型(如使用目标变量的均值进行预测)的改善程度。

其计算公式为:
R² = 1 - (MSE(回归线) / MSE(数据均值))

R²的值通常在0到1之间。

  • R²接近1:表示回归线对数据的拟合很好,模型解释了大量方差。
  • R²接近0:表示回归线的拟合效果与仅使用数据均值差不多,模型性能不佳。
  • R²为负值:可能表明模型存在过拟合问题(我们将在后续模块讨论)。

在Python中,我们可以使用线性回归对象的.score()方法来获取R²值。

以下是获取R²值的代码示例:

from sklearn.linear_model import LinearRegression
lm = LinearRegression()
lm.fit(X, y)
r_squared = lm.score(X, y)

例如,如果得到的R²值为0.49695,我们可以说“该简单线性模型解释了价格约49.695%的变异”。

🎯 本节总结

本节课中我们一起学习了用于回归模型样本内评估的两个核心数值指标:

  1. 均方误差(MSE):衡量预测误差的平均大小,值越小表示模型拟合越好。
  2. 决定系数(R²):衡量模型相对于简单均值模型的解释能力,值越接近1表示模型拟合度越高。

理解这些指标对于评估和比较不同模型的性能至关重要。

040:预测与决策制定 📊

在本节课中,我们将学习如何评估预测模型的正确性,并基于模型结果进行决策制定。我们将探讨模型评估的多种方法,包括可视化、数值指标以及如何解读这些结果。


模型评估与合理性检查

上一节我们介绍了模型训练,本节中我们来看看如何判断模型是否正确。首先,你需要确保模型的结果是合理的。

以下是评估模型合理性的核心步骤:

  1. 使用可视化工具:通过图表直观地观察数据与模型的拟合情况。
  2. 计算数值评估指标:使用量化指标来评估模型性能。
  3. 比较不同模型:通过对比不同模型的评估结果来选择最佳模型。

让我们看一个预测的例子。回想一下,我们使用 fit 方法训练模型。现在,我们想预测一辆高速公路油耗为30英里/加仑的汽车价格。

将数值代入 predict 方法,我们得到预测价格为 $13771.30

这个结果看起来是合理的。例如,价格不是负数,也没有极高或极低。

我们可以通过检查 coef_ 属性来查看系数。回想一下,用于根据高速公路油耗预测价格的简单线性模型表达式为:

价格 = 截距 + 系数 * 高速公路油耗

这个系数对应着高速公路油耗特征的倍数。因此,高速公路油耗每增加一个单位,汽车价格大约下降 $821。这个值看起来也是合理的。


处理不合理的预测值

有时你的模型会产生不合理的值。例如,如果我们为高速公路油耗在0到100的范围内绘制模型,我们会得到负的价格预测值。

这可能是因为:

  1. 该范围内的数值不现实。
  2. 线性假设不正确。
  3. 我们没有该范围内汽车的数据。

在本例中,汽车不太可能有那么高的燃油里程,因此我们的模型看起来是有效的。

为了在指定范围内生成一系列值,我们需要导入 numpy,然后使用 numpy.arange 函数生成序列。

import numpy as np
sequence = np.arange(1, 101, 1)
  • 第一个参数是序列的起点。
  • 第二个参数是序列的终点加一。
  • 最后一个参数是序列中元素之间的步长。本例中为1,表示序列每次递增1。

我们可以使用输出来预测新值。输出是一个 numpy 数组,其中许多值是负数。


可视化评估方法

使用回归图可视化数据是你应该尝试的首要方法。请参阅实验部分以了解如何绘制多项式回归图。

对于这个例子,自变量的影响是明显的。在这种情况下,随着因变量增加,数据呈下降趋势。该图还显示了一些非线性行为。

检查残差图,我们看到残差具有曲线,这表明存在非线性行为。

分布图是评估多元线性回归的好方法。例如,我们看到价格在30000到50000范围内的预测值不准确。

这表明非线性模型可能更合适,或者我们需要该范围内的更多数据。


数值评估指标

均方误差(MSE)或许是判断模型好坏最直观的数值指标。让我们看看不同的均方误差值如何影响模型。

第一张图的均方误差为 3495
第二张图的均方误差为 3652
最后一张图的均方误差为 12870

随着均方误差增加,目标点离预测点越来越远。

正如我们讨论过的,R平方是另一种流行的模型评估方法。它告诉你回归线对模型的拟合程度。R平方值的范围是0到1。

R平方 = 1 - (残差平方和 / 总平方和)

R平方告诉我们因变量的变异中有多少百分比是由自变量的回归解释的。

R平方为1意味着因变量的所有变动完全由自变量的变动解释。

在这张图中,我们看到红色的目标点和蓝色的预测线,R平方为 0.9986。模型看起来拟合得很好。这意味着超过99%的预测变量变异可以由自变量解释。

这个模型的R平方为 0.9226。仍然存在很强的线性关系,模型仍然拟合良好。

R平方为0.8或0.6的数据,我们可以直观地看到数值分散在直线周围。它们仍然接近直线,我们可以说预测变量80%的变异可以由自变量解释。

R平方为 0.61 意味着大约61%的观测变异可以由自变量解释。

R平方的可接受值取决于你研究的领域和你的具体用例。Falcon和Miller(1992)建议,可接受的R平方值应至少为0.1。


关于模型比较的注意事项

较低的均方误差是否意味着更好的拟合?不一定。

多元线性回归模型的MSE将小于简单线性回归模型的MSE,因为当模型中包含更多变量时,数据的误差会减小。多项式回归的MSE也将小于常规回归的MSE。

在下一节中,我们将探讨更准确的模型评估方法。


总结

本节课中我们一起学习了如何评估预测模型。我们介绍了通过检查预测值的合理性、使用回归图和残差图进行可视化分析,以及计算均方误差和R平方等数值指标来评估模型性能。记住,没有单一的“最佳”指标,结合使用多种方法并根据具体场景判断是做出正确决策的关键。

041:模型评估与优化

在本节课中,我们将学习如何评估和优化机器学习模型。模型评估能告诉我们模型在真实世界中的表现。我们将重点介绍如何将数据划分为训练集和测试集,以及如何使用交叉验证来更准确地估计模型的泛化能力。


模型评估简介

模型评估告诉我们模型在真实世界中的表现。在之前的模块中,我们讨论了样本内评估。样本内评估告诉我们模型对已给定的训练数据的拟合程度。它不能估计训练好的模型预测新数据的能力。

解决方案是拆分我们的数据,使用样本内数据(即训练数据)来训练模型。其余的数据称为测试数据,用作样本外数据。这些数据随后被用来近似估计模型在真实世界中的表现。

将数据分离为训练集和测试集是模型评估的重要部分。我们使用测试数据来了解模型在真实世界中的表现。


数据划分:训练集与测试集

当我们拆分数据集时,通常大部分数据用于训练,较小部分用于测试。例如,我们可以使用70%的数据进行训练,然后使用30%的数据进行测试。

我们使用训练集来构建模型并发现预测关系。然后我们使用测试集来评估模型性能。当我们完成模型测试后,应该使用所有数据来重新训练模型。


使用Scikit-learn进行数据划分

Scikit-learn包中一个用于拆分数据集的流行函数是 train_test_split 函数。该函数将数据集随机拆分为训练子集和测试子集。

以下是一个示例代码片段。此方法从 sklearn.model_selection 导入。

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size=0.3, random_state=42)

输入参数 y_data 是目标变量。在汽车评估示例中,它将是价格。X_data 是预测变量列表。在本例中,它是我们用来预测价格的数据集中的所有其他变量。

输出是一个数组:X_trainy_train 是用于训练的子集。X_testy_test 是用于测试的子集。在本例中,test_size 是测试集数据的百分比,这里是30%。random_state 是用于随机数据集拆分的随机种子。


泛化误差

泛化误差是衡量我们的数据在预测先前未见数据时表现如何的指标。我们使用测试数据获得的误差是此误差的近似值。

下图显示了以红色表示的实际值分布与以蓝色表示的线性回归预测值分布的比较。我们看到分布有些相似。如果我们使用测试数据生成相同的图,我们会看到分布相对不同。这种差异是由于泛化误差造成的,它代表了我们在现实世界中看到的情况。


训练数据量与模型性能

使用大量数据进行训练可以为我们提供确定模型在真实世界中表现如何的准确方法,但性能的精度会较低。

让我们用一个例子来澄清这一点。这个靶心图的中心代表正确的泛化误差。假设我们使用90%的数据进行训练,10%的数据进行测试,对数据进行随机抽样。第一次实验时,我们得到了训练数据的良好估计。如果我们再次实验,用不同的样本组合训练模型,我们也会得到一个好结果,但结果将不同于第一次运行实验时的结果。

重复使用不同的训练和测试样本组合进行实验,结果相对接近泛化误差,但彼此不同。重复这个过程,我们得到了泛化误差的良好近似,但精度很差,即所有结果彼此之间差异极大。

如果我们使用较少的数据点来训练模型,并使用更多的数据点来测试模型,泛化性能的准确性会降低,但模型将具有良好的精度。

上图展示了这一点。我们所有的误差估计都相对接近,但它们离真实的泛化性能更远。


交叉验证

为了克服这个问题,我们使用交叉验证。最常见的样本外评估指标之一是交叉验证。

在这种方法中,数据集被分成K个相等的组。每个组被称为一个“折”。例如,四折。一些折可以用作训练集,我们用它来训练模型,其余部分用作测试集,我们用它来测试模型。

例如,我们可以使用三折进行训练,然后使用一折进行测试。这个过程会重复进行,直到每个分区都既用于训练又用于测试。最后,我们使用平均结果作为样本外误差的估计。评估指标取决于模型,例如R平方。


应用交叉验证

应用交叉验证的最简单方法是调用 cross_val_score 函数,该函数执行多次样本外评估。

此方法从Scikit-learn的模型选择包导入。

from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LinearRegression

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/ibm-dtsci-7/img/d79d849ec97d084397afbe8a45e9d208_49.png)

lr = LinearRegression()
scores = cross_val_score(lr, X_data, y_data, cv=3)

我们然后使用函数 cross_val_score。第一个输入参数是我们用于进行交叉验证的模型类型。在这个例子中,我们初始化了一个线性回归模型或对象 lr,我们将其传递给 cross_val_score 函数。其他参数是 X_data(预测变量数据)和 y_data(目标变量数据)。

我们可以通过 cv 参数管理分区的数量。这里 cv=3,意味着数据集被分成三个相等的分区。该函数返回一个分数数组,每个被选为测试集的分区对应一个分数。我们可以使用NumPy中的 mean 函数将结果平均在一起,以估计样本外R平方。


交叉验证过程详解

让我们看一个动画。首先,我们将数据分成三折。我们使用两折进行训练,剩余的一折进行测试。模型将产生一个输出。我们将使用该输出来计算一个分数。在R平方(即决定系数)的情况下,我们将该值存储在一个数组中。

我们将重复这个过程,使用两折进行训练,一折进行测试。保存分数,然后使用不同的组合进行训练,剩余的一折进行测试。我们存储最终结果。cross_val_score 函数返回一个分数值,告诉我们交叉验证的结果。


获取预测值

如果我们想要更多信息呢?如果我们想知道在计算R平方值之前,我们的模型提供的实际预测值呢?

为此,我们使用 cross_val_predict 函数。输入参数与 cross_val_score 函数完全相同,但输出是预测值。让我们说明这个过程。

首先,我们将数据分成三折。我们使用两折进行训练,剩余的一折进行测试。模型将产生一个输出,我们将其存储在一个数组中。

我们将重复这个过程,使用两折进行训练,一折进行测试。模型再次产生一个输出。最后,我们使用最后两折进行训练。然后,我们使用测试数据。这最后的测试折产生一个输出。这些预测存储在一个数组中。


总结

在本节课中,我们一起学习了模型评估与优化的核心概念。我们了解到,为了准确评估模型在真实世界中的表现,必须将数据划分为训练集和测试集。我们介绍了使用Scikit-learn的 train_test_split 函数进行数据划分的方法。

更重要的是,我们探讨了泛化误差的概念,并认识到单一的训练-测试划分可能无法稳定地估计模型性能。因此,我们引入了交叉验证技术,它通过多次划分和平均结果,提供了对模型泛化能力更可靠、更精确的估计。我们学习了如何使用 cross_val_score 函数获取模型的评估分数,以及如何使用 cross_val_predict 函数获取具体的预测值。

掌握这些技术是构建稳健、可靠机器学习模型的关键步骤。

042:过拟合、欠拟合与模型选择 📊

在本节课中,我们将要学习机器学习中的两个核心概念:过拟合欠拟合。我们将探讨如何通过模型选择来找到最佳的模型复杂度,并使用多项式回归作为具体示例进行说明。


概述

上一节我们讨论了多项式回归。本节中,我们将讨论如何选择最佳的多项式阶数,以及选择错误阶数时会引发的问题。

考虑以下函数。我们假设训练数据点来源于一个多项式函数,并加上一些噪声。

公式: Y = f(X) + ε

其中,f(X) 是真实的多项式函数,ε 是噪声项。

模型选择的目标是确定多项式的阶数,以提供对函数 Y = f(X) 的最佳估计。


欠拟合:模型过于简单

如果我们尝试用一个线性函数(一阶多项式)来拟合数据,会发现直线不够复杂,无法很好地拟合数据点。

结果,模型会产生很多误差。这种情况被称为欠拟合,即模型过于简单,无法捕捉数据中的潜在规律。

即使我们增加多项式阶数,如果模型仍然不够灵活,依然会表现出欠拟合。


最佳拟合:找到合适的复杂度

这是一个用八阶多项式拟合数据的例子。我们可以看到,模型在拟合数据和估计函数方面都做得很好,即使在拐点处也是如此。

模型能够较好地追踪数据的整体趋势。


过拟合:模型过于复杂

将阶数增加到十六阶多项式时,模型在追踪训练数据点上表现得极其出色。

然而,它在估计真实函数方面表现很差。这在训练数据稀少的区域尤其明显。估计的函数产生振荡,无法追踪真实函数。这种情况被称为过拟合,即模型过于灵活,以至于拟合了数据中的噪声,而非真实的函数关系。


通过误差分析选择模型

让我们看看不同阶数多项式的训练集和测试集均方误差图。

  • 横轴:多项式的阶数。
  • 纵轴:均方误差。

以下是关键观察结果:

  • 训练误差随着多项式阶数的增加而持续下降。
  • 测试误差是评估多项式泛化能力的更好指标。误差会先下降,直到确定最佳多项式阶数,然后开始上升。

我们选择使测试误差最小的阶数。在这个例子中,最佳阶数是8。

  • 阶数低于8的模型(图左侧)被认为是欠拟合
  • 阶数高于8的模型(图右侧)被认为是过拟合


误差的来源

即使我们选择了最佳的多项式阶数,仍然会存在一些误差。回顾训练点的原始表达式:

公式: Y = f(X) + ε

我们看到一个噪声项 ε。这个项是误差的一个原因。因为噪声是随机的,我们无法预测它。这有时被称为不可约误差

误差还有其他来源,例如:

  1. 模型假设错误:我们的多项式假设可能本身就是错误的。样本点可能来自一个完全不同的函数。例如,在这个图中,数据是由正弦波生成的。多项式函数在拟合正弦波方面做得并不好。
  2. 现实数据的复杂性:对于真实数据,模型可能过于复杂难以拟合,或者我们可能没有正确类型的数据来准确估计函数。

实战:在真实数据上应用

让我们尝试在真实数据(使用“马力”预测价格)上使用不同阶数的多项式。红点代表训练数据,绿点代表测试数据。

以下是不同阶数模型的拟合效果:

  • 仅使用数据均值:模型表现不佳,是严重欠拟合。
  • 线性函数(一阶):能更好地拟合数据。
  • 二阶模型:与线性函数看起来相似。
  • 三阶函数:与前两阶类似,预测价格随马力增加而上升。
  • 四阶多项式:在大约200马力时,预测价格突然下降。这看起来是错误的,可能是过拟合的迹象。


使用R平方进行评估

让我们使用R平方来验证我们的假设。以下是R平方值随多项式阶数变化的图。横轴代表多项式模型的阶数。R平方越接近1,模型越准确。

我们可以看到,当多项式阶数为3时,R平方值最优。当阶数增加到4时,R平方值急剧下降,这验证了我们最初的假设:四阶模型出现了过拟合。


代码实现:计算不同阶数的R平方

以下是计算不同多项式阶数对应R平方值的Python代码示例:

# 1. 创建一个空列表来存储R平方值
rsqu_test = []

# 2. 创建一个包含不同多项式阶数的列表
order = [1, 2, 3, 4]

# 3. 使用循环遍历阶数列表
for n in order:
    # 4. 创建多项式特征对象,指定阶数
    pr = PolynomialFeatures(degree=n)

    # 5. 使用fit_transform方法将训练和测试数据转换为多项式特征
    x_train_pr = pr.fit_transform(x_train[['horsepower']])
    x_test_pr = pr.fit_transform(x_test[['horsepower']])

    # 6. 使用转换后的数据拟合线性回归模型
    lr.fit(x_train_pr, y_train)

    # 7. 使用测试数据计算R平方,并存储到列表中
    rsqu_test.append(lr.score(x_test_pr, y_test))

# 现在 rsqu_test 列表中包含了各阶模型在测试集上的R平方值


总结

本节课中,我们一起学习了:

  1. 欠拟合:模型过于简单,无法捕捉数据模式,表现为高偏差。
  2. 过拟合:模型过于复杂,过度拟合训练数据中的噪声,表现为高方差,泛化能力差。
  3. 模型选择:通过分析测试集误差(或R平方等指标)来找到最佳模型复杂度,平衡欠拟合和过拟合。
  4. 误差来源:包括不可约的随机噪声、错误的模型假设以及数据本身的局限性。
  5. 实践方法:使用PolynomialFeatures和交叉验证等技术来系统性地评估不同复杂度的模型。

理解并处理好过拟合与欠拟合,是构建有效、可靠机器学习模型的关键一步。

043:过拟合、欠拟合与模型选择 📊

在本节课中,我们将学习机器学习中两个核心概念:过拟合欠拟合。我们将探讨如何为多项式回归模型选择合适的阶数,并理解错误选择模型复杂度所带来的问题。

上一模块我们讨论了多项式回归。本节中,我们将看看如何选取最佳的多项式阶数,以及选择错误阶数时会出现的问题。

模型选择的目标 🎯

考虑以下函数。我们假设训练数据点来源于一个多项式函数,并附加了一些噪声。

y = f(x) + ε

其中,ε 代表噪声项。

模型选择的目标是确定多项式的阶数,以提供对函数 Y(X) 的最佳估计。

理解欠拟合 🤔

如果我们尝试用线性函数(一阶多项式)来拟合数据,会发现直线不够复杂,无法很好地拟合数据点。

结果会产生许多误差。这种情况被称为欠拟合,即模型过于简单,无法捕捉数据中的潜在规律。

当我们增加多项式阶数时,模型拟合效果会变好,但如果阶数仍然不足,模型依然不够灵活,会表现出欠拟合。

寻找合适拟合 ✅

这是一个用八阶多项式拟合数据的例子。我们可以看到,模型在拟合数据和估计函数方面表现良好,即使在拐点处也是如此。

理解过拟合 😰

将阶数增加到十六阶,模型在追踪训练数据点上做得极好。

但在估计真实函数时表现很差。这在训练数据稀少的区域尤其明显。估计的函数产生振荡,并未追踪真实函数。这种情况被称为过拟合,即模型过于灵活,拟合了噪声而非真实的函数关系。

误差分析图表 📉

让我们看一下不同阶数多项式的训练集和测试集均方误差(MSE)图。

  • 横轴:多项式阶数。
  • 纵轴:均方误差。

以下是图表的关键观察结果:

  • 训练误差随着多项式阶数的增加而持续下降。
  • 测试误差是评估多项式泛化能力的更好指标。误差会先下降,直到确定最佳多项式阶数,然后开始上升。
  • 我们选择使测试误差最小的阶数。在本例中,最佳阶数是8。
  • 最佳阶数左侧的模型被认为是欠拟合
  • 最佳阶数右侧的模型被认为是过拟合

误差的来源 ⚙️

即使我们选择了最佳多项式阶数,仍然会存在一些误差。回顾训练点的原始表达式 y = f(x) + ε,我们看到一个噪声项 ε。这是误差的一个原因,因为噪声是随机的,无法预测。这有时被称为不可约误差

还存在其他误差来源:

  1. 模型假设错误:我们的多项式假设可能本身就是错的。样本点可能来自完全不同的函数。例如,在此图中,数据由正弦波生成,多项式函数无法很好地拟合正弦波。
  2. 现实数据的复杂性:对于真实数据,模型可能难以拟合,或者我们可能没有正确类型的数据来准确估计函数。

在真实数据上实践 🚗

让我们尝试在真实数据(汽车马力)上使用不同阶数的多项式。红点代表训练数据,绿点代表测试数据。

以下是不同阶数模型的拟合情况:

  • 仅使用数据均值:模型表现不佳。
  • 线性函数(一阶):能更好地拟合数据。
  • 二阶模型:与线性函数看起来相似。
  • 三阶函数:也与前两者趋势类似,呈增长态势。
  • 四阶多项式:在大约200马力时,预测价格突然下降。这看起来是错误的。

使用R平方进行评估 📐

让我们使用R平方来验证我们的假设。以下是R平方值随多项式阶数变化的图。横轴代表多项式模型的阶数。R平方越接近1,模型越准确。

我们可以看到,当多项式阶数为3时,R平方值最优。当阶数增加到4时,R平方值急剧下降,这验证了我们最初的假设——四阶模型可能过拟合了。

计算R平方的代码示例 💻

我们可以通过以下代码计算不同阶数模型的R平方值:

首先,创建一个空列表来存储R平方值,并创建一个包含不同多项式阶数的列表。

rsqu_test = []
order = [1, 2, 3, 4]

然后,使用循环遍历阶数列表。

for n in order:
    # 创建多项式特征对象
    pr = PolynomialFeatures(degree=n)
    
    # 将训练和测试数据转换为多项式特征
    x_train_pr = pr.fit_transform(x_train[['horsepower']])
    x_test_pr = pr.fit_transform(x_test[['horsepower']])
    
    # 使用转换后的数据拟合线性回归模型
    lr.fit(x_train_pr, y_train)
    
    # 计算测试集上的R平方并存储
    rsqu_test.append(lr.score(x_test_pr, y_test))

这段代码演示了如何系统化地评估不同复杂度模型的性能。

总结 📚

本节课我们一起学习了机器学习中的关键概念:

  1. 欠拟合:模型过于简单,无法捕捉数据中的基本模式,表现为高偏差。
  2. 过拟合:模型过于复杂,过度拟合训练数据中的噪声,表现为高方差,泛化能力差。
  3. 模型选择:目标是找到偏差和方差之间的最佳平衡点。我们使用测试误差或像R平方这样的指标来选择最佳模型复杂度(例如多项式的最佳阶数)。
  4. 误差来源:总误差可能来自不可约的噪声、错误的模型假设或数据本身的局限性。

理解这些概念对于构建有效、可泛化的机器学习模型至关重要。

044:岭回归 🏔️

在本节课中,我们将要学习一种称为岭回归的线性回归技术。岭回归的主要目标是防止模型在训练数据上过拟合,从而提高模型在未知数据上的泛化能力。

概述:什么是过拟合?🤔

上一节我们介绍了多项式回归。虽然多项式回归在可视化中很有用,但当存在多个自变量或特征时,过拟合是一个大问题。

考虑一个由橙色线表示的四阶多项式函数。蓝色数据点是从这个函数生成的。

我们可以用一个十阶多项式来拟合这些数据。蓝色估计函数在逼近真实函数方面做得很好。

然而,现实数据中常常存在异常值。例如,下图中的这个点似乎并非来自橙色函数。

如果我们仍然使用十阶多项式函数来拟合包含异常值的数据,蓝色估计函数就会变得不准确,并且不再是橙色实际函数的一个良好估计。

如果我们检查估计函数的表达式,会发现估计出的多项式系数具有非常大的幅度,这在更高阶的多项式中尤其明显。

岭回归的原理 ⚙️

岭回归通过引入一个参数 alpha 来控制这些多项式系数的大小,从而防止过拟合。

Alpha 是我们在拟合或训练模型之前选择的一个参数。它的作用是向线性回归的成本函数中添加一个惩罚项,公式如下:

成本函数 = 残差平方和 + alpha * (系数平方和)

这个惩罚项会迫使模型学习到的系数值变小。

Alpha 参数的影响 📊

不同的 alpha 值会如何改变模型呢?以下表格展示了不同 alpha 值对应的多项式系数。

随着 alpha 值的增加,模型参数(特别是高阶多项式特征的系数)会变小。但 alpha 必须谨慎选择。

以下是不同 alpha 值下模型拟合效果的直观展示:

  • Alpha = 0:等同于普通最小二乘回归,过拟合现象明显。
  • Alpha = 0.001:过拟合开始减弱。
  • Alpha = 0.01:估计函数能较好地跟踪实际函数。
  • Alpha = 1:出现欠拟合的初步迹象,模型灵活性不足。
  • Alpha = 10:出现极端欠拟合,模型甚至无法跟踪两个数据点。

如何选择 Alpha?🎯

为了选择最佳的 alpha 值,我们使用交叉验证技术。

在 Python 的 scikit-learn 库中,使用岭回归的步骤如下:

  1. sklearn.linear_model 导入 Ridge
  2. 使用构造函数创建一个岭回归对象,并将 alpha 作为参数传入。
    from sklearn.linear_model import Ridge
    ridge_model = Ridge(alpha=1.0)
    
  3. 使用 fit 方法训练模型。
  4. 使用 predict 方法进行预测。

为了确定参数 alpha,我们将数据分为训练集和验证集。验证集类似于测试集,但专门用于选择像 alpha 这样的超参数。

以下是选择 alpha 的流程:

  1. 从一个较小的 alpha 值开始。
  2. 用训练数据训练模型。
  3. 用验证数据进行预测。
  4. 计算 R 平方分数并存储该值。
  5. 重复以上步骤,逐渐增大 alpha 值。
  6. 选择能使验证集上 R 平方分数最大化的 alpha 值。

注意:除了 R 平方,我们也可以使用其他指标(如均方误差)来选择 alpha 值。

实际案例:二手车数据集 🚗

当我们拥有大量特征时,过拟合问题会更严重。下图展示了在一个二手车数据集上,使用多个特征和二阶多项式函数时,不同 alpha 值对应的 R 平方分数变化。

纵轴是 R 平方分数,横轴是 alpha 值。红色曲线代表训练数据,蓝色曲线代表验证数据。

我们可以看到,随着 alpha 值增加,验证集上的 R 平方分数增加并最终收敛在约 0.75。在这种情况下,我们选择使验证集分数最高的 alpha 值。

相反,随着 alpha 增加,训练集上的 R 平方分数会下降。这是因为 alpha 项防止了过拟合,虽然这可能提升模型在未知数据上的表现,但会导致模型在训练数据上的性能变差。

总结 📝

本节课中我们一起学习了岭回归。我们了解到:

  1. 岭回归通过在成本函数中添加惩罚项(L2正则化)来防止模型过拟合。
  2. 关键参数 alpha 控制着惩罚的强度:alpha 太小可能导致过拟合,太大则可能导致欠拟合。
  3. 最佳 alpha 值需要通过交叉验证在验证集上进行选择。
  4. 在 scikit-learn 中,可以方便地使用 Ridge 类来实现岭回归。

通过合理应用岭回归,我们可以构建出泛化能力更强、更稳健的预测模型。

045:网格搜索 🔍

在本节课中,我们将学习一种强大的机器学习工具——网格搜索。网格搜索允许我们通过几行代码,系统地扫描和评估多个超参数的不同取值,从而帮助我们找到模型的最佳配置。


什么是网格搜索? 🤔

网格搜索使我们能够用少量代码扫描多个自由参数。

像上一节视频中讨论的 alpha 项这样的参数,并不属于模型的拟合或训练过程本身。这些值被称为超参数

Scikit-learn 提供了一种方法,可以自动使用交叉验证来迭代这些超参数。这种方法就叫做网格搜索


网格搜索的工作原理 ⚙️

上一节我们介绍了超参数的概念,本节中我们来看看网格搜索是如何工作的。

网格搜索接收你想要训练的模型(或对象)以及超参数的不同取值。然后,它会计算不同超参数取值下的均方误差或 R 平方值,从而让你选择最佳值。

让我们用小圆圈代表不同的超参数取值。我们从一个超参数值开始训练模型,然后使用不同的超参数值再次训练模型。我们持续这个过程,直到穷尽所有不同的自由参数值。每个模型都会产生一个误差。我们选择那个能最小化误差的超参数。


数据集划分与验证 📊

为了进行有效的网格搜索,我们需要将数据集分为三个部分:训练集验证集测试集

以下是网格搜索在数据集上的工作流程:

  1. 我们为不同的超参数值训练模型。
  2. 我们使用验证集计算每个模型的 R 平方值或均方误差。
  3. 我们选择在验证集上能最小化均方误差或最大化 R 平方值的超参数。
  4. 最后,我们使用测试数据来评估模型的最终性能。


在Scikit-learn中识别超参数 🔍

这是 Scikit-learn 的网页,其中给出了对象构造函数的参数。需要注意的是,对象的属性也被称为参数。在本模块中,我们不会严格区分,尽管有些选项本身可能不被视为超参数。我们将重点关注超参数 alpha 和归一化参数。


定义参数网格 📋

网格搜索的核心是一个包含 Python 字典的 Python 列表。

以下是定义参数网格的要点:

  • 字典的键是自由参数的名称。
  • 字典的值是该自由参数的不同取值。

这可以看作是一个包含各种自由参数取值的表格。我们还需要指定模型对象。


创建网格搜索对象 🛠️

网格搜索对象需要指定评分方法(本例中是 R 平方)、交叉验证的折数、模型对象以及自由参数的取值。

一些输出包括不同自由参数值对应的不同分数(本例中是 R 平方),以及具有最佳分数的自由参数值。


实践:单参数网格搜索 💻

首先,我们导入所需的库,包括 GridSearchCV 和参数字典。

from sklearn.linear_model import Ridge
from sklearn.model_selection import GridSearchCV
import pandas as pd

我们创建一个岭回归对象(模型)。然后创建一个 GridSearchCV 对象。输入包括岭回归对象、参数值和交叉验证折数。我们将使用 R 平方作为评分方法(这是默认方法)。接着拟合这个对象。

# 创建模型
ridge = Ridge()
# 定义参数网格
parameters = {'alpha': [1, 10, 100]}
# 创建GridSearchCV对象
grid1 = GridSearchCV(ridge, parameters, cv=10)
# 拟合模型
grid1.fit(X_train, y_train)

我们可以使用 best_estimator_ 属性找到自由参数的最佳值。

best_model = grid1.best_estimator_

我们还可以使用 cv_results_ 属性获取诸如验证数据上的平均分数等信息。

results = grid1.cv_results_

实践:多参数网格搜索 🔄

网格搜索的一个优势是能够快速测试多个参数。

例如,岭回归有一个选项可以归一化数据(如何标准化请参见模块4)。参数字典的第一个元素是 alpha 项,第二个元素是 normalize 选项。键是参数的名称,值是不同的选项。在本例中,因为我们可以选择是否归一化数据,所以值分别是 TrueFalse

这个字典是一个包含两个不同取值的表格或网格。和之前一样,我们需要岭回归对象(模型)。过程是相似的,只是我们有了一个包含不同参数值的表格或网格。输出是所有不同参数值组合的分数。

代码也是类似的。字典包含了不同的自由参数值。我们可以找到自由参数的最佳值。不同自由参数的结果分数存储在这个字典 grid1.cv_results_ 中。

# 定义包含两个参数的网格
parameters = {'alpha': [0.001, 0.1, 1, 10, 100],
              'normalize': [True, False]}
# 创建并拟合网格搜索
grid1 = GridSearchCV(ridge, parameters, cv=10)
grid1.fit(X_train, y_train)
# 打印最佳参数
print(grid1.best_params_)

我们可以打印出不同自由参数值的分数。参数值的存储方式如下所示。更多示例请参见课程实验部分。


总结 📝

本节课中我们一起学习了网格搜索。我们了解到网格搜索是一种自动化超参数调优的强大工具,它通过系统性地遍历预定义的参数组合,并利用交叉验证进行评估,来帮助我们找到模型的最佳配置。我们学习了如何定义参数网格、创建 GridSearchCV 对象、进行单参数及多参数搜索,并获取最佳模型和评估结果。掌握网格搜索能显著提高我们构建高效机器学习模型的效率。

046:岭回归 🏔️

在本节课中,我们将要学习一种名为岭回归的线性回归技术。岭回归的核心目标是防止模型在训练过程中出现过拟合现象,从而提高模型在未知数据上的泛化能力。

上一节我们介绍了多项式回归及其可视化。本节中我们来看看当模型存在多个自变量或特征时,过拟合会成为一个显著问题。

过拟合问题与岭回归的引入

考虑一个由橙色曲线表示的四阶多项式函数。蓝色数据点由该函数生成。

我们可以使用一个十阶多项式来拟合这些数据。此时,蓝色估计函数能很好地近似真实的橙色函数。

然而,现实数据常包含异常值。例如,下图中的某个点似乎并非来自橙色函数。

如果我们使用十阶多项式函数来拟合包含此异常点的数据,得到的蓝色估计函数将变得不准确,无法良好估计真实的橙色函数。

检查估计函数的表达式,会发现估计出的多项式系数具有非常大的幅值,对于高阶项尤为明显。

岭回归通过引入参数 alpha 来控制这些多项式系数的大小。

参数 Alpha 的作用与选择

Alpha 是我们在拟合或训练模型之前需要选择的一个参数。

以下表格展示了 alpha 值递增时的情况。每一行代表一个递增的 alpha 值。

让我们看看不同的 alpha 值如何改变模型。此表展示了不同 alpha 值对应的多项式系数。列对应不同的多项式系数,行对应不同的 alpha 值。

随着 alpha 增大,参数值变小。这对高阶多项式特征最为明显。但必须谨慎选择 alpha 值。

以下是不同 alpha 值对模型拟合效果的影响:

  • 如果 alpha 过大,系数将趋近于 0,导致模型欠拟合数据。
  • 如果 alpha 为 0,则等同于普通最小二乘法,过拟合现象明显。
  • 当 alpha 等于 0.001 时,过拟合开始减弱。
  • 当 alpha 等于 0.01 时,估计函数能较好地跟踪实际函数。
  • 当 alpha 等于 1 时,我们看到了欠拟合的初步迹象,估计函数灵活性不足。
  • 当 alpha 等于 10 时,出现极端欠拟合,模型甚至无法跟踪那两个数据点。

使用交叉验证选择 Alpha

为了选择最佳的 alpha,我们使用交叉验证技术。

以下是使用 Python 的 scikit-learn 库进行岭回归预测的基本步骤:

  1. sklearn.linear_model 导入 Ridge
  2. 使用构造函数创建一个岭回归对象,其中参数 alpha 是构造函数的参数之一。
  3. 使用 fit 方法训练模型。
  4. 使用 predict 方法进行预测。

为了确定参数 alpha,我们使用一部分数据(训练集)进行训练,并使用另一个称为验证集的数据集来评估不同 alpha 值的效果。验证集类似于测试集,但专门用于选择像 alpha 这样的超参数。

选择 alpha 的基本流程如下:

  1. 从一个较小的 alpha 值开始。
  2. 训练模型。
  3. 使用验证数据进行预测。
  4. 计算 R 平方分数并存储该值。
  5. 对一个更大的 alpha 值重复此过程:再次训练模型,使用验证数据预测,计算并存储 R 平方值。
  6. 为不同的 alpha 值重复此过程,训练模型并进行预测。
  7. 选择能够最大化 R 平方值的 alpha

注意,我们也可以使用其他指标(如均方误差)来选择 alpha 值。

实际案例:二手车数据集

如果我们拥有大量特征,过拟合问题会更加严重。

下图展示了在二手车数据集上应用二阶多项式函数时的情况。纵轴表示不同的 R 平方值,横轴表示不同的 alpha 值。

图中红色曲线代表训练数据上的 R 平方,蓝色曲线代表验证数据上的 R 平方。

我们可以看到,随着 alpha 值增大,验证集上的 R 平方值增加,并在大约 0.75 处收敛。在这种情况下,我们选择最大的 alpha 值,因为对更高的 alpha 值进行实验影响甚微。

相反,随着 alpha 增加,测试数据上的 R 平方值会下降。这是因为 alpha 项起到了防止过拟合的作用,这可能会提升模型在未见数据上的表现,但模型在测试数据上的性能会变差。具体如何生成此图,请参阅相关实验部分。

总结

本节课中我们一起学习了岭回归。我们了解到,岭回归通过在损失函数中增加一个惩罚项(由参数 alpha 控制)来限制模型系数的大小,从而有效缓解过拟合问题。我们探讨了 alpha 值对模型拟合效果(从过拟合到欠拟合)的影响,并学习了如何使用交叉验证验证集来选择最优的 alpha 值,以提升模型的泛化能力。

047:网格搜索 🔍

在本节课中,我们将要学习一种强大的机器学习工具——网格搜索。网格搜索允许我们通过少量代码,系统地扫描多个超参数,从而找到模型的最佳配置。我们将了解什么是超参数,以及如何使用Scikit-learn库中的GridSearchCV来自动化这一过程。


什么是网格搜索?🤔

上一节我们介绍了模型训练中的参数概念。本节中我们来看看另一类参数——超参数。

像上一视频中讨论的alpha项这样的参数,并不属于模型的拟合或训练过程。这些值被称为超参数

Scikit-learn提供了一种使用交叉验证自动迭代这些超参数的方法,这种方法就叫做网格搜索

网格搜索接收你想要训练的模型对象以及超参数的不同取值。然后,它会计算不同超参数组合下的均方误差或R平方值,从而让你选择最佳值。


网格搜索的工作原理 ⚙️

我们可以将不同的超参数值想象成许多小圆圈。以下是网格搜索的基本步骤:

  1. 我们从一个超参数值开始训练模型。
  2. 使用不同的超参数值再次训练模型。
  3. 重复此过程,直到穷尽所有不同的自由参数值。
  4. 每个模型都会产生一个误差。
  5. 我们选择那个能最小化误差的超参数组合。

为了客观评估,我们需要将数据集分为三部分:训练集验证集测试集

以下是具体流程:

  • 我们为不同的超参数组合训练模型。
  • 使用验证集计算每个模型的R平方或均方误差。
  • 选择在验证集上能最小化均方误差或最大化R平方的超参数。
  • 最后,使用测试数据来评估我们最终模型的性能。

在Scikit-learn中定义参数网格 📊

在Scikit-learn的官方文档中,对象构造函数的参数都被列出。需要注意的是,对象的属性也被称为参数。在本模块中,我们不会严格区分,尽管有些选项本身可能不被视为超参数。我们将重点关注超参数alpha和归一化参数normalize

网格搜索的核心是一个Python列表,其中包含一个或多个Python字典。

  • 是自由参数的名称。
  • 是该自由参数的不同取值列表。

这可以看作是一个包含各种自由参数值的表格。我们还需要模型对象本身。

网格搜索需要指定评分方法(本例中为R平方)、交叉验证的折数、模型对象以及自由参数值网格。

其输出包括不同自由参数值的分数,以及具有最佳分数的自由参数值。


实践:单参数网格搜索 💻

首先,我们导入所需的库,包括GridSearchCV和参数字典。

from sklearn.linear_model import Ridge
from sklearn.model_selection import GridSearchCV

我们创建一个Ridge回归对象(模型),然后创建一个GridSearchCV对象。输入包括Ridge回归对象、参数字典和交叉验证折数。我们将使用R平方作为评分方法(这是默认设置)。接着拟合这个对象。

ridge = Ridge()
parameters = {'alpha': [1, 10, 100]}
grid1 = GridSearchCV(ridge, parameters, cv=4)
grid1.fit(X_train, y_train)

我们可以使用best_estimator_属性找到自由参数的最佳值。

best_model = grid1.best_estimator_

我们也可以使用cv_results_属性获取诸如验证数据上的平均分数等信息。

results = grid1.cv_results_


实践:多参数网格搜索 🧩

网格搜索的一个优势是能快速测试多个参数的组合。

例如,Ridge回归有一个选项可以归一化数据。参数alpha是字典中的第一个元素,第二个元素是normalize选项。键是参数名,值是该参数的不同选项。在本例中,因为我们可以选择是否归一化数据,所以值分别是TrueFalse

这个字典就是一个包含两个不同参数取值的表格或网格。和之前一样,我们需要Ridge回归对象。

流程是相似的,只是我们有一个包含不同参数值的表格。输出是所有不同参数组合的分数。

代码也类似。字典包含了不同的自由参数值。

parameters2 = {'alpha': [1, 10, 100], 'normalize': [True, False]}
grid2 = GridSearchCV(ridge, parameters2, cv=4)
grid2.fit(X_train, y_train)

我们可以找到自由参数的最佳值。不同自由参数的结果分数存储在这个字典中:grid2.cv_results_

我们可以打印出不同自由参数值的分数。参数值的存储方式如图所示。更多示例请参阅课程实验部分。


总结 📝

本节课中我们一起学习了网格搜索。我们了解到网格搜索是一种自动化超参数调优的强大工具,它通过系统性地尝试超参数的不同组合,并利用交叉验证进行评估,来帮助我们找到模型的最佳配置。我们掌握了如何使用Scikit-learn的GridSearchCV来实现单参数和多参数的搜索,并理解了如何解读其结果以选择最优模型。

posted @ 2026-03-26 08:53  布客飞龙II  阅读(2)  评论(0)    收藏  举报