news 2026/9/13 3:20:28

Data-Science-For-Beginners 第 15 课:数据科学生命周期中的探索性数据分析(EDA)实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Data-Science-For-Beginners 第 15 课:数据科学生命周期中的探索性数据分析(EDA)实战

Data-Science-For-Beginners 第 15 课:数据科学生命周期中的探索性数据分析(EDA)实战

【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners

导读

在数据科学生命周期中,"分析(Analyzing)"阶段承担着一项关键职责:验证数据能否回答业务方提出的问题、能否解决特定的问题,并确认模型是否在正确地回应这些问题。本文以 Data-Science-For-Beginners 课程第 15 课《The Data Science Lifecycle: Analyzing》为骨架,结合仓库中真实的 notebook.ipynb 与邮件、出租车两份数据集,系统讲解探索性数据分析(Exploratory Data Analysis, EDA)的四大核心技法:数据剖面与描述性统计、抽样与查询、可视化探索、缺失值探查。读完本文,你将掌握用 Python + Pandas 对任意数据集完成"认识数据—发现问题—为建模做准备"的完整 EDA 工作流,并能独立完成本课附带的纽约出租车小费季节性问题分析作业。


一、为什么需要"分析"阶段:EDA 的定位与三大核心问题

在生命周期的捕获(Capture)阶段,团队完成了数据获取并明确了待解决的业务问题,但一个根本疑问尚未解答:我们怎么知道这些数据真的能支撑最终的结果?数据科学家在获得数据时,通常需要向自己提出三个问题(见 原文课程文档):

  1. 数据量是否足够:我有足够的数据来解决这个问题吗?
  2. 数据质量是否合格:这些数据对本问题而言,质量可以接受吗?
  3. 目标是否需要调整:如果通过这些数据发现了额外信息,我们是否应该考虑改变或重新定义目标?

**探索性数据分析(EDA)**正是"认识数据"的过程:它既能回答上述三个问题,也能提前暴露与该数据集打交道时可能遇到的挑战。EDA 的产出不是最终模型,而是对数据特征(features)与数据内部关系(relationships)的定义——这正是为后续建模阶段做准备的直接输入。

本课使用一份来自 Kaggle 的垃圾邮件分类数据集(data/emails.csv)演示全部技法。该数据集统计了邮件中若干常见英文单词的出现次数,邮件来源匿名,共 406 条记录、17 列(1 列邮件编号 + 16 列词频),典型行如下:

Email No.,the,to,ect,and,for,of,a,you,in,on,is,this,i,be,that,will Email 1,0,0,1,0,0,0,2,0,0,0,1,0,2,0,0,0 Email 2,8,13,24,6,6,2,102,1,18,21,13,0,61,4,2,0

二、数据剖面(Data Profiling)与描述性统计:describe()

数据剖面(Data Profiling)通过描述性统计技术,汇总并收集关于数据集的整体信息。两者的分工是:

  • 数据剖面帮助我们理解"有什么可用"(数据集包含哪些列、什么类型、什么范围);
  • 描述性统计帮助我们理解"有多少可用"(每条特征的计数、均值、分布形态)。

Pandas 中最常用的入口是DataFrame.describe(),它一次性输出数值列的计数(count)、最大值、最小值、均值(mean)、标准差(std)以及 25%/50%/75% 分位数。课程 notebook(4-Data-Science-Lifecycle/15-analyzing/notebook.ipynb)中对邮件数据实际运行的结果如下:

import pandas as pd # 加载邮件数据集 path = '../../data/emails.csv' email_df = pd.read_csv(path) # 对全部数值列做描述性统计 print(email_df.describe())
the to ect and for of count 406.000000 406.00000 406.00000 406.000000 406.000000 406.000000 mean 7.022167 6.51970 4.94828 3.059113 3.502463 2.662562 std 10.945522 9.80191 9.29382 6.267806 4.901372 5.443939 min 0.000000 0.00000 1.00000 0.000000 0.000000 0.000000 25% 1.000000 1.00000 1.00000 0.000000 1.000000 0.000000 50% 3.000000 3.00000 2.00000 1.000000 2.000000 1.000000 75% 9.000000 7.75000 4.00000 3.000000 4.750000 3.000000 max 99.000000 88.00000 79.00000 69.000000 39.000000 57.000000

从这一输出可以快速读出关键信息:

  • count 全部为 406:说明该数据集的数值列没有空值,数据完整性良好;
  • 均值与标准差差距悬殊(如the列 mean≈7.0、std≈10.9),配合 max 高达 99,可初步判断多数词频呈右偏分布——少量垃圾邮件包含极高频词汇;
  • 某些列如ai的均值(57.0、47.2)远高于其他单词,说明这些词是区分邮件内容的强特征候选。

