4. 数据准备与清洗
滚动13周现金流预测模型的质量,不取决于公式有多复杂,而取决于输入数据的干净程度。很多学员在建模阶段反复调试公式,却忽略了真正的问题出在数据源头:银行流水与ERP科目口径不一致、同一笔付款被重复计入、期初余额与银行对账单差了几百元却找不到原因。本节聚焦数据准备与清洗这一“脏活累活”,它是整个模型可信度的地基。
一、核心原理:预测模型的输入决定输出上限
现金流预测本质上是把未来的收付款事件按时间轴排列。数据准备的目标,是把分散在不同系统中的原始记录,转化为统一口径、统一时间粒度、统一币种、可追溯的现金事件表。这里有一个关键原则:先对齐口径,再谈预测精度。如果科目映射错误,再精细的预测算法也只是在错误的基础上放大误差。
数据清洗不是一次性动作,而是一个可重复执行的管道:抽取(Extract)→ 映射(Map)→ 清洗(Clean)→ 校验(Validate)→ 锁定快照(Snapshot)。每一周滚动更新时,都应重新跑一遍这个管道,而不是手工修补Excel。
二、数据来源与科目映射
滚动13周预测通常需要三类数据源:银行流水(实际已发生的现金收付)、ERP应收应付模块(已确认但未到期的债权债务)、合同与订单系统(未来可能发生的收付款承诺)。三者时间属性不同,必须分别处理。
科目映射是清洗环节最容易出错的地方。ERP中的会计科目(如“应收账款—A客户”“预付账款—B供应商”)需要映射到现金流预测的类别维度。建议建立一张独立的映射表,字段包括:科目代码、科目名称、现金流类别(经营/投资/筹资)、预测行项目(销售回款/采购付款/工资/税费等)、是否纳入13周预测、映射生效日期。
| 科目代码 | 科目名称 | 现金流类别 | 预测行项目 | 纳入13周 |
|---|---|---|---|---|
| 1122 | 应收账款 | 经营活动 | 销售回款 | 是 |
| 1123 | 预付账款 | 经营活动 | 采购付款 | 是 |
| 2202 | 应付账款 | 经营活动 | 采购付款 | 是 |
| 2211 | 应付职工薪酬 | 经营活动 | 工资社保 | 是 |
| 2221 | 应交税费 | 经营活动 | 税费缴纳 | 是 |
| 1601 | 固定资产 | 投资活动 | 资本性支出 | 是 |
| 2001 | 短期借款 | 筹资活动 | 借款与还款 | 是 |
| 6602 | 管理费用 | 经营活动 | 其他经营支出 | 否 |
三、异常值处理与数据校验方法
异常值处理遵循“先识别、再分类、后处置”的顺序。常见异常包括:重复记录(同一笔付款在银行流水和ERP中同时出现)、金额离群(单笔金额超过历史均值10倍)、日期缺失或超出预测窗口、币种未折算、正负号方向错误。
处置策略不是简单删除,而是分级处理:
- 重复记录:按“日期+金额+对方户名”做去重,保留银行流水优先,ERP记录标记为已核销。
- 金额离群:不直接剔除,先人工确认是否为真实大额交易;确认为异常后单独挂起,不纳入自动预测。
- 日期缺失:按合同账期或历史平均回款天数推算,并标记为“推算值”,在预测结果中单独列示。
- 方向错误:通过科目余额方向与现金流方向交叉验证,收款为流入、付款为流出。
数据校验是最后一道关卡,建议至少执行以下四项检查:
- 期初余额勾稽:模型期初现金余额 = 银行对账单余额 + 在途资金 − 未兑现支票。
- 连续性检查:第N周期末余额 = 第N周期初余额 + 净现金流,逐周滚动验证。
- 映射完整性:所有纳入预测的科目均能在映射表中找到对应行项目。
- 时间窗口检查:事件日期落在13周预测区间内,超出区间的记录单独归档。
# 数据校验伪代码示例
def validate_cashflow(df, opening_balance):
# 1. 期初余额勾稽
assert abs(df.opening_balance - opening_balance) < 0.01, "期初余额不匹配"
# 2. 逐周连续性
for week in range(1, 14):
expected = df.loc[week-1, 'closing'] + df.loc[week, 'net_cashflow']
assert abs(df.loc[week, 'closing'] - expected) < 0.01, f"第{week}周连续性断裂"
# 3. 映射覆盖率
coverage = df.mapped_amount.sum() / df.total_amount.sum()
assert coverage >= 0.98, f"映射覆盖率不足: {coverage:.2%}"
# 4. 重复记录检查
dup = df.duplicated(subset=['date', 'amount', 'counterparty'], keep=False)
if dup.any():
print(f"发现{dup.sum()}条疑似重复记录,需人工复核")
return True
四、复盘:一次映射错误导致的预测偏差
某制造企业曾出现13周预测中“采购付款”持续偏低的问题。排查后发现,ERP中“应付账款—设备类”被错误映射到了“投资活动—资本性支出”,而该科目实际包含大量日常备件采购。修正映射后,经营现金流预测值上调了约12%。这个案例说明:科目映射不是一次配置就永久有效,当业务科目体系调整、新增供应商或改变采购模式时,映射表必须同步更新。
建议每周滚动更新时执行一次“映射变更日志”检查,记录新增科目、停用科目和映射调整,确保预测模型的口径与最新业务实质保持一致。数据准备与清洗做扎实了,后续的13周滚动预测才有可信的起点。