4、数据清洗与预处理:缺失值处理、异常值检测、去重、格式统一、数据标准化与归一化
市场趋势预测的准确性,高度依赖于输入数据的质量。业界流传着一句经典论断:“Garbage in, Garbage out”(垃圾进,垃圾出)。原始数据往往来自多个业务系统、第三方数据源或传感器采集,不可避免地存在缺失、重复、异常、格式混乱和量纲不一致等问题。本章将系统讲解数据清洗与预处理的五大核心环节,帮助学员建立一套可复用的数据质量保障流程,为后续的特征工程与模型训练奠定坚实基础。
4.1 缺失值处理:从“丢弃”到“智能填补”
4.1.1 核心原理
缺失值是指数据集中某些字段的值为空或不可用。在真实的市场数据中,缺失值的产生原因多种多样:用户未填写、系统采集故障、数据同步延迟、业务逻辑导致的不适用等。缺失值处理的核心原则是:尽可能保留信息,同时避免引入偏差。如果简单删除含缺失值的记录,可能导致样本量骤减或引入选择偏差;如果盲目填补,则可能扭曲数据分布。
4.1.2 判断方法与操作流程
处理缺失值前,首先需要判断缺失的机制:
- 完全随机缺失(MCAR):缺失与任何变量无关,可直接删除或简单填补。
- 随机缺失(MAR):缺失与其他已观测变量相关,需用模型预测填补。
- 非随机缺失(MNAR):缺失与缺失值本身相关,需谨慎处理,可能需要业务干预。
| 处理方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 直接删除 | 缺失比例<5%,且为MCAR | 简单、不引入偏差 | 损失样本量 |
| 均值/中位数填补 | 数值型变量,缺失比例较低 | 计算简单、快速 | 降低方差,可能扭曲分布 |
| 众数填补 | 分类变量 | 保持类别分布 | 可能过度代表某一类别 |
| 线性插值 | 时间序列数据 | 利用时间趋势,平滑自然 | 对非线性趋势效果差 |
| KNN填补 | 多维特征,样本量充足 | 利用相似样本信息 | 计算量大,K值敏感 |
| 模型预测填补 | 缺失变量与其他变量相关性高 | 精度高,保留变量关系 | 可能过拟合,需交叉验证 |
4.1.3 案例拆解:电商平台日销售额缺失填补
背景:某电商平台整理2024年1-6月的日销售额数据,发现3月15日、4月2日、5月20日三天数据缺失,原因是数据库迁移期间采集中断。
分析过程:
- 检查缺失比例:3/181 ≈ 1.66%,比例较低。
- 判断缺失机制:缺失日期无特殊促销活动,属于MCAR。
- 对比方案:直接删除(损失3天数据)、均值填补(用全期均值)、线性插值(用前后各2天数据)。
- 选择线性插值,因为销售额具有周周期性,前后日数据更能反映当时水平。
结果:填补后数据分布与原始数据无明显差异,后续趋势预测模型RMSE降低约8%。
4.2 异常值检测:识别“噪声”还是“信号”
4.2.1 核心原理
异常值(Outlier)是显著偏离数据集中趋势的观测值。在市场预测中,异常值可能是数据录入错误、传感器故障、系统Bug,也可能是真实的极端事件(如“双11”销售额暴增、突发疫情导致销量骤降)。关键判断标准是:该值是否反映了真实业务变化?如果是真实事件,应保留并作为特征;如果是噪声,应修正或剔除。
4.2.2 检测方法对比
| 方法 | 原理 | 适用场景 | 阈值/参数 |
|---|---|---|---|
| 3σ原则 | 假设数据服从正态分布,超出均值±3倍标准差视为异常 | 近似正态分布的数据 | σ = 标准差 |
| IQR(四分位距) | 超出Q1-1.5×IQR或Q3+1.5×IQR视为异常 | 偏态分布、非正态数据 | 1.5倍IQR(可调) |
| 箱线图 | 可视化IQR方法,直观展示异常值 | 探索性数据分析 | 同上 |
| DBSCAN聚类 | 基于密度聚类,低密度区域的点视为异常 | 多维数据、非球形分布 | eps, min_samples |
| 业务规则 | 根据领域知识设定合理范围 | 有明确业务约束的字段 | 如价格>0,销量<库存 |
4.2.3 操作流程
- 可视化探索:绘制箱线图、散点图,初步识别异常候选点。
- 统计检测:使用3σ或IQR方法量化异常边界。
- 业务验证:逐一核对异常点是否对应真实事件(促销、节假日、系统故障)。
- 处理决策:噪声→剔除或修正;真实事件→保留并打标签。
4.3 去重:消除“重复计算”的隐患
4.3.1 核心原理
重复数据会导致统计指标虚高、模型过拟合、训练时间增加。去重的核心是定义“重复”的粒度:是完全相同,还是部分关键字段相同?在时间序列数据中,还可能出现“时间窗口内重复”的情况。
4.3.2 去重策略
- 完全去重:所有字段完全相同,直接删除多余记录。
- 关键字段去重:指定唯一键(如用户ID+日期),保留最新或最早记录。
- 时间窗口去重:同一实体在短时间内多次上报,保留聚合值(如取平均、取最大)。
# Python示例:基于关键字段去重
import pandas as pd
df = pd.read_csv('sales_data.csv')
# 按用户ID+日期去重,保留最新记录
df_dedup = df.drop_duplicates(subset=['user_id', 'date'], keep='last')
print(f"去重前: {len(df)} 行, 去重后: {len(df_dedup)} 行")
4.4 格式统一:让数据“说同一种语言”
4.4.1 核心原理
多源数据往往存在格式差异:日期格式(2024/01/01 vs 2024-01-01 vs 01-Jan-2024)、文本大小写、编码方式(UTF-8 vs GBK)、单位(美元 vs 人民币)、时区(UTC vs 北京时间)等。格式不统一会导致后续特征提取失败或模型无法收敛。
4.4.2 统一规范清单
| 字段类型 | 常见问题 | 统一标准 |
|---|---|---|
| 日期时间 | 多种格式混用、时区不一致 | 统一为ISO 8601(YYYY-MM-DD HH:MM:SS),统一时区 |
| 文本 | 大小写混用、全半角混用、空格 | 统一小写(或大写),去除首尾空格,全角转半角 |
| 数值 | 千分位逗号、百分比、货币符号 | 去除符号,转为浮点数 |
| 分类 | 同义不同名(如“男”/“M”/“male”) | 建立映射字典,统一为规范标签 |
| 编码 | UTF-8与GBK混用导致乱码 | 统一转为UTF-8 |
4.4.3 实战场景
某零售企业整合线上App和线下POS机数据,发现线上日期格式为“2024-03-15 14:30:00”(北京时间),线下POS机为“03/15/2024 2:30 PM”(美东时间)。若不统一,按日期聚合销量时会出现偏差。处理方案:统一转为UTC时间戳存储,展示时再按业务时区转换。
4.5 数据标准化与归一化:消除量纲影响
4.5.1 核心原理
市场预测中常涉及多个特征,如销售额(万元)、用户数(千人)、转化率(0-1)、客单价(元)。不同量纲和数量级会导致:距离计算被大数值特征主导、梯度下降收敛缓慢、正则化效果失衡。标准化和归一化的本质是让不同特征具有可比性。
4.5.2 两种主流方法对比
| 方法 | 公式 | 输出范围 | 适用场景 |
|---|---|---|---|
| Z-score标准化 | z = (x - μ) / σ | 无固定范围,均值0,标准差1 | 数据近似正态分布;使用距离度量或梯度下降的模型(SVM、线性回归、神经网络) |
| Min-Max归一化 | x' = (x - min) / (max - min) | [0, 1] | 数据有明确边界;使用距离度量的模型(KNN、K-Means);需要输出在[0,1]范围的场景 |
4.5.3 操作流程与注意事项
- 先拆分数据集:在训练集上计算μ、σ或min、max,再用同一参数转换验证集和测试集,避免数据泄露。
- 异常值影响:Min-Max对异常值敏感,若存在极端值,建议先处理异常或使用RobustScaler(基于中位数和IQR)。
- 稀疏数据:对于稀疏矩阵(如One-Hot编码后的特征),不建议标准化,会破坏稀疏性。
# Python示例:标准化与归一化
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import numpy as np
data = np.array([[1000, 0.05], [2000, 0.08], [3000, 0.12]])
# Z-score标准化
scaler = StandardScaler()
data_z = scaler.fit_transform(data)
# Min-Max归一化
scaler_mm = MinMaxScaler()
data_mm = scaler_mm.fit_transform(data)
print("Z-score结果:\n", data_z)
print("Min-Max结果:\n", data_mm)
4.6 案例复盘:某快消品牌销量预测的数据清洗全流程
背景与约束:某快消品牌计划构建区域销量预测模型,数据源包括:ERP系统(历史销量)、CRM系统(客户信息)、第三方天气数据。原始数据共120万条记录,时间跨度3年,涉及50个SKU、200个区域。
初始现象与目标:初步建模时,模型RMSE高达35%,且训练时间超过4小时。数据质量检查发现:缺失值占比8.5%,重复记录约3.2万条,部分销量字段出现负值(异常),日期格式有3种,价格字段混有货币符号。
关键输入数据与指标:
- 缺失字段:天气数据中的“降雨量”缺失12%,“温度”缺失5%。
- 异常值:销量为负的记录127条,单价超过1000元的记录89条(正常范围50-300元)。
- 重复:同一区域+SKU+日期出现多次的记录。
分析判断过程:
- 缺失值:降雨量缺失与气象站故障相关,属于MAR,使用KNN填补(k=5);温度缺失为MCAR,使用线性插值。
- 异常值:负销量为系统Bug,直接剔除;高单价为促销活动中的组合套餐,保留并新增“是否促销”特征。
- 去重:按“区域+SKU+日期”去重,保留销量最大的记录(因重复多为系统多次上报)。
- 格式统一:日期统一为YYYY-MM-DD,价格去除货币符号转为浮点数,区域名称统一为官方编码。
- 标准化:对销量、价格、温度、降雨量做Z-score标准化。
实际操作步骤:使用Python Pandas进行数据清洗,编写自动化脚本,耗时约2小时完成全量清洗。
结果对比:
| 指标 | 清洗前 | 清洗后 | 提升幅度 |
|---|---|---|---|
| RMSE | 35% | 21% | ↓40% |
| 训练时间 | 4.2小时 | 1.8小时 | ↓57% |
| 数据量 | 120万条 | 115.6万条 | 有效数据保留96.3% |
风险与代价:KNN填补耗时较长(约40分钟),且对内存要求高;剔除负销量记录可能损失少量真实信息,但经业务确认均为系统错误,风险可控。
复盘经验:
- 数据清洗不是一次性工作,应建立自动化流水线,每次数据更新后自动执行。
- 异常值处理前必须与业务团队确认,避免误删真实业务信号。
- 标准化参数(μ、σ)必须持久化保存,供模型上线时对实时数据使用同一参数转换。