在拿到一份原始数据之后,直接从建模入手几乎一定会碰壁——缺失值、异常值、格式混乱、特征与目标相关性未知,这些都会让后续工作返工。一套规范且可复用的数据处理流程,是数据分析与机器学习项目的基石。本节就梳理这三步的标准操作和 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.cut 或 pd.qcut。
特征编码
- 标签编码:将有序类别转成 0,1,2...(
sklearn.LabelEncoder)。 - 独热编码:无序类别转成虚拟变量(
pd.get_dummies或OneHotEncoder),注意避免多重共线性(drop_first=True)。 - 目标编码:用目标变量的均值来编码类别,需小心过拟合,通常结合交叉验证。
特征选择
- 方差过滤:
VarianceThreshold移除方差极低(近乎常数)的特征。 - 相关系数过滤:计算特征与目标的相关性,保留较强的特征;特征间高相关则保留其一。
- 模型内嵌选择:使用带正则化(L1)的模型,或树模型的特征重要性自动筛选。
探索性分析流程:看清数据再动手
探索性数据分析(EDA)的目的不是产出模型,而是用统计和可视化回答:数据长什么样?特征和目标有什么关系?哪里有坑?
高效 EDA 流水线
- 概览数据全貌
df.shape、df.info()、df.describe()快速查看大小、类型、数值统计。- 缺失值比例、唯一值个数(
df.nunique())。
- 单变量分析
- 数值变量:用直方图看分布(
sns.histplot)、用箱线图看离散值。 - 类别变量:用柱状图或计数图(
sns.countplot)看频次。
- 双变量与多变量关系
- 数值 vs 数值:散点图(
sns.scatterplot)或散点矩阵(sns.pairplot),观察线性/非线性趋势。 - 数值 vs 类别:分组箱线图或提琴图(
sns.boxplot(x=cat, y=num)),比较组间差异。 - 类别 vs 类别:交叉表(
pd.crosstab)或堆叠柱状图,看分布比例。
- 目标导向分析
- 针对你要预测的标签,重复上述双变量分析,优先找出强相关特征。
- 相关性热力图(
sns.heatmap(df.corr()))直观展示特征间及与目标的关系。
- 记录与假设形成
- 随手记录发现的模式、异常和想法(Jupyter 的 Markdown 单元格就很好用)。
- 形成可验证的假设:如“高收入人群流失率更低”,并在建模后回头验证。
真实建议
- 不要试图把每个角落都探索干净,在足够理解数据后立即进入特征工程和建模,再根据模型表现针对性地回到 EDA 深挖。
- 善用第三方辅助库:
pandas_profiling(已更名 ydata-profiling)可一键生成数据报告;autoviz、sweetviz也能快速生成可视化总览。 - 始终把业务逻辑放在首位:一个数值异常在业务上可能正是你感兴趣的高价值用户群,不要机械地用统计规则删除。
这“三步曲”在数据项目中并非严格线性,而是循环迭代:建模后发现测试集表现差,往往要回溯到清洗和特征工程,甚至重新做探索分析。掌握它们,就能把混乱的原始数据转化为干净、有用、可建模的结构化数据集。