📦 数据清洗 · 实战精要

🧪 机器学习赋能需求预测 第4讲

✨ 缺失值、异常值、重复值是数据清洗的三大核心。本章涵盖删除、填充、插值策略,IQR / Z-score 异常检测,以及重复值处理,为需求预测模型提供干净、可靠的数据基础。

📌 1. 缺失值处理 删除 · 填充 · 插值

① 删除 & 填充

  • 删除行/列 缺失比例 < 5% 或随机缺失
  • 固定值填充 0 / 中位数 / 众数 (需求预测常用中位数)
  • 前向/后向填充 时间序列需求数据 (ffill / bfill)
  • 模型填充 KNN / 回归 (高级)
# 中位数填充 (需求预测稳健)
df['sales'].fillna(df['sales'].median(), inplace=True)

# 前向填充 (时间序列)
df['demand'].ffill(inplace=True)

② 插值方法

  • 线性插值 适用于连续趋势
  • 多项式/样条 季节性需求曲线
  • 时间插值 日期索引 (考虑节假日)
# 线性插值 (按索引)
df['demand'].interpolate(method='linear', inplace=True)

# 时间插值 (日期索引)
df['demand'].interpolate(method='time', inplace=True)
💡 需求预测建议: 缺失 < 20% 用插值或中位数; > 50% 考虑删除特征。
📌 2. 异常值检测与处理 IQR 法 · Z-score 法

📐 IQR 四分位距法

  • IQR = Q3 – Q1;下限 = Q1 – 1.5×IQR;上限 = Q3 + 1.5×IQR
  • 适用于偏态分布、含离群点的需求数据
  • 处理:截尾 / 替换为边界值 / 删除
Q1 = df['sales'].quantile(0.25)
Q3 = df['sales'].quantile(0.75)
IQR = Q3 - Q1
lower = Q1 - 1.5*IQR
upper = Q3 + 1.5*IQR
outliers = df[(df['sales'] < lower) | (df['sales'] > upper)]
下限 中位数 上限

📊 Z-score 标准分数法

  • Z = (x – μ) / σ,通常阈值 |Z| > 3 视为异常
  • 适用于近似正态分布的需求数据
  • 处理:删除 / 盖帽法 (winsorize)
from scipy import stats
z_scores = stats.zscore(df['demand'])
outliers = df[abs(z_scores) > 3]

# 盖帽法 (1% / 99% 分位)
df['demand'] = df['demand'].clip(lower=df['demand'].quantile(0.01),
                                  upper=df['demand'].quantile(0.99))
⚖️ 对比: IQR 稳健,适合含极端促销的需求;Z-score 适合稳定销售。
原始需求数据 IQR 检测 Q1/Q3 · 1.5×IQR Z-score 检测 |Z|>3 · 正态假设 清洗 删除 · 截尾 · 盖帽 · 替换为边界值
📌 3. 重复值处理 识别 · 去重 · 聚合
  • 完全重复 所有列相同 → 直接删除
  • 关键列重复 如 (SKU+日期) 重复 → 聚合均值/中位数
  • 去重保留 保留第一个 / 最后一个 (时间序列)
# 完全去重
df.drop_duplicates(inplace=True)

# 按SKU+日期去重,保留最后一次记录
df.drop_duplicates(subset=['sku','date'], keep='last', inplace=True)

# 重复聚合 (均值)
df_grouped = df.groupby(['sku','date'])['demand'].mean().reset_index()
📋 方法对比速查表
类型方法适用场景需求预测注意
缺失值删除 (listwise)缺失极少 <5%避免删除时间序列关键点
中位数 / 插值连续缺失 <30%线性插值适合平滑需求
异常值IQR 法偏态、含促销峰值1.5×IQR 可调整至 3×IQR 若促销频繁
Z-score 法近似正态、稳定品阈值 2.5~3.0 灵活设定
重复值drop_duplicates完全重复 / 主键重复按业务键去重,保留最新或均值
🧰 实战建议: 需求预测中,缺失值优先用时间插值或中位数;异常值用 IQR 结合业务规则 (如大促标记);重复值务必按 SKU+时间 去重,避免数据泄漏。