人人都会AI编程

20.4 数据清洗、特征工程、探索性分析流程

更新时间:2026-07-12

在拿到一份原始数据之后,直接从建模入手几乎一定会碰壁——缺失值、异常值、格式混乱、特征与目标相关性未知,这些都会让后续工作返工。一套规范且可复用的数据处理流程,是数据分析与机器学习项目的基石。本节就梳理这三步的标准操作和 Python 实现要点。

数据清洗:让脏数据变干净

真实数据从来都不会整齐干净。清洗的目标是处理缺失、重复、不一致的数据,使其可以安全地用于分析或建模。

常见问题与处理方式

  • 缺失值

df.isnull().sum() 统计缺失情况。决策思路:

  • 缺失比例很小(<5%)且随机 → 可直接删除行(dropna())或用均值/中位数/众数填充。
  • 缺失较多但特征重要 → 用分组填充(如按类别填均值)、向前/向后填充(ffill/bfill)或模型预测填充。
  • 缺失过多且特征意义不大 → 直接删除列。
  • 重复数据

df.duplicated().sum() 检测,df.drop_duplicates() 删除。注意根据业务判断“唯一键”是什么,避免误删。

  • 数据类型与格式错误
  • 数值列中出现字符串 → pd.to_numeric(col, errors='coerce') 强制转换。
  • 日期列格式混乱 → pd.to_datetime(col, format=...) 统一解析。
  • 字符串前后空格、大小写不一致 → str.strip()str.lower() 规范化。
  • 异常值检测

可以用箱线图(seaborn.boxplot)或 IQR 方法识别。处理时结合业务:异常可能是真实极值(如大额交易),也可能是录入错误。保守做法是截尾(clip)或盖帽,而不是直接删除。

特征工程:从原始字段中挖掘更多信号

特征工程决定了模型的上限。好的特征能让简单的模型也表现优秀。

构造新特征

  • 时间特征拆解:从 datetime 列中提取年、月、日、星期几、是否周末、是否节假日。Pandas 的 .dt 访问器可直接获得这些属性。
  • 文本特征处理:用 str.contains 标记关键字是否存在,用 str.len 计算长度,或用 TF-IDF 向量化(sklearn.feature_extraction.text.TfidfVectorizer)。
  • 组合特征:加减乘除、比率(如“总价/面积”得到单价)、交叉特征(如“性别×年龄段”)。
  • 聚合特征:在分组场景下(如用户多个订单),对每组统计 count、sum、mean、max、min 等。

特征变换

  • 标准化与归一化

对距离敏感模型(如 SVM、KNN)需将特征缩放到相同尺度。

  • 标准化(StandardScaler):均值为 0、标准差为 1,适用于大多算法。
  • 归一化(MinMaxScaler):缩放到 [0,1],对神经网络有利。
  • 非线性变换

对数变换(np.log1p)可处理长尾分布,使数据更接近正态分布。Box-Cox 变换也可尝试。

  • 离散化/分箱

将连续年龄转为年龄段,既增加非线性又提高可解释性,可用 pd.cutpd.qcut

特征编码

  • 标签编码:将有序类别转成 0,1,2...(sklearn.LabelEncoder)。
  • 独热编码:无序类别转成虚拟变量(pd.get_dummiesOneHotEncoder),注意避免多重共线性(drop_first=True)。
  • 目标编码:用目标变量的均值来编码类别,需小心过拟合,通常结合交叉验证。

特征选择

  • 方差过滤VarianceThreshold 移除方差极低(近乎常数)的特征。
  • 相关系数过滤:计算特征与目标的相关性,保留较强的特征;特征间高相关则保留其一。
  • 模型内嵌选择:使用带正则化(L1)的模型,或树模型的特征重要性自动筛选。

探索性分析流程:看清数据再动手

探索性数据分析(EDA)的目的不是产出模型,而是用统计和可视化回答:数据长什么样?特征和目标有什么关系?哪里有坑?

高效 EDA 流水线

  1. 概览数据全貌
  • df.shapedf.info()df.describe() 快速查看大小、类型、数值统计。
  • 缺失值比例、唯一值个数(df.nunique())。
  1. 单变量分析
  • 数值变量:用直方图看分布(sns.histplot)、用箱线图看离散值。
  • 类别变量:用柱状图或计数图(sns.countplot)看频次。
  1. 双变量与多变量关系
  • 数值 vs 数值:散点图(sns.scatterplot)或散点矩阵(sns.pairplot),观察线性/非线性趋势。
  • 数值 vs 类别:分组箱线图或提琴图(sns.boxplot(x=cat, y=num)),比较组间差异。
  • 类别 vs 类别:交叉表(pd.crosstab)或堆叠柱状图,看分布比例。
  1. 目标导向分析
  • 针对你要预测的标签,重复上述双变量分析,优先找出强相关特征。
  • 相关性热力图(sns.heatmap(df.corr()))直观展示特征间及与目标的关系。
  1. 记录与假设形成
  • 随手记录发现的模式、异常和想法(Jupyter 的 Markdown 单元格就很好用)。
  • 形成可验证的假设:如“高收入人群流失率更低”,并在建模后回头验证。

真实建议

  • 不要试图把每个角落都探索干净,在足够理解数据后立即进入特征工程和建模,再根据模型表现针对性地回到 EDA 深挖。
  • 善用第三方辅助库:pandas_profiling(已更名 ydata-profiling)可一键生成数据报告;autovizsweetviz 也能快速生成可视化总览。
  • 始终把业务逻辑放在首位:一个数值异常在业务上可能正是你感兴趣的高价值用户群,不要机械地用统计规则删除。

这“三步曲”在数据项目中并非严格线性,而是循环迭代:建模后发现测试集表现差,往往要回溯到清洗和特征工程,甚至重新做探索分析。掌握它们,就能把混乱的原始数据转化为干净、有用、可建模的结构化数据集。