2. 时间滑窗特征:滚动窗口统计量的构建与陷阱

时间滑窗特征,说白了就是「用过去一段时间的表现,来预测未来」。这在金融风控里太常见了——比如用过去3个月的消费均值,来判断用户当前的还款能力。

但我得说,这个看似简单的操作,坑特别多。我在项目中见过太多人,窗口一滑,模型就崩了。今天咱们就把它掰开揉碎了讲清楚。

2.1 滚动窗口统计量:到底在算什么?

先看一个最基础的场景。假设你有用户每天的消费金额,想算过去7天的平均消费。

import pandas as pd
import numpy as np

# 模拟数据
df = pd.DataFrame({
    'user_id': ['A'] * 10,
    'date': pd.date_range('2024-01-01', periods=10),
    'amount': [100, 200, 150, 300, 250, 400, 350, 500, 450, 600]
})

# 7天滚动均值
df['amount_ma7'] = df['amount'].rolling(window=7).mean()
print(df[['date', 'amount', 'amount_ma7']])

输出结果里你会发现,前6天都是NaN。为什么?因为数据不够7天。这个细节很多人会忽略。

核心统计量有哪些?

  • 均值:最常用,反映平均水平。但容易被极端值拉偏。
  • 最大值/最小值:捕捉极端行为。比如突然的大额消费,可能意味着风险。
  • 标准差:衡量波动性。波动越大,不确定性越高。
  • 趋势:比如用线性回归的斜率,或者简单的前后差值。

2.2 趋势特征的构建:不只是算个斜率

我个人习惯用两种方式构建趋势特征。

方法一:差分法

最简单,就是当前值减去N天前的值。比如「今天消费 - 7天前消费」,正数表示上升趋势。

df['amount_diff7'] = df['amount'] - df['amount'].shift(7)

方法二:线性回归斜率

更稳健,但计算量也大。用过去N天的数据拟合一条直线,斜率就是趋势。

from scipy import stats

def calc_slope(series):
    if len(series) < 2:
        return np.nan
    x = np.arange(len(series))
    slope, _, _, _, _ = stats.linregress(x, series)
    return slope

df['amount_slope7'] = df['amount'].rolling(window=7).apply(calc_slope)

我的经验:差分法适合短期趋势,斜率法适合中期趋势。在信贷场景里,我通常用差分法做「突变检测」,用斜率法做「持续恶化判断」。

2.3 那些年我踩过的坑

嗯,这里要重点说。时间滑窗特征看着简单,但陷阱一个比一个隐蔽。

陷阱一:数据泄露

这是最致命的。我曾经犯过一个错——用整个数据集算滚动均值,结果把未来的信息带到了过去。模型在训练集上表现完美,一上线就崩了。

正确的做法:按时间顺序分组,每个样本只能用它之前的数据

# 错误做法:全局滚动
df['amount_ma7_wrong'] = df['amount'].rolling(window=7).mean()

# 正确做法:按用户分组,且保证时间顺序
df['amount_ma7_correct'] = df.groupby('user_id')['amount'].transform(
    lambda x: x.rolling(window=7, min_periods=1).mean()
)

陷阱二:窗口边界效应

窗口刚启动时,数据不够。很多人直接填0或者均值,这其实是在「创造假数据」。我建议用min_periods参数控制最少需要多少数据,不够的就设为NaN,后续用缺失值处理。

陷阱三:时间间隔不均匀

用户不是每天都消费。如果直接用7天窗口,可能实际只用了3天的数据。这时候要用「日历窗口」而不是「数据点窗口」。

# 日历窗口:按实际天数滚动
df.set_index('date', inplace=True)
df['amount_cal_ma7'] = df['amount'].rolling('7D').mean()

2.4 多窗口策略:别只用一个窗口

你想想看,只用7天窗口够吗?不够。短期波动和长期趋势要分开看。

我一般会构建3个窗口:

窗口类型 窗口大小 捕捉的信号
短期 3天 / 7天 近期突变、临时行为
中期 30天 月度消费习惯
长期 90天 / 180天 稳定行为模式

然后可以算「短期均值 / 长期均值」这样的比率特征。如果短期突然远高于长期,说明用户行为发生了异常变化。

2.5 知识体系总览

下面这张图,是我自己总结的时间滑窗特征构建逻辑。你看一眼就明白了。

时间滑窗特征构建逻辑 原始时序数据 基础统计量 趋势特征 多窗口融合 均值 最大/最小 差分法 斜率法 短期+中期+长期 比率 ⚠️ 三大陷阱 数据泄露 | 窗口边界效应 | 时间间隔不均匀

2.6 实战建议:怎么选窗口?

说实话,没有标准答案。但我给你一个经验法则:

  1. 业务周期:如果用户是月薪制,30天窗口是必须的。如果是日结工,7天就够了。
  2. 数据密度:数据稀疏的用户,窗口要拉大。数据密集的,窗口可以缩小。
  3. 模型需求:树模型对特征尺度不敏感,窗口大小可以随意些。线性模型则要小心,窗口太小噪声大,窗口太大信号滞后。

我的小技巧:先做一次特征重要性分析,看看哪个窗口的贡献最大。然后围绕那个窗口,再微调大小。别一上来就搞十几个窗口,计算资源扛不住,模型也容易过拟合。

好了,时间滑窗特征就讲到这里。记住一句话:窗口是工具,不是目的。别为了做特征而做特征,要想清楚每个窗口到底在捕捉什么行为信号。

专注资料整理