4. 成本数据采集与清洗:数据源识别、质量检查与异常处理
成本趋势预测的准确性,80% 取决于底层数据的质量。在采购管理平台中,成本数据分散在多个异构系统与外部渠道,必须经过系统化的采集与清洗,才能进入预测模型。本节将拆解数据源识别、质量检查、缺失值与异常值处理三个核心环节。
4.1 数据源识别:ERP、SRM 与外部市场
采购成本数据主要来自三类源头,每类源头的结构、更新频率与可信度不同,需要分别设计采集策略。
| 数据源类型 | 典型系统/渠道 | 核心数据字段 | 更新频率 | 采集方式 |
|---|---|---|---|---|
| ERP | SAP、Oracle EBS、用友、金蝶 | 采购订单价格、发票价格、库存成本、物料主数据 | 日/实时 | API 接口 / 数据库直连 / 中间表 |
| SRM | Ariba、Coupa、SAP Ariba、自建平台 | 询报价记录、合同价格、供应商绩效、招标结果 | 周/日 | API 接口 / 文件导入 |
| 外部市场 | 上海有色网、Platts、Wind、海关数据 | 大宗商品指数、汇率、关税、运费指数 | 日/周 | RPA 爬虫 / 第三方 API / 人工录入 |
实践建议:优先通过 API 或数据库直连采集 ERP 与 SRM 数据,保证实时性与一致性;外部市场数据建议使用 RPA 或第三方数据服务商 API,避免人工录入带来的延迟与错误。
4.2 数据质量检查:六维评估框架
数据进入清洗阶段前,必须进行系统性质量评估。推荐使用 六维数据质量框架 对每个字段打分,低于阈值的字段需要优先处理。
- 完整性(Completeness):检查必填字段(如物料编码、采购价格、供应商ID)的空值比例,阈值通常设为 < 5%。
- 准确性(Accuracy):抽样比对系统数据与原始凭证(如发票、合同),误差率应 < 1%。
- 一致性(Consistency):同一物料在不同系统中的编码、单位、价格币种是否一致。
- 时效性(Timeliness):数据是否在预期时间窗口内更新,延迟超过 24 小时的数据需标记。
- 唯一性(Uniqueness):是否存在重复的采购订单记录或供应商主数据。
- 有效性(Validity):字段值是否符合业务规则(如价格 > 0、日期格式正确)。
质量检查清单示例(以采购订单价格字段为例):
- 完整性:空值率 2.3%(通过)
- 准确性:抽样 200 条,误差 0.5%(通过)
- 一致性:ERP 与 SRM 价格差异 > 5% 的记录占 8%(不通过,需对齐)
- 时效性:98% 的订单在 4 小时内同步(通过)
- 唯一性:重复订单号 0 条(通过)
- 有效性:负价格记录 3 条(不通过,需处理)
- 完整性:空值率 2.3%(通过)
- 准确性:抽样 200 条,误差 0.5%(通过)
- 一致性:ERP 与 SRM 价格差异 > 5% 的记录占 8%(不通过,需对齐)
- 时效性:98% 的订单在 4 小时内同步(通过)
- 唯一性:重复订单号 0 条(通过)
- 有效性:负价格记录 3 条(不通过,需处理)
4.3 缺失值处理策略
缺失值在成本数据中常见于:外部市场指数未更新、供应商未填写报价、历史数据迁移遗漏。处理策略需根据缺失率与字段重要性选择。
| 缺失率 | 字段重要性 | 推荐策略 | 适用场景 |
|---|---|---|---|
| < 5% | 高 | 均值/中位数填充 | 价格、数量等连续数值字段 |
| 5% – 20% | 高 | 时间序列插值(线性/样条) | 月度成本指数、汇率序列 |
| > 20% | 高 | 模型预测填充(回归/随机森林) | 供应商报价缺失,但有其他特征可预测 |
| 任意 | 低 | 删除该字段或标记为“未知” | 备注、辅助描述字段 |
注意:对于时间序列成本数据,禁止使用全局均值填充,这会破坏趋势与季节性模式。应优先使用前向填充(Forward Fill)或时间插值。
4.4 异常值检测与处理
异常值可能来自数据录入错误、系统故障或真实的极端市场事件(如原材料价格暴涨)。需要区分“噪声”与“信号”。
4.4.1 常用检测方法
- Z-Score 法:适用于正态分布数据,|Z| > 3 视为异常。
- IQR 四分位距法:适用于偏态分布,超出 Q1 – 1.5×IQR 或 Q3 + 1.5×IQR 视为异常。
- 移动平均偏差法:适用于时间序列,当前值偏离 30 日移动平均 ±3 倍标准差时标记。
- 业务规则法:价格突变超过 50%、数量为负数、日期为未来等硬性规则。
4.4.2 处理流程
- 标记:对每条异常记录添加异常标签与检测方法。
- 人工复核:采购专家判断是否为真实市场波动(如铜价单日上涨 8% 可能是真实事件)。
- 处理:
- 确认录入错误 → 修正或删除
- 确认真实事件 → 保留并标记为“极端事件”
- 无法确认 → 用插值替换或剔除 - 记录:将异常处理日志写入数据血缘表,供预测模型参考。
4.5 数据清洗代码示例(Python)
以下代码片段展示了在采购成本数据集中执行缺失值填充与异常值检测的典型流程。
import pandas as pd
import numpy as np
# 加载采购成本数据
df = pd.read_csv('procurement_cost.csv', parse_dates=['date'])
# 1. 缺失值处理:价格字段使用前向填充
df['unit_price'] = df['unit_price'].fillna(method='ffill')
# 2. 异常值检测:IQR 法
Q1 = df['unit_price'].quantile(0.25)
Q3 = df['unit_price'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# 标记异常
df['is_outlier'] = (df['unit_price'] < lower_bound) | (df['unit_price'] > upper_bound)
# 3. 处理异常:对标记为异常且非真实事件的数据进行插值
# 假设已有人工复核列 'confirmed_event'
mask = df['is_outlier'] & ~df['confirmed_event']
df.loc[mask, 'unit_price'] = np.nan
df['unit_price'] = df['unit_price'].interpolate(method='linear')
# 4. 输出清洗报告
print(f"清洗后记录数: {len(df)}")
print(f"异常值处理数: {mask.sum()}")
print(f"缺失值填充数: {df['unit_price'].isna().sum()}")
工程提示:在生产环境中,建议将清洗逻辑封装为可配置的 ETL 管道(如 Airflow DAG),每次运行自动生成数据质量报告并发送给采购数据管理员。
4.6 数据血缘与版本管理
每次清洗操作都应记录数据血缘,确保预测结果可追溯。推荐维护一张 清洗日志表:
| 字段 | 说明 | 示例 |
|---|---|---|
| record_id | 原始记录唯一标识 | PO-2024-00123 |
| field_name | 被修改的字段 | unit_price |
| original_value | 修改前的值 | 0.00 |
| new_value | 修改后的值 | 15.80 |
| operation_type | 操作类型 | 缺失值填充 / 异常值修正 |
| operator | 执行人/系统 | etl_pipeline_v2.1 |
| timestamp | 操作时间 | 2024-06-15 03:00:00 |
通过完整的数据血缘记录,采购分析师可以随时回溯某个成本预测值的来源,增强模型的可信度与审计合规性。