3. 数据获取与预处理:金融数据源(FRED、Tushare、Yahoo Finance)、数据清洗、缺失值处理、异常值检测
做利率预测,说白了就是跟数据打交道。我见过太多人模型调得飞起,结果数据一塌糊涂,最后全白干。这一章咱们就聊聊数据从哪来、怎么洗、怎么补、怎么排雷。嗯,都是我在项目里踩过的坑,你听听看。
3.1 金融数据源:三个常用渠道
我个人习惯把数据源分成三类:宏观数据、国内行情、国际行情。分别对应FRED、Tushare和Yahoo Finance。别贪多,一个场景用一个就够了。
3.1.1 FRED(联邦储备经济数据)
FRED是美联储官方的数据仓库。利率预测嘛,联邦基金利率、国债收益率、CPI这些核心指标都在这。我建议你直接注册个API Key,免费又好用。
核心数据字段:
DFF:联邦基金有效利率(日频)DGS10:10年期国债收益率CPIAUCSL:消费者价格指数(月频)UNRATE:失业率(月频)
# 获取FRED数据示例
import pandas as pd
from fredapi import Fred
fred = Fred(api_key='你的API_KEY')
data = fred.get_series('DFF', start_date='2000-01-01')
print(data.head())
我的经验:FRED的数据频率不统一。日频、月频、季频混在一起。我一般先统一重采样到日频,再往下做。不然模型会莫名其妙地报错。
3.1.2 Tushare(国内金融数据)
做国内利率预测,Tushare是绕不开的。Shibor、LPR、国债期货这些数据它都有。不过要注意,Tushare的积分制有点坑,免费用户能拿到的数据有限。
import tushare as ts
ts.set_token('你的TOKEN')
pro = ts.pro_api()
# 获取Shibor数据
shibor = pro.shibor(start_date='20200101', end_date='20231231')
print(shibor.head())
避坑指南:我曾经因为Tushare的接口返回格式变了,导致整个数据管道崩了。建议每次调用后都检查一下返回的列名和数据类型,别偷懒。
3.1.3 Yahoo Finance(国际行情)
Yahoo Finance适合拿国际利率数据,比如美国国债、欧元区利率。用yfinance库很方便,但要注意它有时候会断连。
import yfinance as yf
# 获取10年期美国国债收益率
tnx = yf.download('^TNX', start='2020-01-01', end='2023-12-31')
print(tnx.head())
3.2 数据清洗:别让脏数据毁了模型
数据清洗听着简单,做起来全是细节。我总结了三步:去重、对齐、格式化。
3.2.1 去重与对齐
金融数据经常有重复行,尤其是跨数据源合并的时候。我习惯用drop_duplicates()先清一遍,再用merge()按日期对齐。
# 去重
df = df.drop_duplicates(subset=['date'])
# 按日期对齐
merged = pd.merge(df1, df2, on='date', how='outer')
3.2.2 格式化问题
日期格式不统一是常见坑。FRED用YYYY-MM-DD,Tushare用YYYYMMDD,Yahoo Finance又不一样。我统一转成datetime类型。
df['date'] = pd.to_datetime(df['date'])
df = df.sort_values('date')
3.3 缺失值处理:补还是不补?
利率数据缺失很常见。节假日、数据发布延迟都会导致空值。我个人习惯分情况处理。
| 缺失比例 | 处理方法 | 适用场景 |
|---|---|---|
| < 5% | 前向填充(ffill) | 日频利率数据 |
| 5% - 20% | 线性插值 | 月频宏观数据 |
| > 20% | 删除该特征 | 质量太差的数据 |
# 前向填充
df['rate'] = df['rate'].ffill()
# 线性插值
df['rate'] = df['rate'].interpolate(method='linear')
我的建议:别一上来就用均值填充。利率数据有很强的时序性,均值填充会破坏趋势。前向填充是最安全的。
3.4 异常值检测:揪出那些离谱的数据
异常值在利率数据里很要命。一次错误的报价、一次系统故障,都可能让模型学歪。我常用的方法有两种。
3.4.1 基于统计的方法
Z-score方法简单粗暴。超过3个标准差的,我一般标记为异常。
from scipy import stats
z_scores = np.abs(stats.zscore(df['rate']))
df['is_outlier'] = z_scores > 3
3.4.2 基于IQR的方法
IQR(四分位距)对极端值更鲁棒。我更喜欢用这个,尤其是利率数据有厚尾特征的时候。
Q1 = df['rate'].quantile(0.25)
Q3 = df['rate'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
df['is_outlier'] = (df['rate'] < lower_bound) | (df['rate'] > upper_bound)
避坑指南:我曾经在2008年金融危机数据里用Z-score,结果把真实的利率飙升当成了异常值全删了。后来模型预测效果极差。记住:异常值不一定是错误,可能是市场信号。处理前一定要结合业务背景判断。
3.5 知识体系总览
下面这张图是我自己总结的数据获取与预处理流程。你照着走,基本不会出大问题。
你看,整个流程其实不复杂。但每一步都马虎不得。数据源选对了,清洗做干净了,缺失值和异常值处理得当,后面的模型训练才能顺风顺水。
核心要点回顾:
- FRED适合宏观利率数据,Tushare适合国内,Yahoo Finance适合国际
- 数据清洗三件套:去重、对齐、格式化
- 缺失值处理:前向填充最安全,别乱用均值
- 异常值检测:结合业务背景,别一刀切