资讯动态

一文读懂资金流入流出预测:赛题理解与时间序列建模要点

发布时间:2026/10/14 11:14:31 来源:尧图企业网站定制
第一次打开这类资金流入流出预测赛题的时候我其实有点懵数据表里躺着一堆用户行为记录金额有大有小时间有长有短可赛题到底要我们预测什么是整个平台的资金总量还是每个用户自己的余额变化评价指标又是怎么算的如果不把这些问题搞清楚后面的特征工程做得再漂亮也容易跑偏方向。这篇是资金流入流出预测系列的第一篇我只讲一件事——赛题理解。说白了就是接到题目之后怎么把一个模糊的“预测资金流入流出”业务问题拆解成数据上可定义、指标上可量化、建模上可执行的清晰任务。这个阶段看起来不起眼但很多返工都源于这里没做透。读完这篇你能搞清楚这类题目的数据长什么样、预测目标到底是什么、评价指标怎么反向影响你的预处理以及如何在动手建模前就避开几个致命的时间穿越陷阱。1. 资金流入流出预测到底在预测什么从业务定义到任务边界1.1 一个交易流水表背后的用户资金行为先想象一个实际的业务场景一个大型支付平台每天有海量用户在里面做各种操作。有人用余额付款有人往账户里充值有人买了理财产品有人把理财赎回还有人把自己的钱转给另一个用户。这些行为都会在系统里留下一笔一笔的交易记录。站在平台的角度看钱的走向无非两种钱从外部进入平台或者钱从平台流向外部。前者就是资金流入后者就是资金流出。听起来很直觉但真落到数据上就没有这么干净了。用户把银行卡里的钱充值到平台余额这是流入用户用余额买东西给商家钱到了另一个用户的账户里从平台整体看这笔钱并没有离开平台系统只是换了主人但如果商家提现到银行卡钱才真正流出了平台。所以“流入”和“流出”的定义取决于你站在哪个统计口径上看是站在单个用户角度还是站在平台资金池总盘子的角度。赛题不会直接给你一个已经分好类的“流入”和“流出”字段它很可能只有一笔笔带行为类型的流水需要你自己去聚合口径。这里就引出了赛题理解的第一层要义你必须先弄清楚预测对象是平台总体的资金流入流出金额而不是每个用户的余额变化。平台总体盘子更容易受宏观因素和头部用户影响个体行为噪声巨大两者在特征设计和模型选择上完全是两条路线。1.2 赛题的任务边界与预测口径再看任务定义。典型的资金流入流出预测赛题会给你一段历史时间范围内的用户数据要求你预测未来某一段时间内的资金流入总额和流出总额。这个“某一段时间”很关键有的赛题要求逐日预测有的要求预测一个时间段的总量有的甚至要求预测未来多天的日序列。我见过不少参赛选手忽略预测窗口长度对数据切分方式的影响。如果你要预测的是未来14天每一天的流入流出那么你的训练样本标签就是“某一天之前的N天特征 → 当天的流入/流出值”类似于监督学习中的时序预测如果你只需要预测一个完整月份的总额那问题又变得更接近“用一个时间段的特征预测另一个时间段的聚合值”。后者虽然指标上可能也是均方误差一类的回归损失但样本量会骤减因为你能构造的独立时间段样本本身就不多。还有一个容易被忽略的口径问题流入和流出是预测两个独立的数值还是预测一个净值。这两个建模难度完全不同。净值往往波动小、稳定性高看起来更好预测但它掩盖了业务风险——某个交易日流入流出同时暴增但净值没变这种异常对平台来说恰恰是最需要关注的。赛题如果明确给了流入和流出两个目标就老老实实各建一个模型不要图省事用净值替代。1.3 输入输出关系吃透数据字典是动手前最重要的一步赛题理解最终要落到输入输出的明确化。从数据层面这类题通常包括用户基本信息表每个用户的静态属性比如所在城市、注册时间、年龄段、偏好标签等。日粒度余额明细表每个用户每天在平台上的资金快照包括持有总资产、可用余额、在途金额、各类理财产品持仓等可能还会附带当天发生的一些汇总行为数值。宏观参考数据表比如不同期限的市场利率报价或者平台自身发布的收益率数据用于引入外部环境变量。从输出层面提交文件一般是“预测日期 流入金额 流出金额”的格式有的还会细化到按用户分组。我建议拿到数据后的第一件事不是跑一通describe而是画一张纸左侧写上能用到的输入表右侧写上要预测的目标字段中间用箭头标出它们的关联键和时间粒度。这张图画完你就知道哪些字段是静态的、哪些是时序的、哪些是你根本用不上的冗余列。任何字段在脑子里没有清晰含义之前都不要放进特征里。2. 数据资产的完整拆解这类题目的标配三表结构与关联方式2.1 用户信息表静态数据能带来的先验偏差用户信息表通常是三张表里最“安分”的一张每条记录代表一个用户每个用户只出现一次。字段无外乎是用户标识、性别、城市等级、星座、注册时间等。很多选手觉得这张表信息量有限草草做了个用户维度的统计就扔到一边。实际上用户信息表的价值在于提供分层视角不同城市等级的用户资金行为差别非常大一线城市用户可能更多使用理财功能下沉市场用户可能更多用于转账付款不同注册时长的用户其资金沉淀规律也完全不同。举个我实际遇到过的情况注册时间很短的新用户其资金流入流出往往和拉新活动节奏强相关而老用户的行为更稳健、更有周期性。如果你把新老用户混在一起做全局特征模型会在某些时间段被新用户的高波动样本带偏而在另一些时间段被老用户的稳定样本带出虚高的置信度。所以赛题理解阶段就要想好是全局建模还是分层建模还是把用户分层结果作为特征喂进去。2.2 每日余额明细表最核心但最容易被误读的表每日余额明细表是整个赛题的核心资产。它的粒度通常是“用户ID × 日期”每个用户每天一行描述的是用户在当天的资金快照。这里有几个需要在赛题理解阶段就确认清楚的细节时间粒度是否连续是不是每个用户每天都有记录如果用户某天没有任何操作他是没有记录还是有一条全零的记录快照值还是发生值字段描述的是当天结束后账户里有多少钱还是当天发生了一共多少钱的变动空值的语义是什么某个字段为空是数据缺失、用户未持有该产品还是金额为0这三个语义对特征填充策略的影响完全不同。我有一次就因为没搞清某字段的空值语义在特征工程阶段把“未持有该理财产品”的用户全部填充成了0结果对后续排序类模型影响不大但在回归模型里直接把一大批样本的预测值拉向了0改回“单独标记空值”之后误差才降下来。这里还要看表里是否直接包含流入流出相关的字段。有的赛题会直接在余额明细表里给出实付金额、实收金额、申购金额、赎回金额等列那你就不需要自己从原始流水里聚合了有的赛题则只给余额快照需要你从“今天余额相对昨天余额的变化 当日交易行为”去反推流入流出。如果是后者理解工作量会大很多你需要在心里模拟一遍资金的流转过程。2.3 宏观参考数据表外部变量如何与用户行为对齐宏观参考数据表在大多数教程里存在感很低但它往往是拉开名次的关键。它描述的是外部金融环境随时间的变化比如不同期限的利率报价。为什么这东西和用户的资金流入流出有关思路很简单当市场利率走高时用户更愿意把钱留在平台里买短期理财流入增加、流出减少当利率走低时资金可能外流到其他渠道。在赛题理解阶段你要确认宏观数据表的时间粒度和覆盖范围和用户余额表是否对齐。通常它只有每天一条记录粒度比用户级细不少因此在使用时需要做广播式的关联同一日期下所有用户共享同一个宏观指标值。这个操作很简单但很多人在特征阶段忘了它白白浪费了一个提前注入外部信息的窗口。另外一个容易踩的点是宏观数据的“时间对齐方向”你只能用预测时刻之前已知的宏观数据来预测未来不能把未来某个时间的宏观数据也放进特征里否则就构成了时序穿越。这个问题的本质将在后面专门展开。2.4 关联键与时间对齐三张表怎么挂接把三张表关联起来是赛题理解的标志性动作。用户信息表和余额明细表通过用户ID关联这是最常见的等值连接。宏观数据表和余额明细表通过日期关联。具体操作上我建议先做三个确认用户ID在两张表里的唯一性用户表里一个ID只出现一次吗余额表里一个ID一天只出现一次吗日期范围是否严格一致三张表的覆盖范围有没有错位比如余额表从1月到8月但宏观表从1月到9月多出的月份没有用户数据直接关联不会报错但会产生一堆无效行。用户出现频率的分布有的用户可能只出现几天就流失了有的用户出现几百天。出现天数极少的用户样本在建模时是保留还是剔除需要提前有策略。做完这三个确认你手上就有了一个干净的、可按时间对齐的数据主表后面所有特征工程都在这张主表基础上展开。这一步看似机械却决定了后面有多少时间花在调试看不见的脏数据上。3. 资金流水的统计语义流入、流出与平台内部资金转移的区分3.1 哪些行为算流入哪些行为算流出赛题数据不会直接告诉你“这笔算流入那笔算流出”但数据字典里的行为类型字段会给你线索。以常见的支付平台场景为例行为类型对平台总盘子来说对单个用户来说银行卡充值到余额资金流入流入余额付款给平台商家资金流向商家未流出平台流出商家提现到银行卡资金流出平台流出用户A转账给用户B内部转移总量不变A流出、B流入申购理财产品资金从余额进入理财子账户总量不变流出余额减少理财产品赎回资金从理财回到余额总量不变流入余额增加如果你要预测的是平台总资金池的流入流出那么真正算数的只有“充值”和“提现”这一类和银行账户发生交互的行为用户之间的转账、余额和理财之间的划转都不应该计入。但如果你要预测的是每个用户个体的流入流出那么转账、申购、赎回全部要算进去。赛题理解阶段最怕的就是想当然地把“所有金额变动都当作流入流出”。我在第一次做类似赛题时因为想偷懒直接用了余额表里“当日余额相对昨日的变化”当作流入流出。当时看着训练集上拟合得很好直到做时间漂移分析才发现余额变化反映的是净额变动而不是流入流出总量。举个极端例子一个用户当天先充值100元、再提现100元流入流出各100元但余额净变化是0。用净额做目标等于把一个资金活跃的用户识别成了没有行为的静默用户整个建模逻辑直接崩了。确认目标口径之后我把所有涉及内部转移的行为重新分类统计模型的效果才开始正常。3.2 净额预测和总额预测是完全不同的任务这个问题值得单独强调。净额等于流入减流出预测净额往往比预测流入、流出各自的值要简单因为内部抵消掉大量噪声。但赛题如果要求你交流入和流出两个目标你用净额做中间变量再拆很容易出现“净额对了但总额错得离谱”的情况。原因在于净额预测只学到了一个压缩后的信号丢失了流入和流出各自的量级信息。举例来说某天平台做大型促销充值流入暴增提现流出也暴增净额和平时差不多但总额翻了好几倍。如果模型只见过净额训练它根本不知道“暴增”这件事发生了。所以只要赛题目标包含总额就必须分开建模或设计多输出的结构尽量让模型看到流入和流出各自的变化规律。还有一个比口径更现实的坑流入和流出不是独立的。用户的资金是有限的在某个时间内大量流入往往意味着未来的流出也会增加比如用户在月初发工资后充值月末消费后提现这种时间上的相关性是特征工程的重要来源。在赛题理解阶段至少要形成“流入流出有滞后相关性”的初步判断后续做特征时主动构造跨期统计量去捕捉这种关系。3.3 用户级汇总与平台级汇总的建模视角差异还要想清楚一个层次问题数据是用户级的预测目标是平台级的这两者之间的桥怎么搭常见做法有两种。第一种是“自下而上”先预测每个用户的日流入流出再对所有用户求和得到平台总量。这种方法理论最自然但误差会随用户规模放大而且对每个用户单独建模的成本很高通常需要对用户分群后再按群体预测。第二种是“自上而下”把用户级数据聚合成平台级日序列然后直接对平台总量做时间序列预测或回归预测。这种做法简单、稳定被绝大多数队伍采用但它丢失了个体层面的多样性特征。实际竞赛中比较稳的策略是折中按用户重要程度分层对头部用户单独建模预测长尾用户做聚合预测最后相加。我建议赛题理解阶段先不要纠结采用哪种策略而是先确认提交格式允许哪种粒度。如果提交格式本身要求用户级的预测结果那别无选择只能“自下而上”如果提交的只有平台级别的总量你可以自由地选择任意策略。这个看似和模型无关的信息往往决定了整个项目的复杂度。4. 评估指标与损失函数的映射MSE不等于直接回归金额4.1 常见指标的计算方式与直觉含义这类资金流预测赛题最常见的评价指标是均方误差MSE。它的计算方式是对每个预测日期把预测的流入金额、流出金额和真实金额做差、平方、取平均。均方误差天然对“大金额样本”极其敏感这意味着在比赛初期谁能把金额量级大的日期预测准谁的分数就会有质的提升。我见过很多选手花大力气优化平均绝对误差MAE类的损失结果排名纹丝不动原因就是评价指标是MSE而他们用的是MAE。两者的最优解不同MAE倾向于逼近中位数MSE倾向于逼近均值在资金分布严重右偏的数据里这个差别会被放大。建议动手建模前先写一个简单的评估函数输入预测结果和真实结果输出官方口径的分数之后每次迭代都用它而不是用模型自己的loss去判断好坏。4.2 金额的偏态分布与对数变换的必要性资金流入流出的分布通常极度偏态大部分日期金额在较低水平波动少数日期出现高峰值。如果直接对这种目标做MSE回归模型会被少数极高值日期牵着走为了压低那几个点的大误差不惜牺牲大部分普通日期的预测精度。解决思路很成熟对目标做对数变换或在变换之前先加一个常数比如log(y 1)。取完对数之后原来相差十倍的金额变成相差两倍多高峰值不再主导损失函数模型能把更多精力放在拟合日常规律的细节上。提交之前再做反向变换还原成原始金额即可。另一个常见方案是用tanh或sigmoid把目标压缩到有限区间再对压缩后的目标做回归。这种变换适合金额存在明显上下界的场景。选择哪种变换取决于你数据里高峰值的密度如果高峰值频率很高选择log变换更稳如果只有屈指可数的一两次极端事件我反而建议保留原始MSE因为这些极端日期是硬性得分点压过头了会导致整体分数变差。4.3 从指标倒推预处理方案加一、截断与离群值策略指标理解还要落到预处理的具体选择上。MSE对“大而准”的权重极高这启示我们几个处理方向极端值要不要平滑对目标做截断比如把超过99.5%分位数的值直接截断到分位数值能稳定训练过程但要控制在一个较小幅度内否则预测结果的天花板会被压低。训练权重是否要调整既然MSE对高峰值敏感在自定义损失时可以考虑按目标量级加权训练让模型更关注大金额样本。很多框架的采样器可以直接按样本量级排序采样实现成本很低。反向变换的偏差修正如果用了log变换训练出的模型在预测值上的期望是E[log(y)]直接exp回去得到的是几何均值相关的结果通常会低估实际均值。常见做法是把还原值乘以一个修正系数系数在验证集上拟合即可。这些方法论层面的东西必须在赛题理解阶段就定下来。我见过有人所有特征都做完了才发现指标理解错了被迫重新生成目标变换结果所有特征的统计口径都得跟着重算一周的活白干。5. 从赛题理解直接推导的第一版特征与建模思路5.1 时间窗口聚合过去7天、14天、30天的统计量赛题理解如果到位第一版特征几乎是顺势而来的。既然目标是某天或未来某段时间的资金流入流出那最直接的特征就是过去若干天内的流入流出统计量近7天流入总和、近14天流出均值、近30天流入标准差、近N天流入流出的相关系数等等。这些特征是时序预测的基石背后逻辑是资金行为有很强的惯性——昨天流入了很多今天大概率不会突然归零。窗口长度怎么选有人习惯拍脑袋选7、14、30也可以根据数据本身的周期性来定。具体做法是用训练集前一段数据画出日度流入流出的自相关折线看它衰减到第一次明显谷底的位置那个位置附近就是合适的窗口下限。如果发现7天周期性明显至少要用到14天的窗口才能覆盖完整周期加一个小缓冲。窗口太长会把太久远的信息也搅拌进来反而稀释了近期趋势。5.2 周期性与趋势特征星期几效应、节假日与月度节奏资金行为有明显的日历周期性。举个例子多数用户周末更倾向于消费而不是理财工作日的流入流出形态和工作日的形态差异显著每月月底和月初往往是工资发放和信用卡还款的高峰资金流动量级明显高于月中。因此赛题理解阶段就要把以下特征列入计划当前日期的星期几、是否月初、是否月末、是否季度末。距离上一个/下一个特殊时间点的天数比如距离月末还有几天。历史同期均值去年同月、上周同期、上月同日的流入流出量。连续工作天数或连续休息天数节假日邻近程度。这类特征做起来非常快但对分数的影响往往立竿见影。我在类似赛题里曾经只用“星期几 月份”两个类别特征加上一个月的历史均值就把一个未调参的XGBoost基线分数拉到了排行榜中游可见周期性信息在这个问题里的分量有多重。5.3 时间序列基线朴素预测、移动平均与加权历史均值在进入复杂模型之前务必建立一个时间序列基线。最简单的是朴素预测用昨天的值预测明天。更好一点的是移动平均平滑预测用过去N天的均值预测未来。再进一步可以引入指数加权移动平均给近期数据更高权重对趋势和周期变化反应更灵敏。为什么在赛题理解阶段就要做基线因为只有跑通一个简单基线你才有一个可信的参考线。后面所有复杂模型的提升都要以超越这个参考线为最低标准。我有一次在某个时序赛题里精心调整的深度模型居然打不过简单的按星期几分组的均值预测排查了半天才发现是训练集和验证集的切分方式出了问题导致模型看到了未来信息但在实际预测场景里失效。没有基线对比这个问题根本不会被发现。5.4 特征验证的简单规则切分不能只看随机比例有了特征之后怎么验证特征有没有效第一版特征做完先不要着急上复杂模型用线性回归或决策树在小验证集上看特征重要性排序然后把不重要的特征逐批移除观察验证分数变化。这个“减法调试”的思路在赛题初期比“加法堆料”有效得多。但这里有一个前提你的验证集切分方式必须正确。在时序类赛题中绝不能随机打乱数据后按比例切分那样会人为制造未来信息泄漏。正确的做法是按时间顺序用前70%或75%时间段的数据训练用最后的时间段做验证如果你想模拟真实比赛中的“预测未来窗口”验证集位置要更靠后紧跟训练集之后且连续覆盖。6. 赛题理解阶段最容易踩的坑时序穿越、数据缺失与提交格式错位6.1 训练集和验证集切分的时序陷阱上面提到的切分问题属于资金预测赛题里最高发的坑值得展开讲。很多人习惯性用train_test_split按随机比例切分这在普通结构数据上没问题但在时间序列数据上是灾难。举例说明训练集包含1月到6月的数据验证集随机抽取了其中一些日期包括5月15日。那么你在训练时可用的特征可能来自5月16日之前的所有历史窗口其中就包含5月15日当天的信息。模型通过某种特征隐含地“记住”了5月15日的真实标签再拿5月15日做验证得分自然虚高。等到了真正提交时预测对象是未来完全看不到的日期模型根本没有可记忆的信息成绩就会断崖式下跌。正确的做法是从开始就坚持按时间切分训练集取前80%的时间区间验证集取后20%的时间区间中间留一段空隙防止窗口特征泄漏。如果赛题要求预测7月1日到7月14日那你验证集最好就是6月1日到6月14日或6月20日到7月3日这类紧邻的区间让验证尽可能贴近真实预测场景。6.2 能否用“当天数据”预测“当天目标”另一个高频错误是训练样本的特征里包含了当天的信息。例如预测7月5日的资金流入流出却在特征里用了7月5日当天的余额变化或行为汇总。这在构建训练集时看起来很正常因为训练数据里“当天”的标签本来就和当天行为同一天但到了实际预测阶段你不知道未来那天的行为数据特征构建不出来训练与预测完全不一致。规避方法很简单构造特征时所有统计量一律使用“截至预测日前一天”的数据。习惯养成之后你会发现自己在数据处理阶段就会自动把日期偏移一天而不是等到模型跑完再来回改。这条规则怎么强调都不为过它甚至比模型选型和参数调优更影响最终成绩。6.3 数据缺失与假期对齐问题资金数据往往存在天然缺失平台早期用户少每天记录不满某些日期因维护或故障没有产生记录不同用户在不同时间注册导致历史窗口长度不一致。处理这些缺失时不要把“缺失”机械地填成0因为0在资金场景里是有意义的——用户确实没有任何资金行为。你需要区分“没有数据”和“数据为0”分别用特征值-1、0和实际数值来标记。节假日对齐也是一个隐蔽问题。传统节假日和周末的资金行为规律完全不同如果只用“星期几”做特征无法区分普通周末和长假期周末。建议构造一个额外的“临近节假日”特征比如“未来三天内是否是节假日”“距离上次节假日结束过几天”这些特征能有效捕捉假期前后用户资金调动的脉冲现象。6.4 提交格式与预测天数错位最后一个不起眼却致命的坑最后提醒一个非常低级但每年都有队伍踩的问题提交格式里的日期范围和预测目标顺序与官方要求不一致。有些队伍在本地验证得很好却在提交时发现行列错位直接得零分。赛题理解阶段结束前至少要做一次真实的提交测试构造一个全零的或基线预测的文件跑通提交流程确认格式无误后再开始真正的建模工作。这一步花不了半小时却能为整个比赛周期省下大量为格式问题焦虑的时间。我对资金流入流出这类赛题最深的体会是赛题理解不是简单的“读题”而是把业务、数据、评价指标和时间结构四样东西在脑子里完成闭环。目标口径没锁死后面所有工作都可能是白费指标理解不到位模型优化方向就会跑偏时序切分不严谨验证分数再高也只是自欺欺人。把这几个基础打扎实之后进入特征工程和建模调参阶段你才有底气说每一步改进都是真实的提升。下一篇我会接着写该赛题的特征工程细节重点讲讲如何从余额明细表里构造出真正有效的时序特征以及怎样用简单的验证方法快速筛选特征。如果你按这篇的思路把赛题理解部分过了一遍那下一篇的内容你会吸收得轻松很多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