利用describe()这类描述性统计,你可以量化地评估"已经拥有多少数据、是否还需要更多"——这是回答第一个 EDA 问题的直接手段。


三、抽样(Sampling)与查询(Querying)

3.1 抽样:sample()快速理解全貌

在大数据集上逐一探索每一行非常耗时,这类任务通常交给计算机处理;而抽样(Sampling)是帮助人类快速建立认知的实用工具。通过抽取样本,你可以运用概率与统计知识,对整体数据得出一般性结论。需要注意:

  • 关于"抽样多少"没有硬性规定,但样本量越大,对总体的概括(generalization)就越精确
  • 抽样应与业务背景结合,例如按月份、地区等维度分层抽样往往比纯随机抽样更具代表性。

Pandas 提供DataFrame.sample()方法,通过参数指定期望的随机样本条数。课程 notebook 中抽取 10 封邮件的实际输出:

# 随机抽样 10 封邮件 print(email_df.sample(10))
Email No. the to ect and for of a you in on is this i 150 Email 151 0 1 2 0 3 0 15 0 0 5 0 0 7 380 Email 5147 0 3 2 0 0 0 7 0 1 1 0 0 3 19 Email 20 3 4 11 0 4 2 32 1 1 3 9 5 25 ... 320 Email 321 10 12 4 6 8 6 187 5 26 28 23 2 171 be that will 150 1 0 0 380 0 0 0 19 3 0 1 ... 320 5 1 1

样本直观展示了数据的多样性:既有Email 151这样词频普遍较低的邮件,也有Email 321这样高频词大量集中(a出现 187 次、i出现 171 次)的极端样本——这为后续判断"什么样的邮件更像垃圾邮件"提供了直觉依据。

3.2 查询:query()精确聚焦

与抽样"看整体"不同,查询(Querying)让你对数据拥有控制权,能精确聚焦到自己有疑问的特定部分。Pandas 的DataFrame.query()接受一段布尔表达式,返回满足条件的行。课程 notebook 中的示例是"找出to出现次数多于the的邮件":

# 返回 "to" 出现次数多于 "the" 的行 print(email_df.query('the < to'))
[169 rows x 17 columns]

该查询从 406 行中筛选出 169 行,一条语句即完成了条件过滤。query()的典型使用技巧包括:

  • 多条件组合:email_df.query('the > 5 and to > 10')
  • 使用列名直接比较,无需重复写df['列名'],代码更简洁可读;
  • 支持innot in==!=<>&|等运算符。

在实践中,建议把"抽样(快速直觉)"与"查询(定向验证假设)"组合使用:先用sample()建立整体印象,再针对具体假设用query()精确验证。


四、探索阶段就该开始的可视化

一个常见误区是"等数据完全清洗、分析完毕后再画图"。实际上,在探索阶段就建立可视化能带来三重收益:

  1. 发现模式与关系:散点图、直方图、箱线图能直观暴露变量间的相关性与分布形态;
  2. 暴露数据问题:异常点、长尾分布、缺失值区域往往一眼可见;
  3. 跨角色沟通:可视化是与不参与数据管理的业务方沟通的媒介,也是澄清捕获阶段未覆盖问题的机会——例如向客户展示"词频分布严重右偏"比口头描述更有说服力。

课程在探索阶段主动将读者引导至 3-Data-Visualization 章节,那里系统覆盖了数量(quantities)、分布(distributions)、比例(proportions)、关系(relationships)四大类可视化,包括直方图、箱线图、饼图、散点图等常用图表;第 13 课还专门讨论了如何做出"有意义、不误导"的可视化。在 EDA 阶段,推荐从以下三类图入手:

想探索的问题推荐图表对应课程
单个特征的分布形态直方图、箱线图10-visualization-distributions
特征之间的相关性散点图、散点矩阵12-visualization-relationships
分类特征的占比饼图、堆积柱状图11-visualization-proportions

五、探索不一致性:缺失值探查isna()/isnull()

以上所有技术(剖面、抽样、查询、可视化)都能帮助发现缺失值或不一致值,而 Pandas 还专门提供了检查函数:

  • isna()isnull()功能等价,均返回一个与原 DataFrame 形状相同的布尔矩阵,标记每个位置是否为缺失值;
  • 配合sum()可按列统计缺失数量:email_df.isnull().sum()
  • 配合any()可快速定位含缺失值的列。

例如,在邮件数据上运行email_df.isna().sum()会得到全 0 的结果(与describe()中 count 全为 406 相互印证);而对 data/taxi.csv 这类真实出租车记录做同样检查,则可能发现tip_amount中存在大量 0(对应payment_type为现金支付等场景)。

