4、缺失值处理:缺失值类型与处理方法
做金融时间序列分析,缺失值是个绕不开的坎。
我刚开始做量化策略时,拿到一份日频收益率数据,心想直接跑模型吧。结果一跑,报错。一看数据,中间缺了三天。嗯,这就是典型的缺失值问题。今天咱们就把这块彻底讲透。
4.1 缺失值的三种类型
搞懂缺失值的类型,比学会插补方法更重要。为什么?因为不同类型,处理策略完全不同。
我个人习惯把缺失值分成三类:
| 类型 | 全称 | 通俗理解 | 金融场景举例 |
|---|---|---|---|
| MCAR | 完全随机缺失 | 缺失纯属偶然,跟数据本身无关 | 某天交易所系统故障,所有股票都缺数据 |
| MAR | 随机缺失 | 缺失跟其他变量有关,跟自身无关 | 小市值股票更容易缺失流动性数据 |
| MNAR | 非随机缺失 | 缺失跟自身取值有关 | 收益率特别低的股票,主动不披露数据 |
核心判断标准:缺失的原因是否与缺失值本身有关。有关就是MNAR,无关就是MCAR或MAR。
我在项目中遇到过最头疼的就是MNAR。比如某只债券连续几天没有成交价,你以为只是流动性差,其实是因为它要违约了,没人敢交易。这种缺失,你插补出来的值全是错的。
4.2 删除法:简单粗暴,但有代价
删除法是最直接的方法。说白了就是「眼不见为净」。
行删除
把包含缺失值的整行删掉。适用于MCAR场景,且缺失比例很小(比如5%以内)。
# 行删除示例
df_clean = df.dropna() # 删除所有含缺失值的行
print(f"删除前:{len(df)}行,删除后:{len(df_clean)}行")
注意:金融时间序列中,行删除可能导致时间不连续。比如你删掉某天的数据,后续的滞后特征计算就全乱了。
列删除
如果某一列缺失太多(比如超过50%),我建议直接删掉这列。留着也是鸡肋。
# 列删除示例
threshold = 0.5 # 缺失比例阈值
df_clean = df.loc[:, df.isnull().mean() < threshold]
我曾经处理过一份300只股票的日频数据,其中一只股票有80%的数据缺失。我当时犹豫要不要保留,后来发现这只股票已经退市了。嗯,果断删掉。
4.3 插补法:更精细的处理方式
删除法太浪费数据了。金融数据本来就贵,删了心疼。所以大多数时候,我们选择插补。
均值/中位数插补
最简单的插补方式。用该列的均值或中位数填充缺失值。
# 均值插补
df['close'].fillna(df['close'].mean(), inplace=True)
# 中位数插补(更稳健,适合有异常值的情况)
df['close'].fillna(df['close'].median(), inplace=True)
我的建议:金融数据通常有尖峰厚尾特征,中位数比均值更靠谱。比如某只股票突然暴涨10倍,均值会被拉高,但中位数不受影响。
前向填充与后向填充
时间序列特有的插补方式。用上一个或下一个有效值填充。
# 前向填充:用上一个值填充
df['close'].fillna(method='ffill', inplace=True)
# 后向填充:用下一个值填充
df['close'].fillna(method='bfill', inplace=True)
前向填充在金融中很常用。比如股票停牌一天,复牌后价格通常沿用停牌前的收盘价。但要注意,如果连续缺失太多天,前向填充会引入偏差。
避坑指南:我曾经用前向填充处理过连续10天的缺失数据,结果模型训练出来全是错的。后来发现那10天发生了重大政策变化,前向填充完全忽略了市场突变。
线性插值
假设缺失值前后是线性关系,用直线上的点来填充。
# 线性插值
df['close'].interpolate(method='linear', inplace=True)
线性插值比前向填充更平滑。适合处理收益率、波动率这类连续变化的指标。但如果是跳跃性数据(比如突然的涨跌停),线性插值就不太合适了。
KNN插补
用K个最相似的样本的均值来填充。这是机器学习的方法,效果通常更好。
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=5)
df_imputed = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)
KNN插补的优点是能利用多个维度的信息。比如某只股票缺失了收盘价,但它的成交量、开盘价、行业指数都正常,KNN就能通过这些信息推断出合理的收盘价。
选择建议:
- 缺失比例<5%:行删除或均值插补
- 缺失比例5%-20%:前向填充或线性插值
- 缺失比例>20%:KNN插补,或考虑列删除
- MNAR类型:不要插补,先分析缺失原因
4.4 知识体系总览
下面这张图,是我梳理的缺失值处理全流程。你保存下来,以后遇到缺失值问题,照着走就行。
这张图的核心逻辑很简单:先判断类型,再选方法。MCAR和MAR可以放心处理,MNAR要格外小心。
最后说一句:没有万能的方法。我每次处理缺失值,都会先画个缺失值分布图,看看缺失模式。有时候缺失值本身就在告诉你一些信息——比如某只股票频繁缺失数据,可能意味着它流动性差,或者有潜在风险。
公众号:蓝海资料掘金营,微信deep3321