数据清洗与预处理:缺失值处理、异常值检测、收益率计算

数据清洗,说白了就是给原始数据「洗澡」。我做了这么多年风控,见过太多因为数据没洗干净导致模型翻车的案例。你想想看,如果输入的数据都是脏的,再牛的模型也白搭。这一节,咱们就聊聊VaR建模前必须做的三件事:缺失值处理、异常值检测、收益率计算。

一、缺失值处理:别让「空」坑了你

金融数据里,缺失值太常见了。停牌、节假日、数据源故障,都会导致某天没有价格。我个人习惯,拿到数据第一件事就是检查缺失情况。

核心原则: 缺失比例低于5%可以填充,超过20%建议直接剔除该序列。

常见处理方法

方法 适用场景 我的经验
前向填充(ffill) 日频数据,短期缺失 最常用,用上一个交易日价格填充
线性插值 收益率曲线构建 适合连续型数据,但别用在波动率上
删除缺失行 缺失比例极低 简单粗暴,但会损失样本量

我在项目中遇到过一只股票连续停牌5天,直接前向填充后,VaR值被严重低估。后来我改用「市场指数收益率+个股beta」来估算缺失日的收益率,效果好了很多。

小技巧: 处理前先画个缺失值热力图,一眼就能看出哪些时间段、哪些资产问题最大。

二、异常值检测:揪出那些「离谱」的数据

异常值是什么?就是那些明显不符合市场规律的数据点。比如某股票一天涨了1000%,或者某汇率突然跳了50个基点——这通常是数据录入错误,不是真实市场行为。

我常用的检测方法有三种:

  1. Z-score方法:计算每个数据点与均值的偏离程度,超过3倍标准差就标记为异常。适合正态分布的数据。
  2. IQR方法:用四分位距来识别。低于Q1-1.5*IQR或高于Q3+1.5*IQR的,都算异常。这个方法对极端值更稳健。
  3. 百分比截尾法:直接去掉前后各1%的数据。简单,但可能误删有效信息。
注意: 金融数据往往有厚尾特征,Z-score方法容易把真实的市场极端波动误判为异常。我曾经因为这个原因,把2008年金融危机期间的真实暴跌数据给删了,结果回测出来的VaR值完全失真。

我的建议是:先用IQR方法做初步筛选,再结合业务逻辑人工复核。比如某天收益率超过±20%,你得问问自己——这天是不是有重大事件?如果是,保留;如果是数据错误,删除或修正。

三、收益率计算:对数收益率 vs 简单收益率

这是VaR建模最基础的一步,也是很多人容易搞混的地方。咱们直接上代码。

import pandas as pd
import numpy as np

# 假设我们有收盘价数据
prices = pd.Series([100, 102, 101, 105, 107])

# 简单收益率
simple_returns = prices.pct_change().dropna()
# 结果: [0.02, -0.0098, 0.0396, 0.0190]

# 对数收益率
log_returns = np.log(prices / prices.shift(1)).dropna()
# 结果: [0.0198, -0.0099, 0.0388, 0.0188]

看到区别了吗?数值上很接近,但数学性质完全不同。

为什么我偏爱对数收益率?

  • 时间可加性:对数收益率可以直接相加得到多期总收益率。简单收益率不行,你得用连乘。
  • 近似正态分布:对数收益率更接近正态分布,这对VaR的参数法建模非常友好。
  • 数值稳定性:对数收益率的值域是(-∞, +∞),不会出现简单收益率那种「跌到-100%就卡住」的问题。
一句话总结: 做VaR建模,用对数收益率。做投资组合业绩归因,用简单收益率。各有所长。

嗯,这里要注意一点:当收益率很小时(比如日频数据),两者几乎没区别。但如果你做的是周频或月频数据,差异就会变大。我习惯在日频上用对数收益率,在报告最终结果时再转换回简单收益率,这样既保证了建模的数学严谨性,又方便业务人员理解。

四、完整的数据清洗流程

下面这张图是我做VaR项目时常用的数据预处理流程,你可以参考。

数据清洗与预处理流程图 原始价格数据 缺失值检测与处理 缺失率 < 5%? 前向填充/插值 剔除该序列 异常值检测与修正 计算对数收益率 清洗后的收益率序列

这个流程我用了很多年,基本没出过大问题。核心就一句话:先处理缺失,再处理异常,最后算收益率。顺序不能乱,否则异常值检测会被缺失值干扰,收益率计算也会被异常值带偏。

避坑指南: 我曾经在计算对数收益率时,忘了先检查价格数据里有没有0值。结果log(0)直接报错,整个脚本崩了。所以记得先过滤掉价格为0的样本。

好了,数据清洗这块就聊到这儿。你把这些步骤跑通,VaR建模的基础就打牢了。下一节咱们会基于清洗好的数据,正式进入VaR参数估计环节。


公众号:蓝海资料掘金营,微信deep3321