课程特别强调了一个重要观点:探查缺失值的重点在于"研究它们最初为何变成这样"。缺失值往往不是随机出现的,其背后可能隐藏着采集逻辑、业务规则或数据源问题——理解成因后才能正确决定处理方式(删除、填充、标记等)。关于缺失值处理的完整行动方案,课程链接到了 2-Working-With-Data/08-data-preparation/notebook.ipynb,那里系统讲解了数据准备阶段的清洗、去重、类型转换与缺失值处理策略。


六、实战作业:用 EDA 回答"纽约出租车小费是否存在季节性"

本课作业(assignment.md)是前一课(14-Introduction/assignment.md)的延续。在前一课(捕获阶段),团队只对数据做了初步评估;现在团队进入分析阶段,要对数据做深度 EDA。

6.1 业务问题与数据

客户想知道的核心问题是:纽约市的黄色出租车乘客,冬天给司机的小费更多,还是夏天更多?

团队获得了一个包含200 笔交易的数据集(data/taxi.csv,来自纽约市出租车与轿车委员会 TLC,样本取自 2019 年 1 月与 7 月各 100 笔),共 18 列。可从 assignment.ipynb 起步(其中已包含!pip install pandaspd.read_csv加载代码),关键列包括:

列名含义
tpep_pickup_datetime/tpep_dropoff_datetime上下车时间(可用于提取月份/季节)
passenger_count乘客人数
trip_distance行程距离(英里)
payment_type支付方式(1=信用卡、2=现金等)
fare_amount车费金额
tip_amount小费金额
tolls_amount过路费
total_amount总金额(含各项附加费)
congestion_surcharge拥堵附加费(2019 年起部分区域征收)

更完整的字段说明可参考数据字典(data dictionary)与用户指南(user guide)文档。

6.2 三个必答问题

在 notebook 中(可自行添加单元格)运用本课所学技术完成 EDA,并回答:

  1. 数据中还有哪些因素可能影响小费金额?建议方向:用describe()观察tip_amountfare_amounttrip_distance的分布;用query()对比payment_type不同取值下tip_amount的差异;用sample()抽查极端小费记录;还可按tpep_pickup_datetime提取小时、星期等维度,考察时段对打赏行为的影响。

  2. 哪些列很可能对回答客户问题没有帮助?例如VendorID(出租车供应商编号)、store_and_fwd_flag(存储转发标志)、RatecodeID等与"季节性打赏"业务目标关联较弱的元数据列;论证时应说明理由,而不是简单罗列。

  3. 基于目前提供的数据,是否能看到季节性打赏行为的证据?关键在于按月份分组对比:例如用query()或布尔索引分离 1 月(冬季)与 7 月(夏季)的记录,再分别统计tip_amount的均值/中位数;同时注意区分"小费金额"与"小费比例"(tip_amount / fare_amount),后者更能反映打赏意愿本身。

6.3 评分参考

作业按以下标准评估(Exemplary / Adequate / Needs Improvement 三级):能否系统运用describe()sample()query()isna()等本课技法;三个问题是否都给出了有数据依据的结论;是否对"为什么"(如现金支付无小费记录、极端值来源)给出了合理解释。


七、小结:EDA 是建模前不可跳过的"体检"

回到课程主旨:分析阶段(Analyzing)确认数据能够回答提出的问题,EDA 则是这一确认过程的方法论载体。本课的四组工具形成了完整的 EDA 工作流:

步骤工具回答的问题
数据剖面describe()数据有哪些特征?规模多大?质量如何?
抽样与查询sample()/query()数据长什么样?特定假设能否被验证?
可视化matplotlib / seaborn(详见 3-Data-Visualization)存在哪些模式、关系与异常?
缺失值探查isna()/isnull()缺失值在哪?为何缺失?如何处理(见 08 数据准备)?

课程以随堂测验(课前/课后 quiz)与上述作业收尾。无论后续建模使用何种算法,扎实的 EDA 都能显著降低"用错误数据回答错误问题"的风险——这正是数据分析师与数据科学家基本功的核心所在。

【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 3:17:34

HDMI切换器选购指南:从带宽、EDID到RE辐射,避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 3:16:15

微服务+AI改造:统一研发运维标准的实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 3:15:37

如何把 Bun.serve() 应用部署到 Vercel 并配置 bunVersion

如何把 Bun.serve() 应用部署到 Vercel 并配置 bunVersion 【免费下载链接】bun Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one 项目地址: https://gitcode.com/GitHub_Trending/bu/bun 如果你的项目核心是一个 Bun.se…

作者头像 李华