Data-Science-For-Beginners 表单数据质量评估实战:用数据准备技术诊断并改进信息收集表单
【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners
本篇文章基于 Data-Science-For-Beginners 课程第 8 课"数据准备(Data Preparation)"的配套作业展开,核心任务是:站在数据分析师视角,评估一份用于收集客户基础信息的 HTML 表单及其产生的 CSV 数据,定位其中导致可视化结果错误的"脏数据"根源,并运用课程中讲解的缺失值处理、格式统一、去重等数据清洗技术给出可落地的表单改进建议。读完本文,你将掌握一套"表单字段设计 → 数据质量审计 → 可视化失真归因 → 清洗与改进建议"的完整实战流程,可直接复用到任何需要校验采集数据质量的业务场景。
作业背景:从一份客户表单说起
课程作业描述了一个非常典型的现实场景:一位客户正在测试一个小型表单,用来收集客户群体的基本信息。他把收集到的结果交给了我们,希望验证这些数据的有效性。作业要求我们打开表单页面查看表单设计,结合表单产生的 CSV 数据集与基础可视化结果,使用本课学到的数据准备技术,为改进表单提出建议,使其能够收集到**准确且一致(accurate and consistent)**的信息。
作业涉及的核心文件如下:
| 文件 | 相对路径 | 作用 |
|---|---|---|
| 表单页面 | 2-Working-With-Data/08-data-preparation/index.html | 待评审的客户信息收集表单 |
| 数据集 | data/form.csv | 表单产生的 CSV 记录 |
| 作业 Notebook | 2-Working-With-Data/08-data-preparation/assignment.ipynb | 加载数据与绘制基础可视化的实验环境 |
| 课程讲义 | 2-Working-With-Data/08-data-preparation/README.md | 本作业所依据的数据准备技术讲解 |
在深入分析前,建议先通读课程讲义 2-Working-With-Data/08-data-preparation/README.md 及其配套演示 notebook.ipynb,其中系统的数据清洗目标与策略(格式化、去重、缺失数据处理)正是本次作业的理论武器。
第一步:评审表单设计(index.html)
打开 2-Working-With-Data/08-data-preparation/index.html,可以看到这份表单的完整结构非常精简:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Entry Form</title> </head> <body> <h1>Please Fill out the Form (* required)</h1> *<label>Birth Month</label> <input type="text"> <br> <label>State</label> <input type="text"> <br> <label for="pets">Dogs or Cats?</label> <select name="pets" id="pets"> <option value="dogs">Dog</option> <option value="cats">Cats</option> </select> <br> <button>Submit</button> </body> </html>从源码层面可以立即发现几个关键设计缺陷:
- "Birth Month"(出生月份)是自由文本输入框:
<input type="text">没有任何约束。用户既可以输入January,也可以输入JAN、january、1、01、一月等任意形式,这直接导致了数据集中月份列格式爆炸式不一致。 - "State"(州/地区)同样是自由文本输入框:用户既可以输入
CA(缩写),也可以输入California(全称),甚至Hawaii、AK、RI、FL、Florida等五花八门的写法,还可能出现留空的情况。 - "Dogs or Cats?"(猫还是狗)使用了
<select>下拉框:这是三个字段中唯一做了输入约束的字段。但注意其<option>的value属性是dogs和cats(小写),而页面上显示的文本是Dog和Cats(首字母大写)——一旦数据以显示文本而非 value 落库,就会再次产生大小写不一致。 - 标题声明 "required",但表单没有任何必填校验*:没有
required属性,没有 JS 校验逻辑,也没有maxlength、pattern之类的约束。所以"必填"形同虚设,用户完全可以提交空值,这正是form.csv中出现缺失state的原因。
可以这样说:这份表单把"数据质量控制"完全寄托在了用户自觉上,而真实世界的用户行为是多样且随意的,这为后续数据清洗埋下了必然的伏笔。
第二步:加载并审计 CSV 数据集(form.csv)
作业提供了数据集 data/form.csv,共 10 条记录、3 个字段,与表单字段一一对应:
birth_month,state,pet January,,Cats JAN,CA,Cats Sept,Hawaii,Dog january,AK,Dog July,RI,Cats September,California,Cats April,CA,Dog January,California,Cats November,FL,Dog December,Florida,Cats作业 Notebook assignment.ipynb 中给出了标准的数据加载流程,我们在自己的环境中按同样方式执行:
import pandas as pd import matplotlib.pyplot as plt # 加载数据集 path = '../../data/form.csv' form_df = pd.read_csv(path) print(form_df)运行结果与原数据集一致:
birth_month state pet 0 January NaN Cats 1 JAN CA Cats 2 Sept Hawaii Dog 3 january AK Dog 4 July RI Cats 5 September California Cats 6 April CA Dog 7 January California Cats 8 November FL Dog 9 December Florida Cats缺失值审计
state列的第一条记录是空的,pandas 读入后以NaN呈现。课程讲义 2-Working-With-Data/08-data-preparation/README.md 中强调,pandas 用NaN(浮点缺失值)和 PythonNone两种形式表达缺失,检测它们的方法是isnull()与notnull()。我们可以快速量化缺失情况:
form_df.isnull().sum() # 输出: # birth_month 0 # state 1 # pet 0即 10 条记录中有 1 条state缺失(缺失率 10%)。对于一个旨在分析客户地域分布的小数据集而言,这条记录的缺失会让"客户在哪些州最多"的统计失真。
格式不一致审计
对比数据值,可以肉眼确认两列存在严重的格式(Formatting)不一致问题,这正是课程讲义中明确列出的数据清洗目标之一:
- birth_month 列:
January、JAN、january、Sept、September五种写法并存。同一月份存在大小写不统一(January/JAN/january)、全称与缩写混用(Sept/September)两种问题。 - state 列:
CA、California、Hawaii、AK、RI、FL、Florida并存。同一地区存在缩写与全称混用(CA/California、FL/Florida);更重要的是,Hawaii、AK、RI的出现意味着部分用户根本没按"州缩写"的预期填写,把任意文本都填了进来。 - pet 列:
Cats、Dog两种取值。数据看起来只有两种值,但如果表单把显示文本Cats/Dog存入数据库(而不是<option value="dogs">的小写值),那么后端统计时"dogs"与"Dog"、"cats"与"Cats"就会被当成不同类别——这同样是一种隐藏的格式隐患。
课程讲义对格式化问题的定性非常准确:"根据数据来源不同,数据在呈现方式上可能存在不一致,这会导致搜索和表示值的困难——值明明在数据集里,却无法在可视化或查询结果中正确呈现。"我们的数据集正是这段话的教科书级实例。
第三步:定位"看起来不正确"的可视化
客户反馈"有些可视化看起来不正确,但不知道怎么修"。作业 Notebook 中预置了两段可视化代码,我们逐一复现并分析。
州分布条形图
form_df['state'].value_counts().plot(kind='bar'); plt.show()由于state列存在缺失值,且同一州有两种甚至多种写法(CA 与 California、FL 与 Florida),value_counts()会把CA和California当成两个完全不同的类别分别计数。结果就是:本应聚合为"某州有 N 人"的柱状图,被拆散成若干个高度均为 1 的细柱子,条形图无法反映真实的客户地域分布。同时缺失值NaN不参与value_counts()的默认计数,进一步加剧了统计偏差。
出生月份条形图
form_df['birth_month'].value_counts().plot(kind='bar'); plt.show()同理,birth_month列中January、JAN、january在 pandas 看来是三个不同的字符串类别,于是"一月出生"的 3 条记录被拆成三个柱子(January×2、JAN×1、january×1),而不是合并成一根高度为 3 的柱子。数据本身没有错,错的是数据的表示方式不够统一,导致可视化聚合失效——这正是课程讲义反复强调的"格式化问题会让值无法在可视化中正确呈现"的直接体现。
归因结论
两张图"看起来不正确"的根因可以归纳为三点,全部源自表单设计而非绘图代码:
state列存在缺失值,导致统计基数不完整;- 自由文本输入导致同一类别多种写法并存,
value_counts()聚合被拆散; - 上述两点叠加,使得任何基于类别的可视化(条形图、计数图等)都无法给出准确结论。
第四步:用课程技术清洗数据,验证根因
在向客户提出表单改进建议之前,我们可以先用课程讲义中的技术对现有数据做一次"演示级清洗",从而量化说明"只要统一格式,可视化立刻恢复正常"。这一步并非作业强制要求,但它能显著增强建议的说服力。
统一 birth_month 格式
利用 pandas 的字符串方法把月份统一为规范形式。先做大小写归一,再通过映射把缩写/全称对齐到标准月份名:
month_map = { 'january': 'January', 'february': 'February', 'march': 'March', 'april': 'April', 'may': 'May', 'june': 'June', 'july': 'July', 'august': 'August', 'september': 'September', 'october': 'October', 'november': 'November', 'december': 'December', 'jan': 'January', 'feb': 'February', 'mar': 'March', 'apr': 'April', 'jun': 'June', 'jul': 'July', 'aug': 'August', 'sep': 'September', 'sept': 'September', 'oct': 'October', 'nov': 'November', 'dec': 'December' } form_df['birth_month_clean'] = ( form_df['birth_month'] .str.strip() # 去除首尾空白 .str.lower() # 统一小写 .map(month_map) # 对齐到标准月份名 )清洗后January、JAN、january全部归并为January,Sept、September归并为September。此时再画图,一月就能正确聚合成一根高度为 3 的柱子。
统一 state 格式并处理缺失
对州字段,先统一为州缩写,再决定缺失值的处理策略。课程讲义给出了缺失值处理的两种大方向:删除(dropna)或填充(fillna)。对于只有 10 条记录的小数据集,直接删除会损失 10% 的样本,通常更推荐结合业务知识填充或暂时保留并在分析中注明:
state_map = { 'ca': 'CA', 'california': 'CA', 'ak': 'AK', 'alaska': 'AK', 'ri': 'RI', 'fl': 'FL', 'florida': 'FL', 'hawaii': 'HI' } form_df['state_clean'] = ( form_df['state'] .str.strip() .str.lower() .map(state_map) ) # 方案A:删除缺失行(适合大样本) form_df_clean_drop = form_df.dropna(subset=['state_clean']) # 方案B:填充缺失值(fillna),例如标注为 'Unknown' 或按众数填充 form_df['state_filled'] = form_df['state_clean'].fillna('Unknown')需要说明的是,课程讲义也提醒:fillna还支持前向填充(method='ffill')、后向填充(method='bfill')等策略,具体选哪种取决于数据缺失的原因与业务背景;对分类数据,用众数(mode)填充是常见做法。清洗后再执行value_counts().plot(kind='bar'),各州的计数就能正确聚合,图表的"不正确感"随之消失。
顺带检查重复数据
课程讲义专门强调了**重复数据(Duplications)**会歪曲分析结果。本例数据量小,肉眼即可确认无重复行,但我们可以养成用duplicated()/drop_duplicates()检查的习惯:
form_df.duplicated().sum() # 返回 0,无重复行清洗总结表
| 数据问题 | 所属类别(课程定义) | 清洗手段 |
|---|---|---|
| state 缺失 1 条 | Missing Data(缺失数据) | isnull()检测;dropna()删除或fillna()填充 |
| 月份大小写/缩写混用 | Formatting(格式化) | str.strip()+str.lower()+ 映射表统一 |
| 州缩写/全称混用 | Formatting(格式化) | 同上 |
| 潜在 pet 大小写问题 | Formatting(格式化) | 后端落库时统一采用<option value>值 |
第五步:面向客户的表单改进建议
作业的核心交付物是"为改进表单提出建议,使其收集准确且一致的信息"。结合前三步的诊断,建议从输入约束和数据规范两个层面出发,逐字段给出方案。
1. 出生月份:把文本框换成下拉选择框
自由文本输入是月份格式混乱的唯一根源,最彻底的解法是从源头禁止自由输入:
<label for="birth_month">Birth Month *</label> <select name="birth_month" id="birth_month" required> <option value="">-- Select Month --</option> <option value="January">January</option> <option value="February">February</option> <!-- ... 其余月份 ... --> <option value="December">December</option> </select>要点:<option value>使用统一的规范值(如标准英文月份名),页面显示文本与落库值保持一致;默认提供空选项并要求用户显式选择,避免用户"顺手提交默认值"。
2. 州/地区:同样改为受控下拉框
针对CA与California混用的问题,用<select>枚举全部州选项(value 统一为官方两字母缩写)即可一劳永逸:
<label for="state">State</label> <select name="state" id="state"> <option value="">-- Select State --</option> <option value="AK">Alaska</option> <option value="CA">California</option> <option value="FL">Florida</option> <option value="HI">Hawaii</option> <option value="RI">Rhode Island</option> <!-- ... 其余州 ... --> </select>若业务上确实需要保留自由输入(如"其他/其他地区"),则应配合pattern正则或后端白名单校验,并在入库前统一strip + lower + 映射。
3. 宠物字段:统一选项值语义
现有<select>的方向是对的,但要注意两点:其一,落库值应严格采用<option value="dogs">/<option value="cats">中的小写 value,而不是显示文本Dog/Cats;其二,可考虑增加第三个选项None/Other,防止用户被迫二选一。
4. 必填校验要真正落地
页面标题写着 "* required",但三个字段中只有出生月份带星号,且没有任何字段真正设置required。改进建议:
- 在真正必填的字段上添加
required属性(如出生月份、宠物偏好),让浏览器在提交前完成前端校验; - 对自由输入字段设置
maxlength限制长度; - 后端(或数据入库脚本)再做一次非空、格式校验,双保险。
5. 建立统一的数据规范文档
最后一条建议属于流程层面:任何信息收集工具都应配套一份"数据字典/填写规范",明确每个字段的合法取值、存储格式(大小写、缩写规则)、必填策略。这呼应了课程讲义开篇的论点——数据规范统一后,多源数据才能顺利合并,模型与分析结果才可信。
评分标准解读(Rubric)
作业末尾给出了三档评分标准,可以作为自查清单:
| 档位 | 达标表现 |
|---|---|
| Exemplary(优秀) | 准确识别表单在输入约束上的设计缺陷,提出的建议能系统性解决数据准确性与一致性问题,并给出可执行的实现方案(如本文的改进 HTML 片段与清洗代码) |
| Adequate(合格) | 指出了部分数据问题(如格式不统一、有缺失值),提出了改进方向,但不够系统或缺乏落地细节 |
| Needs Improvement(待改进) | 仅描述了数据表面现象,未与表单设计缺陷建立因果联系,或未提出实质改进建议 |
对照本文的完整路径——评审表单 → 审计数据 → 归因可视化错误 → 演示清洗 → 给出逐字段改进方案——可以确保输出达到 Exemplary 档位。
总结
本次作业表面上是对一份表单的评价,实质上是一次完整的数据质量闭环训练:表单设计决定数据质量的上限,数据清洗只能修复而非根治问题。通过 index.html 的自由文本字段设计缺陷,到 data/form.csv 中缺失值、格式混用的真实脏数据,再到 assignment.ipynb 中条形图聚合失效的可视化失真,我们完整走通了课程第 8 课"数据准备"所强调的三大清洗目标——格式化、缺失数据处理、去重,并最终把诊断结论反哺为表单的改进建议。
这套方法不限于本仓库的教学场景:任何涉及问卷调查、注册表单、CRM 数据采集的项目,都可以把"约束输入 + 规范存储 + 入库前清洗"作为默认防线,从源头保证后续分析与建模的数据质量。
【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考