多因子模型水平测试题 模型拟合 解答
核心环节(数据处理、因子选择/合并、模型拟合、预测、组合构建、回测评估)都不能省略。单因子测试可以看作因子筛选的一部分,交易成本预测可以简化但最好包含。
好的,我们来继续探讨多因子模型“模型拟合”部分的深入问题。
目录
- 2. 模型拟合 (Model Fitting)
- 2.1 多因子模型拟合的综合目标
- 2.2 样本空间选择与异常处理
- 2.3 因子组选择与经典理论
- 2.4 多因子策略回测流程环节
- 2.5 因子暴露预处理的必要性与后果
- 2.6 离群值处理方法与参数选择
- 2.7 缺失值处理方法比较
- 2.8 标准化方法、效果与利弊
- 2.9 带权重的标准化
- 2.10 预处理步骤的先后顺序
- 2.11 因子正交化的影响与理由
- 2.12 截面回归频率的选择
- 2.13 个股收益率计算方法
- 2.14 回归模型截距项的选择
- 2.15 OLS 与 WLS 回归的区别与依据
- 2.16 多因子模型效果评估
- 2.17 判断因子解释力是否足够
- 2.18 A股多因子模型 R² 量级
- 2.19 过多因子的潜在问题
- 2.20 拒绝高 R² 贡献因子的理由
- 2.21 面板回归在因子测试中的适用性
- 2.22 共线性与异方差检验及解决
- 2.23 无风险资产选择 (中国市场)
- 2.24 Beta 基准选择及其影响
- 2.25 线性模型主导与非线性探索
- 2.26 数据挖掘与过拟合问题及缓解
2. 模型拟合 (Model Fitting)
2.1 拟合多因子模型的综合目标是什么?
拟合多因子模型的综合目标根据其主要用途有所不同:
-
收益预测 (Alpha 模型):
- 目标: 最大化预测能力。即,构建的模型能够最准确地预测未来一段时期内个股的超额收益率 (Alpha)。
- 侧重点: 因子选择侧重于寻找具有持续预测能力的 Alpha 因子;模型拟合侧重于准确估计这些 Alpha 因子的预期收益 (Factor Return);评估指标侧重于信息系数 (IC)、信息比率 (IR)、因子 t 统计量显著性、模型预测的 Alpha 组合的夏普比率等。
-
风险预测 (Risk 模型):
- 目标: 最大化解释能力和预测稳定性。即,模型能够最大程度地解释历史收益率的波动来源,并准确预测未来投资组合的风险(如波动率、VaR、跟踪误差、Beta)以及资产间的联动性(协方差矩阵)。
- 侧重点: 因子选择侧重于纳入能够广泛解释市场共同波动的风险因子(行业、风格等);模型拟合侧重于准确估计因子暴露度 (Factor Exposure)、因子收益率的波动性 (Factor Volatility) 和因子间的协方差 (Factor Covariance Matrix);评估指标侧重于模型解释力 (R-squared)、预测风险与实现风险的差距、因子协方差矩阵的稳定性等。
-
业绩归因 (Performance Attribution):
- 目标: 准确分解投资组合的历史收益来源。即,将组合的实际收益(或超额收益)清晰地归因于各个因子(市场、行业、风格、Alpha 因子)的暴露以及选股能力(特异收益)。
- 侧重点: 要求模型使用的因子具有清晰的经济含义,因子暴露和因子收益的计算需要与收益预测或风险模型保持一致(取决于归因的目标是解释超额收益来源还是风险来源)。评估指标侧重于归因结果的准确性(归因收益之和 ≈ 实际收益)、残差项(选股能力)的大小和稳定性。
综合来看:
一个理想的多因子模型系统(如果追求统一模型)希望能同时实现:用稳定的风险因子解释大部分共同波动(高 R²),并从中分离出具有持续预测能力的 Alpha 因子(显著的 Alpha 因子收益和高 IR),最终能清晰地将收益分解到各个因子贡献上。但在实践中,针对不同目标优化的模型在因子选择、参数估计方法上可能存在差异。
2.2 如何选择样本空间?例如对初上市股票、ST股票、指数成分股变动、停牌股票等异常情况的处理方法。
选择合适的样本空间(股票池)对模型拟合至关重要,需要仔细处理各种异常情况,避免引入偏差:
-
初上市股票 (IPOs):
- 处理: 通常剔除上市未满一定时间(如 3 个月、6 个月或 12 个月)的股票。
- 原因: 新股上市初期价格波动剧烈,可能受到非市场化定价、炒作、锁定期解禁预期等因素影响,其收益行为与成熟股票不同,且缺乏足够的历史数据(如计算动量因子、波动率因子所需)。
-
ST 股票 / *ST 股票:
- 处理: 通常剔除。
- 原因: ST 股票(Special Treatment)代表公司财务状况异常或存在其他风险警示。其价格行为往往受退市风险、重组预期等特殊因素驱动,与基本面或常规风格因子的关联可能减弱或扭曲。数据质量也可能较差。风险模型有时会考虑纳入 ST 股以覆盖更全风险,但需特殊处理(如单独归类或因子调整)。
-
指数成分股变动:
- 处理: 使用历史成分股。在进行历史回测或模型拟合时,任一时点
t
的样本空间应包含当时该指数实际包含的成分股,而不是使用当前的成分股回溯。 - 原因: 避免前视偏差 (Lookahead Bias)。使用未来才被纳入指数的股票去拟合过去的模型,会错误地假设当时就能预知这些股票未来会“变好”而被纳入。需要动态维护指数的历史成分股列表。
- 处理: 使用历史成分股。在进行历史回测或模型拟合时,任一时点
-
停牌股票:
- 处理:
- 截面回归: 在进行当期截面回归时,剔除当日(或当期)停牌的股票。因为没有当日收益率数据,无法作为回归的因变量。
- 因子暴露计算: 停牌期间的因子暴露度通常保持停牌前最后一天的值不变 (carry forward)。对于需要用到交易量或价格变动的因子(如换手率、波动率),停牌期间这些因子值如何处理需根据因子定义决定(见 1.10)。
- 样本池定义: 是否将长期停牌股票从整个样本池中剔除,取决于模型需求和停牌时长。
- 原因: 停牌股票无法交易,其信息未在价格中反映,将其纳入回归会引入噪声或错误。
- 处理:
-
其他常见处理:
- 剔除 B 股、H 股等非 A 股。
- 剔除上市地点非主板/科创板/创业板的股票(如新三板,取决于研究范围)。
- 剔除某些行业的股票(如金融服务业,因其财务报表结构特殊,因子适用性不同,有时会单独建模或剔除)。
- 设置流动性门槛: 剔除日均成交额过低或流通市值过小的股票,以确保因子有效性可以转化为可投资的策略,并避免低流动性带来的噪声。
- 数据完整性过滤: 剔除关键数据(如市值、收益率、核心因子)缺失的股票。
- Python 代码示例 (基于 pandas 过滤):
import pandas as pd
# 假设 all_stocks_data 是包含所有股票信息的 DataFrame
# 列包括: 'stock_code', 'date', 'list_date', 'is_st', 'is_trading', 'market_cap', 'adj_close', ...
# all_stocks_data['date'] = pd.to_datetime(all_stocks_data['date'])
# all_stocks_data['list_date'] = pd.to_datetime(all_stocks_data['list_date'])
def get_regression_universe(df, current_date, min_list_days=180, exclude_st=True, min_market_cap=1e9):
"""
获取指定日期的回归样本空间
Args:
df (pd.DataFrame): 包含所有股票信息的 DataFrame
current_date (str or pd.Timestamp): 当前截面日期
min_list_days (int): 最短上市天数要求
exclude_st (bool): 是否剔除 ST 股票
min_market_cap (float): 最低市值要求 (示例)
Returns:
pd.DataFrame: 符合条件的当期样本数据
"""
current_date = pd.to_datetime(current_date)
subset = df[df['date'] == current_date].copy()
# 1. 过滤上市日期
subset = subset[(current_date - subset['list_date']).dt.days >= min_list_days]
# 2. 过滤 ST 股票
if exclude_st and 'is_st' in subset.columns:
subset = subset[subset['is_st'] != True] # 假设 is_st 是布尔值
# 3. 过滤当日停牌股票 (假设 is_trading=1 代表交易)
if 'is_trading' in subset.columns:
subset = subset[subset['is_trading'] == 1]
# 或者根据当日收益率是否为 NaN 判断(需要先计算好收益率)
# if 'return' in subset.columns:
# subset = subset[subset['return'].notna()]
# 4. 过滤市值过小的股票 (示例)
if 'market_cap' in subset.columns:
subset = subset[subset['market_cap'] >= min_market_cap]
# 5. 过滤关键数据缺失 (示例:需要有因子暴露 X 和收益率 y)
# subset = subset.dropna(subset=['factor1', 'factor2', 'next_return'])
return subset
# 示例用法
# today = '2023-10-31'
# regression_sample = get_regression_universe(all_stocks_data, today)
# print(f"在 {today}, 有 {len(regression_sample)} 只股票用于回归.")
2.3 如何选取因子组?有什么可以参考的经典理论?【提示:Barra USE3 Handbook】
选取因子组是构建多因子模型的关键步骤,需要平衡理论基础、实证效果、经济直觉和模型目标。
经典理论参考:
-
套利定价理论 (Arbitrage Pricing Theory, APT):
- 核心思想: Ross (1976) 提出,资产的预期收益率由一系列共同的宏观经济因子或统计因子线性决定,加上一个资产特定的误差项。APT 提供了多因子定价模型的理论基础,但未指明具体是哪些因子。
-
Fama-French 三因子 / 五因子模型:
- 三因子 (1993): 市场风险 (Market Beta)、规模因子 (SMB, Small Minus Big)、价值因子 (HML, High Minus Low Book-to-Market)。解释了 CAPM 无法解释的规模效应和价值效应。
- 五因子 (2015): 在三因子基础上增加了盈利能力因子 (RMW, Robust Minus Weak Profitability) 和投资风格因子 (CMA, Conservative Minus Aggressive Investment)。
- 意义: 提供了基于实证和经济逻辑选择系统性风险因子的范例,是学术界和业界的重要基石。
-
Barra 风险模型 (如 USE3, CNE5 等):
- 思路: Barra (现 MSCI Barra) 提供了一套系统化、结构化的风险因子体系,旨在全面捕捉市场风险。其因子库通常包括:
- 国家/市场因子 (Country/Market Factor): 整个市场的系统性风险。
- 行业因子 (Industry Factors): 使用标准行业分类(如 GICS, 或 Barra 自定义)构建虚拟变量因子,捕捉行业层面的共同波动。
- 风格因子 (Style Factors): 捕捉跨行业的、具有相似风险特征的股票群体的表现。常见的风格因子类别(与 1.2 类似):
- 波动率 (Volatility): 如 Beta、历史波动率、残差波动率。
- 动量 (Momentum): 如相对强弱。
- 规模 (Size): 如对数总市值。
- 价值 (Value): 如市净率倒数 (B/P)、预期市盈率倒数 (E/P)。
- 成长 (Growth): 如历史盈利增长、预期盈利增长。
- 盈利能力/质量 (Earnings Yield/Quality): 如 ROE、盈利变动性。
- 杠杆 (Leverage): 如市场杠杆、账面杠杆。
- 流动性 (Liquidity): 如换手率、成交额。
- 意义: Barra 模型提供了一个全面的、层次化的风险因子框架,是商业风险模型的事实标准,其因子分类和选择思路对业界实践影响深远。它强调因子的广泛性、持续性、可投资性、以及相对独立性(低相关性)。
- 思路: Barra (现 MSCI Barra) 提供了一套系统化、结构化的风险因子体系,旨在全面捕捉市场风险。其因子库通常包括:
因子组选取原则:
- 经济意义 (Economic Intuition): 因子应具有合理的经济逻辑或行为金融学解释,说明其为何能解释风险或预测收益。避免纯粹的数据挖掘。
- 实证有效性 (Empirical Evidence): 因子在历史数据中应表现出显著的解释能力(对风险模型)或预测能力(对 Alpha 模型),并且这种效果是稳健的(跨时间、跨市场、对不同定义不敏感)。
- 广泛性 (Pervasiveness): 因子(尤其是风险因子)应能影响大量股票,而不是仅限于少数几只。
- 持续性 (Persistence): 因子的效果应具有一定的持续性,而不是昙花一现。因子本身的定义和暴露度也应相对稳定。
- 可投资性 (Investability): 因子应该是可以实际投资的,即基于该因子构建的组合是可行的(考虑流动性、交易成本等)。
- 低冗余性 (Low Redundancy): 因子组内的因子之间相关性不宜过高,以避免多重共线性问题,并确保每个因子提供相对独立的信息。通常会计算因子相关性矩阵进行检查。
- 数据可用性 (Data Availability): 因子所需的基础数据应易于获取、质量可靠且历史足够长。
选取流程:
- 风险模型: 通常从 Barra 等经典框架出发,选择公认的行业因子和风格因子,并根据特定市场(如 A 股)的特点进行调整(如 A 股特有的 Size 因子强度、波动率因子的重要性)。
- Alpha 模型: 在控制了风险因子后,寻找对残差收益具有预测能力的因子。这通常涉及更广泛的因子挖掘和筛选过程,更强调因子的预测能力指标 (IC, IR) 和与风险因子的低相关性。
2.4 从选择因子到多因子策略回测,一般有哪几个环节?哪些可以省去,哪些不能?【单因子测试(似乎可以省略),合并因子(貌似不能省略,因为不合并相似因子无法消除共线性),预测个股收益率、成本、跟踪误差等,再进行约束优化问题求解】
一个标准的多因子策略(假设是基于因子预测进行组合优化)的回测流程通常包括:
- 因子定义与计算 (Factor Definition & Calculation): 明确每个因子的计算公式,获取所需数据。
- 不能省略。 这是基础。
- 数据预处理 (Data Preprocessing):
- 因子暴露数据清洗: 处理原始因子值的缺失值、离群值。
- 因子标准化: 将不同因子的值转换到可比的尺度上。
- 因子中性化 (可选但常用于 Alpha 因子): 剔除因子中不希望的系统性风险暴露(如行业、市值)。
- 不能省略。 对模型稳定性和有效性至关重要。
- 单因子测试 (Single Factor Test): (可选环节)
- 独立检验每个(或候选)因子的有效性(如 IC、IR、分层回测、因子收益 t 检验)。
- 可以省略,但强烈建议执行。 这是因子筛选和理解因子特性的重要步骤,不做的话风险很大,可能将无效或不理解的因子引入后续流程。其功能可以在因子筛选阶段完成。
- 因子筛选与选择 / 因子合并 (Factor Selection / Combination):
- 筛选: 基于单因子测试结果、因子相关性、经济逻辑等,从候选因子库中选择最终纳入模型的因子组。
- 合并/正交化: 处理因子间的共线性问题。可以通过合并相似因子(如多个价值指标合成为一个综合价值因子)、逐步回归筛选、或因子正交化(如 PCA、序贯正交化)等方法。
- 不能省略。 必须解决因子冗余和共线性问题,否则模型不稳定。是合并还是正交化,取决于模型目标。
- 多因子模型拟合 (Multi-Factor Model Fitting):
- 因子收益率估计 (Factor Return Estimation): 通过截面回归(OLS 或 WLS)估计每个因子在每一期的收益率 (
Y = X*beta + e
中的beta
)。 - 因子协方差矩阵估计 (Factor Covariance Matrix Estimation): 估计因子收益率的协方差矩阵,用于风险预测和优化。可能需要用到风险模型或时间序列平滑技术。
- 特异性风险估计 (Specific Risk Estimation): 估计模型残差(特异收益)的波动率。
- 不能省略。 这是模型的核心,产生后续预测和优化所需的参数。
- 因子收益率估计 (Factor Return Estimation): 通过截面回归(OLS 或 WLS)估计每个因子在每一期的收益率 (
- 收益率与风险预测 (Return & Risk Forecasting):
- 个股预期收益率预测: 结合最新的因子暴露度和(可能经过预测调整的)因子预期收益率,预测个股下一期的收益率 (
Expected Return = Exposure * Expected Factor Return
)。Alpha 模型的核心输出。 - 个股/组合预期风险预测: 结合因子暴露、因子协方差矩阵、特异性风险,预测个股或组合的风险指标(波动率、Beta、VaR、跟踪误差等)。风险模型的核心输出。
- 不能省略。 这是连接模型和策略的关键一步。
- 个股预期收益率预测: 结合最新的因子暴露度和(可能经过预测调整的)因子预期收益率,预测个股下一期的收益率 (
- 交易成本预测 (Transaction Cost Forecasting): (可选但推荐)
- 估计交易执行成本(佣金、印花税、冲击成本等),用于优化和更真实的业绩评估。
- 可以省略,但省略后回测结果会过于乐观。 对于高换手率策略尤其重要。
- 组合构建 / 优化 (Portfolio Construction / Optimization):
- 根据预测的收益率、风险、交易成本,以及投资组合的约束条件(如行业中性、市值中性、个股权重限制、换手率限制等),求解优化问题(如最大化预期收益、最小化预期风险、最大化信息比率),得到目标持仓权重。
- 不能省略(对于优化型策略)。 这是将因子信号转化为投资决策的核心步骤。对于简单的排序打分策略,此步骤可能简化为按分数加权。
- 回测执行与业绩评估 (Backtesting Execution & Performance Evaluation):
- 模拟历史交易,根据目标权重调整持仓,考虑交易成本。
- 计算回测期内的组合净值、收益率、波动率、夏普比率、最大回撤、信息比率、因子暴露、换手率等指标,评估策略表现。
- 不能省略。 验证策略的历史有效性。
总结:
核心环节(数据处理、因子选择/合并、模型拟合、预测、组合构建、回测评估)都不能省略。单因子测试可以看作因子筛选的一部分,交易成本预测可以简化但最好包含。
2.5 每一期的因子暴露度,如果不进行离群值、缺失值以及标准化处理,会有什么后果?如果选择进行处理,又会带来哪些需要注意的模型扭曲?
不进行处理的后果:
- 离群值 (Outliers):
- 后果:
- OLS 回归: 极端因子值会对回归系数(因子收益率)产生巨大影响(杠杆点),使得估计结果不稳定且可能偏离大部分数据的真实关系。
- WLS 回归: 影响依然存在,只是可能被权重部分缓解。
- 因子相关性计算: 扭曲相关系数的计算。
- 组合构建: 可能导致对具有极端因子值的股票配置极端(过高或过低)的权重,增加组合风险。
- 后果:
- 缺失值 (Missing Values / NaN):
- 后果:
- 截面回归: 导致包含缺失值的股票在当期回归中被剔除(listwise deletion),减小样本量,可能导致回归系数估计效率降低,甚至在缺失普遍时无法进行回归。
- 因子相关性/协方差计算: 同样导致数据丢失。
- 组合构建: 无法为缺失因子暴露的股票计算预期收益或风险,导致这些股票无法被纳入组合或需要特殊处理。
- 后果:
- 未标准化 (Non-Standardized):
- 后果:
- 回归系数不可比: 不同因子的回归系数(因子收益率)量纲不同,无法直接比较哪个因子的“影响”更大。例如,市值的 beta 和市盈率倒数的 beta 单位完全不同。
- WLS 权重问题: 如果使用 WLS,权重(如市值)与量纲差异巨大的因子相乘,可能导致数值问题或权重效果失衡。
- 优化器敏感性: 某些优化算法对输入变量的尺度敏感,未标准化的因子可能导致优化过程不稳定或收敛困难。
- 因子组合困难: 如果想将多个因子等权或按某种规则组合成复合因子,未标准化的因子会因量纲不同导致实际权重失衡。
- 后果:
进行处理可能带来的模型扭曲:
- 离群值处理 (如 Winsorization / Capping):
- 扭曲:
- 信息损失: 强行将极端值拉回边界,损失了关于分布尾部的信息。如果极端值是真实的经济信息而非噪声,处理会引入偏差。
- 分布改变: 改变了因子原始的分布形状,可能影响后续统计推断的假设。
- 低估尾部风险: 对于风险模型,过度压缩尾部可能导致低估极端事件的风险。
- 扭曲:
- 缺失值处理 (如 Imputation - 均值/中位数/零填充):
- 扭曲:
- 引入假设: 假设缺失值可以用某种中心趋势(均值、中位数)或特定值(零)代替,这可能与事实不符。
- 降低方差: 填充的值通常比真实值波动小,可能人为降低因子的方差。
- 扭曲相关性: 填充的值可能改变该因子与其他因子的相关关系。
- 掩盖问题: 如果缺失本身是重要信号(如公司不披露特定数据),填充会掩盖这个信号。
- 扭曲:
- 标准化 (Standardization):
- 扭曲:
- 假设分布: Z-score 标准化假设数据大致对称,对偏态分布效果可能不好。它也不能保证处理后的数据一定服从正态分布。
- 丢失绝对水平信息: 标准化后只保留相对位置信息。例如,所有公司的 PE 都很高,标准化后依然会有正有负,掩盖了整体高估值的绝对水平。
- 对离群值敏感 (Z-score): 标准差受离群值影响大,可能导致大部分数据的标准化值被压缩在很小范围。
- 扭曲:
结论:
预处理是必要的,但需要理解其潜在的副作用。选择何种处理方法、参数如何设定(如 Winsorization 的 N 值,缺失值填充方式),应基于对数据、因子特性、模型目标的理解,并通过稳健性检验来评估不同处理方式对最终结果的影响。没有完美的处理方法,都是在偏差和方差(或噪声影响)之间做权衡。
2.6 离群值处理方法有那几种?一种比较常用的办法是将离开均值N倍标准差距离以外的离群值拉回N倍标准差的位置上,这时候N一般取值多少?【离群值处理还可以用中位数去极值等办法,对题干所述方法,有把N取成2,2.5,3,5的,也许可以通过理论+实践验证一下哪种取值更好】
处理因子暴露中离群值的常用方法包括:
-
基于标准差的方法 (Winsorization / Clamping / Capping):
- 方法: 计算因子值的均值 (mean) 和标准差 (std)。将所有大于
mean + N * std
的值设为mean + N * std
,将所有小于mean - N * std
的值设为mean - N * std
。 - N 的取值: 这是一个经验性选择,常见的取值有 2.5, 3, 3.5, 4, 5。
- N=3: 对应于正态分布下约 99.7% 的数据。这是非常常用的选择。
- N=2.5 或 2: 更严格,去除或压缩更多数据,可能用于噪声较多或对极端值更敏感的模型。
- N=4 或 5: 更宽松,保留更多尾部信息,适用于认为极端值包含较多真实信息或数据本身波动较大的情况。
- 优劣: 简单直观,易于实现。但均值和标准差本身对离群值敏感,可能导致 N 个标准差的边界被极端值拉偏。
- 方法: 计算因子值的均值 (mean) 和标准差 (std)。将所有大于
-
基于中位数的方法 (Robust Winsorization):
- 方法: 计算因子值的中位数 (median) 和中位数绝对偏差 (Median Absolute Deviation, MAD)。
MAD = median(|x_i - median(x)|)
。为了与标准差可比,通常使用一个调整后的 MAD,即Adjusted_MAD = MAD / Φ⁻¹(0.75)
(其中 Φ⁻¹(0.75) ≈ 0.6745,是标准正态分布的 0.75 分位数)。然后将离群值拉回median ± N * Adjusted_MAD
的边界。 - N 的取值: 同样常取 2.5, 3 等。
- 优劣: 对离群值更稳健 (Robust),因为中位数和 MAD 不易受极端值影响。在因子分布偏斜或存在显著离群值时通常优于基于标准差的方法。
- 方法: 计算因子值的中位数 (median) 和中位数绝对偏差 (Median Absolute Deviation, MAD)。
-
基于百分位数的方法 (Percentile Capping):
- 方法: 计算因子的特定百分位数,例如 1% 和 99% (或 0.5% 和 99.5%)。将所有小于 1% 分位数的值设为 1% 分位数的值,将所有大于 99% 分位数的值设为 99% 分位数的值。
- 优劣: 不依赖于对数据分布的假设(如正态分布),直观。但丢弃了超出百分位数范围的所有大小信息。
-
将离群值设为缺失值 (NaN):
- 方法: 将超出 N 倍标准差或 N 倍 MAD 范围的值直接设为 NaN,后续按缺失值处理。
- 优劣: 完全剔除极端值的影响,但损失了样本信息。
N 取多少更好?
-
没有绝对的“最好”值。
-
理论依据: 如果假设数据大致服从正态分布,N=3 覆盖了 99.7% 的数据,是一个常用的基准。
-
实践验证: 最好的方法是通过实证检验:
- 尝试不同的 N 值(以及不同的方法,如 MAD 法 vs Std 法)。
- 观察不同处理方式对因子统计特性(如分布形状)、单因子测试结果(如 IC, IR, t-stats)、最终模型拟合效果(如 R², 因子收益稳定性)的影响。
- 进行稳健性分析 (Robustness Check),看模型结果对 N 的选择是否敏感。如果结果对 N 非常敏感,说明模型可能不够稳健。
-
倾向: 基于 MAD 的方法通常更受推荐,因为它对原始数据中的离群值不敏感。对于 N 的选择,N=3 (基于 MAD 或 Std) 是一个合理的起点,可以根据具体因子特性和模型需求调整。
-
Python 代码示例 (Winsorization 基于 Std 和 MAD):
import pandas as pd
import numpy as np
from scipy.stats import norm
def winsorize_std(series, n_std=3):
"""基于均值和标准差进行 Winsorize 处理"""
mean = series.mean()
std = series.std()
lower_bound = mean - n_std * std
upper_bound = mean + n_std * std
return series.clip(lower=lower_bound, upper=upper_bound)
def winsorize_mad(series, n_mad=3):
"""基于中位数和 MAD 进行 Winsorize 处理"""
median = series.median()
# 处理所有值都相同的情况
if series.nunique() <= 1:
return series
diff = np.abs(series - median)
# 处理 diff 全为0的情况 (如果所有值都等于中位数)
mad = diff.median()
if mad == 0:
# 如果MAD为0,可以采用标准差作为备选,或者根据业务逻辑处理
# 这里用标准差替代,或者可以直接返回原 series
mean_abs_dev = np.mean(np.abs(series - median)) # 使用平均绝对偏差替代
if mean_abs_dev == 0: return series # 如果还是0,说明所有值相同
adjusted_mad = mean_abs_dev * 1.253 # 近似关系调整
# 或者简单处理:如果 mad=0 且 median 非0,可能是一个脉冲信号,可能需要特殊处理
else:
adjusted_mad = mad / norm.ppf(0.75) # 调整使其与正态分布的标准差可比
lower_bound = median - n_mad * adjusted_mad
upper_bound = median + n_mad * adjusted_mad
return series.clip(lower=lower_bound, upper=upper_bound)
# 假设 df 是包含因子暴露的 DataFrame
# factor_column = 'factor_value'
# df[f'{factor_column}_winsorized_std'] = winsorize_std(df[factor_column], n_std=3)
# df[f'{factor_column}_winsorized_mad'] = winsorize_mad(df[factor_column], n_mad=3)
# print(df[[factor_column, f'{factor_column}_winsorized_std', f'{factor_column}_winsorized_mad']].describe())
2.7 缺失值的处理方法有哪几种?现提供三种参考方式:一是把空置设为NaN,回归涉及NaN项时用程序自动忽略;二是把所有含NaN项的个股从当期票池中剔除;三是把所有NaN(在标准化后)设为零(或中位数)。它们有什么区别?哪种好?或者有没有更好的?
处理因子暴露缺失值 (NaN) 的方法,以及题中提到的三种方式的比较:
方法与区别:
-
方法一:保持 NaN,回归时忽略 (Listwise Deletion by Regression Software):
- 操作: 因子值保持为 NaN。在执行截面回归时,
statsmodels
等库通常默认会忽略任何包含 NaN 的行(无论是自变量 X 还是因变量 Y)。 - 区别: 不改变原始数据。每期回归使用的样本量是当期所有因子和收益率都完整的股票集合。不同期回归的样本量可能不同。
- 优点: 保留了尽可能多的原始信息(未进行填充);对于特定股票,如果只是某个因子暂时缺失,其他因子信息仍可用于其他分析。
- 缺点: 如果某个股票或某个因子缺失值较多,会导致回归样本量大幅减少,降低估计效率和稳定性;每次回归的样本不同,可能影响结果的可比性。
- 操作: 因子值保持为 NaN。在执行截面回归时,
-
方法二:从当期票池剔除含 NaN 个股 (Complete Case Analysis):
- 操作: 在进行任何计算(如标准化、回归)之前,将当期截面数据中任何一个因子值为 NaN 的整只股票从样本池中剔除。
- 区别: 保证了当期所有分析(标准化、回归等)都基于同一组“完整数据”的股票。每期使用的股票集合是固定的(在该期内)。
- 优点: 实现简单,数据处理逻辑清晰,保证了分析样本的一致性。
- 缺点: 信息损失严重。只要有一个因子缺失,该股票的所有信息(包括其他有效因子和收益率)都被丢弃,可能导致样本量急剧下降,尤其在因子数量多或数据质量不高时。可能引入样本选择偏差 (Sample Selection Bias),如果缺失数据的股票具有某些系统性特征。
-
方法三:填充特定值(标准化后设为 0 或 中位数)(Imputation):
- 操作:
- 标准化后设为 0: 先对非缺失值进行标准化(如 Z-score),然后将所有 NaN 替换为 0。
- 标准化后设为中位数: (这种说法不常见)更常见的做法是标准化前用中位数填充:先计算非缺失值的中位数,用该中位数填充 NaN,然后再对填充后的完整序列进行标准化。或者,直接用截面中位数/均值填充:计算当期截面上该因子的中位数(或均值),用该值填充 NaN。
- 区别: 人为地为缺失值赋予了一个具体数值,以保留样本量。标准化后设为 0 意味着假设该股票在该因子上的暴露是截面平均水平。用中位数/均值填充也是类似的假设(但填充在中位数/均值上)。
- 优点: 保留了完整的样本量,所有股票都可以参与回归和组合构建,提高了覆盖率,尤其对风险模型很重要。
- 缺点: 引入了较强假设和潜在偏差。填充的值可能与真实值相差甚远。降低了数据的真实方差。扭曲了因子与其他变量的相关性。如果缺失本身是信号,填充会丢失该信号。标准化后再填充 0 尤其需要注意,因为 0 代表的是样本均值,如果原始缺失值并非均值水平,偏差会很大。
- 操作:
哪种好?
- 没有绝对最优,取决于情境和权衡。
- 收益预测 (Alpha 模型): 对因子信号质量要求高,可能更倾向于方法一(回归时忽略)或方法二(剔除个股),以避免填充噪声干扰 Alpha 信号。但如果因此导致样本量过小,则模型不可靠。有时也会采用方法三(填充),但需要非常小心其引入的偏差,并进行稳健性测试。
- 风险预测 (Risk 模型): 对样本覆盖率要求很高,希望能估计所有(或绝大多数)股票的风险暴露和协方差。因此,方法三(填充,通常用截面均值或中位数填充后再标准化)是常用实践,尽管它有缺点,但为了保证协方差矩阵的完整性和稳定性,这是必要的牺牲。需要监控填充比例,过高的填充比例会降低模型可靠性。
- 方法一 vs 方法二: 方法一通常比方法二更好,因为它只在必要时(即回归需要该变量时)才剔除,而方法二则是一刀切,损失信息更多。
更好的方法?
-
更复杂的填充技术 (Advanced Imputation):
- 基于历史数据填充: 用该股票自身的历史均值或中位数填充(如果历史数据足够)。
- 基于同类股票填充: 用同行业、同市值组股票的均值或中位数填充。
- 基于模型预测填充 (Model-Based Imputation): 使用其他因子或变量,通过回归模型或机器学习模型(如 K-Nearest Neighbors Imputation, MICE - Multiple Imputation by Chained Equations)来预测缺失值。
- 优点: 可能比简单的均值/中位数填充更准确。
- 缺点: 模型更复杂,引入更多假设,计算量大。
-
因子特定处理: 根据因子本身的含义判断缺失原因。例如,研发费用缺失可能就是零投入,可以填充 0。财务比率的分母为 0 或负导致缺失,可能需要特殊处理。
结论: 填充法(方法三,尤其是用截面中位数/均值填充)是风险模型中为了保证覆盖率的常用选择。回归时忽略(方法一)在 Alpha 模型或缺失值较少时可能更优。剔除个股(方法二)通常过于极端。高级填充方法值得探索,但需平衡复杂度和收益。
- Python 代码示例 (填充):
import pandas as pd
# 假设 df_slice 是单期截面数据 DataFrame
# factor_column = 'factor_value'
# 方法三的变种:用截面中位数填充,然后标准化
def fillna_median_then_standardize(series):
median_val = series.median()
filled_series = series.fillna(median_val)
# 再进行标准化 (示例 Z-score)
mean = filled_series.mean()
std = filled_series.std()
if std == 0: # 处理标准差为0的情况
return pd.Series(0.0, index=series.index) # 或 np.nan,取决于后续处理
standardized_series = (filled_series - mean) / std
return standardized_series
# df_slice[f'{factor_column}_filled_standardized'] = fillna_median_then_standardize(df_slice[factor_column])
# 方法三:先标准化,再填充 0 (需要先处理非 NaN 值)
def standardize_then_fillna_zero(series):
# 仅对非 NaN 值计算均值和标准差
not_na_series = series.dropna()
if len(not_na_series) < 2: # 无法计算 std
return pd.Series(0.0, index=series.index) # 或 np.nan
mean = not_na_series.mean()
std = not_na_series.std()
if std == 0:
# 如果非缺失值都相同,标准化结果为 0 或 NaN
standardized_series = pd.Series(0.0, index=series.index) # 或 np.nan
else:
standardized_series = (series - mean) / std
# 填充 NaN 为 0
return standardized_series.fillna(0)
# df_slice[f'{factor_column}_standardized_fillna_zero'] = standardize_then_fillna_zero(df_slice[factor_column])
2.8 标准化的方法有哪些?标准化后数据近似呈现何种分布规律?各种标准化方法的利弊?【除了减去均值、再除以标准差,还可以取排序序数等】
标准化的目的是将不同量纲、不同分布的因子暴露度转换到统一的可比尺度上,便于后续的回归分析、因子组合和组合优化。常用方法:
-
Z-Score 标准化 (Standard Score):
- 方法:
z = (x - mean(x)) / std(x)
- 分布规律: 转换后的数据具有均值为 0,标准差为 1。如果原始数据近似正态分布,则标准化后仍近似标准正态分布。但 Z-score 不改变分布的形状(偏度、峰度基本不变),只是进行了线性的平移和缩放。
- 优点:
- 最常用,易于理解和实现。
- 保留了原始数据的相对距离信息(线性变换)。
- 使得回归系数的解释更方便(代表因子暴露增加一个标准差时,预期收益的变化)。
- 缺点:
- 对离群值敏感:均值和标准差受极端值影响很大,可能导致大部分数据的 Z-score 被压缩在很小的区间内,夸大极端值的影响。
- 不适用于不满足均值和标准差有意义的分布(如极度偏态分布)。
- 方法:
-
稳健 Z-Score 标准化 (Robust Z-Score):
- 方法:
z_robust = (x - median(x)) / (Adjusted_MAD)
(Adjusted_MAD 见 2.6) - 分布规律: 均值和标准差不一定严格为 0 和 1,但数据的中心位置和离散程度是用更稳健的统计量(中位数和 MAD)来度量的。同样不改变分布的基本形状。
- 优点:
- 对离群值稳健:中位数和 MAD 不易受极端值影响,标准化结果更稳定。
- 适用于偏态分布或含有离群值的数据。
- 缺点:
- 计算比 Z-score 稍复杂。
- 标准化后的均值和标准差不是精确的 0 和 1。
- 方法:
-
排序标准化 / 分位数标准化 (Rank / Quantile Standardization):
- 方法:
- 简单排名: 将因子值按升序(或降序)排列,用其排名(如 1 到 N)或排名百分位(排名 / (N+1))作为标准化后的值。
- 正态分位数转换 (Normal Score Transformation): 先计算每个值的排名百分位
p
,然后找到标准正态分布中对应于该百分位的分位数Φ⁻¹(p)
作为标准化后的值。
- 分布规律:
- 简单排名/排名百分位:强制转换为均匀分布(或近似均匀分布)。
- 正态分位数转换:强制转换为标准正态分布。
- 优点:
- 完全不受离群值影响。
- 消除了原始分布形状的影响,使得不同因子具有相同的分布(均匀或正态)。
- 对于单调关系,即使原始关系非线性,排序后也变为线性。
- 缺点:
- 丢失了原始数据的绝对差异和相对距离信息,只保留了排序信息。例如,排名第 1 和第 2 的原始值差距可能远大于排名第 100 和第 101 的差距,但在排序标准化后这种差异消失了。
- 可能丢失一些有用的非单调信息。
- 方法:
-
Min-Max 标准化 (Min-Max Scaling):
- 方法:
x_scaled = (x - min(x)) / (max(x) - min(x))
- 分布规律: 将数据线性地缩放到 [0, 1] 区间。不改变分布的基本形状。
- 优点:
- 将数据限定在明确的范围内,有时便于输入某些模型(如神经网络)。
- 缺点:
- 对离群值极其敏感:最大值和最小值决定了缩放的范围,一个极端值会严重压缩其他所有数据的范围。
- 在金融因子中较少使用,因为因子通常没有明确的上下界。
- 方法:
选择哪种方法?
-
如果数据比较干净,近似对称分布,Z-score 是常用且方便的选择。
-
如果数据存在离群值或偏态分布,稳健 Z-score 或 排序/分位数标准化 通常是更好的选择。
- 稳健 Z-score 保留了更多原始数值信息(相对距离)。
- 排序/分位数标准化 完全消除了离群值和分布形状的影响,但丢失了数值间距信息。在 Alpha 因子挖掘中,Rank IC(基于排序计算 IC)和基于排序的因子组合很常见,说明排序标准化有其价值。
-
实践中,可以对不同因子采用不同的标准化方法,取决于该因子的分布特性和在模型中的作用。例如,对接近正态的因子用 Z-score,对有明显离群值的因子用稳健 Z-score 或排序。
-
Python 代码示例 (Rank 标准化):
import pandas as pd
from scipy.stats import norm
def rank_standardize(series):
"""按排名百分位标准化到 [0, 1] 区间"""
# rank(method='average') 处理并列排名
return series.rank(method='average') / (len(series.dropna()) + 1)
def normal_score_standardize(series):
"""转换为标准正态分位数 (Normal Scores)"""
rank_pct = series.rank(method='average') / (len(series.dropna()) + 1)
# 使用正态分布的 PPF (Percent Point Function, 即 quantile function or inverse CDF)
# 为避免 inf,对接近 0 和 1 的值做微小调整
epsilon = 1e-6
rank_pct = rank_pct.clip(epsilon, 1 - epsilon)
return norm.ppf(rank_pct)
# 假设 df_slice 是单期截面数据 DataFrame
# factor_column = 'factor_value'
# df_slice[f'{factor_column}_rank_pct'] = rank_standardize(df_slice[factor_column])
# df_slice[f'{factor_column}_normal_score'] = normal_score_standardize(df_slice[factor_column])
# print(df_slice[[factor_column, f'{factor_column}_rank_pct', f'{factor_column}_normal_score']].describe())
2.9 带权重的标准化,权重怎么设置?是否需要和回归时的个股权重保持一致?
带权重的标准化 (Weighted Standardization):
当样本中不同观测值(股票)的重要性不同时(例如,在构建可投资组合或拟合 WLS 回归时),可能需要进行带权重的标准化。
-
计算方法:
- 计算加权均值 (Weighted Mean):
w_mean = sum(w_i * x_i) / sum(w_i)
- 计算加权标准差 (Weighted Standard Deviation):
w_std = sqrt(sum(w_i * (x_i - w_mean)^2) / sum(w_i))
(注意:有时分母会用(sum(w_i) * (M-1))/M
或其他形式进行无偏调整,M 为观测数,但简单加权常用sum(w_i)
) - 进行标准化:
z_weighted = (x_i - w_mean) / w_std
- 计算加权均值 (Weighted Mean):
-
权重设置 (Weight Setting):
- 权重
w_i
的选择取决于标准化的目的。最常见的情况是与后续 WLS 回归中使用的权重保持一致。 - 常用权重:
- 市值平方根 (sqrt(Market Cap)): 这是 Barra 等风险模型在进行 WLS 回归时常用的权重,认为股票的特异性风险与市值平方根成反比。因此,标准化时也常使用
sqrt(Market Cap)
作为权重。 - 市值 (Market Cap): 有时也直接使用市值作为权重,给予大市值股票更大的影响力。
- 等权重 (Equal Weight): 如果不考虑股票重要性差异,则所有
w_i = 1
,退化为普通标准化。
- 市值平方根 (sqrt(Market Cap)): 这是 Barra 等风险模型在进行 WLS 回归时常用的权重,认为股票的特异性风险与市值平方根成反比。因此,标准化时也常使用
- 权重
-
是否需要和回归时的个股权重保持一致?
- 强烈建议保持一致。
- 理由:
- 一致性: 保证了因子暴露的尺度与回归模型对样本的加权方式相匹配。例如,如果回归更关注大市值股票(使用市值相关权重),那么因子暴露的“一个标准差”也应该反映大市值股票贡献更大的分布特征。
- 解释性: 标准化后的因子值(如 Z-score=1)代表着相对于由权重定义的“市场平均”偏离了一个由权重定义的“标准差”,这与 WLS 回归的视角一致。
- 避免尺度扭曲: 如果标准化时不加权(或使用不同权重),而回归时加权,可能会导致实际上因子暴露的尺度与回归中股票的重要性不匹配,影响系数估计和解释。
结论: 进行带权重标准化时,权重通常设置为与后续 WLS 回归(如果使用 WLS)所用的权重一致,最常见的是市值平方根。
- Python 代码示例 (加权标准化):
import pandas as pd
import numpy as np
def weighted_standardize(series, weights):
"""进行加权 Z-score 标准化"""
# 确保 series 和 weights 索引对齐,且处理 NaN
valid_idx = series.notna() & weights.notna() & (weights > 0) # 权重需有效
if not valid_idx.any():
return pd.Series(np.nan, index=series.index)
series_valid = series[valid_idx]
weights_valid = weights[valid_idx]
w_mean = np.average(series_valid, weights=weights_valid)
# 计算加权方差
w_variance = np.average((series_valid - w_mean)**2, weights=weights_valid)
if w_variance < 1e-10: # 避免除以接近零的数
w_std = 0
else:
w_std = np.sqrt(w_variance)
# 标准化
if w_std == 0:
standardized_series = pd.Series(0.0, index=series.index) # 或 np.nan
else:
standardized_series = (series - w_mean) / w_std
# 将无效的部分设回 NaN (可选,或根据业务逻辑)
standardized_series[~valid_idx] = np.nan
return standardized_series
# 假设 df_slice 是单期截面数据 DataFrame
# factor_column = 'factor_value'
# weight_column = 'market_cap_sqrt' # 假设已有市值平方根权重列
# df_slice['weights'] = np.sqrt(df_slice['market_cap']) # 如果没有,先计算
# df_slice[f'{factor_column}_w_standardized'] = weighted_standardize(df_slice[factor_column], df_slice['weights'])
# print(df_slice[[factor_column, f'{factor_column}_w_standardized']].describe())
2.10 标准化、离群值处理、缺失值处理,三个环节如何确立先后顺序?
这三个预处理环节的顺序对最终结果有影响,需要仔细考虑。一个常用且逻辑上比较稳妥的顺序是:
-
缺失值处理 (Missing Value Handling - Imputation First):
- 如果采用填充法 (Imputation)(如均值、中位数填充),应该最先进行。
- 理由: 后续的离群值检测和标准化都需要基于完整的数据集进行计算(计算均值、标准差、中位数、MAD 或百分位数都需要尽可能多的数据)。如果在填充前进行离群值处理或标准化,这些统计量的计算会因缺失值而产生偏差。
- 如果缺失值是保留 NaN,由后续步骤(如回归)处理,则此步骤可以理解为“识别 NaN”,不涉及填充。
-
离群值处理 (Outlier Treatment):
- 应在缺失值填充之后(如果填充),标准化之前进行。
- 理由:
- 离群值会严重扭曲用于标准化的统计量(尤其是均值和标准差)。如果在标准化之后再处理离群值,标准化的效果可能已经被破坏。例如,一个极端值可能导致其他所有值的 Z-score 都非常接近 0。
- 需要基于填充后的(相对)完整数据来识别哪些值是相对于“整体”的离群值。
-
标准化 (Standardization):
- 通常是最后一步。
- 理由: 标准化需要基于经过清洗(填充了缺失、处理了离群)的数据进行,以确保计算出的均值/标准差(或中位数/MAD)能代表数据的主体分布特征,从而得到有意义的标准化结果。
总结顺序:
常用顺序: 缺失值填充 (Imputation) -> 离群值处理 (Outlier Treatment) -> 标准化 (Standardization)
特殊情况:
- 如果缺失值处理方式是保留 NaN: 则顺序可以是 离群值处理 -> 标准化(此时标准化函数需要能处理 NaN 或在处理前临时忽略 NaN 计算统计量)。
- 如果使用排序标准化: 排序标准化本身对离群值不敏感,所以离群值处理步骤甚至可以省略或放在标准化之后(意义不大)。但缺失值填充(如果需要)仍然建议在排序前进行。
关键原则: 保证每一步操作所依赖的统计量(均值、标准差、中位数、MAD、分位数)是基于尽可能准确反映数据主体特征的数据计算得到的。
2.11 因子之间或多或少具有一些相关性,若把所有因子进行正交化处理,会发生什么情况?这样做或不这样做的理由是什么?
将因子组进行正交化处理(Orthogonalization),意味着通过数学变换,使得新的因子组两两之间的线性相关系数为零。常用方法包括格兰-施密特 (Gram-Schmidt) 序贯正交化、主成分分析 (PCA) 提取正交因子等。
发生的情况:
- 因子暴露改变: 股票在新的、正交化后的因子上的暴露度会发生变化,不再是原始因子的暴露度。
- 因子收益改变: 正交化后的因子的收益率(回归系数)也会改变。
- 因子解释含义改变:
- 序贯正交化: 假设原始因子为 F1, F2, F3。将 F2 对 F1 回归取残差得到 F2’,再将 F3 对 F1 和 F2’ 回归取残差得到 F3’‘。新的因子组是 F1, F2’, F3’‘。F2’ 的含义是 F2 中不能被 F1 解释的部分,F3’’ 是 F3 中不能被 F1 和 F2’ 解释的部分。因子的经济意义变得依赖于正交化的顺序,且不直观。
- PCA 正交化: 提取的主成分是原始因子的线性组合,其选择是为了最大化解释原始因子矩阵的方差。这些主成分通常缺乏清晰的经济含义,难以命名和解释,尽管它们在统计上是正交的。
- 模型解释力 (R²): 如果保留所有正交化后的因子(或足够多的主成分),模型的总解释力 R² 通常不会有太大变化(理论上不变,实践中因数值精度略有差异)。变化的是 R² 在不同因子间的分配。
- 回归系数解释: 正交化后,某个因子的回归系数(因子收益率)可以解释为“在控制了其他所有(正交)因子后,该因子变动一个单位对收益率的影响”。解释变得“干净”,因为消除了其他因子的混淆效应。
这样做的理由 (Pros):
- 解决多重共线性: 彻底消除因子间的线性相关性,使得回归系数的估计更稳定,标准误更小。
- 简化模型解释: 每个因子的系数代表其“独立”贡献,便于分析单个因子的边际效应。
- 满足某些模型要求: 某些风险模型或组合优化技术可能假设或要求因子是正交的。
- 因子筛选/降维: PCA 等方法可以在正交化的同时实现降维,用少数几个正交因子捕捉原始因子的大部分信息。
不这样做的理由 (Cons):
- 牺牲经济可解释性 (最主要原因): 正交化后的因子(尤其是 PCA 或序贯正交化的后续因子)往往失去了原始因子的直观经济含义。这使得模型变成了“黑箱”,难以理解风险的真正来源或 Alpha 的驱动因素,不利于模型诊断和改进。例如,正交化后的“价值”因子不再是纯粹的价值因子。
- 结果依赖于方法和顺序: 序贯正交化的结果依赖于因子的排列顺序。不同的正交化方法(如 PCA)结果也不同。
- 不稳定: 如果因子间的相关性结构随时间变化,那么正交化过程和得到的正交因子也会不稳定。
- 可能并非必要:
- 风险模型: 风险模型的目标是解释风险和协方差,因子间的相关性本身就是风险的重要组成部分,需要被准确估计而不是消除。Barra 等主流风险模型并不要求因子完全正交,而是会估计并提供因子协方差矩阵。
- Alpha 模型: 通常更关心 Alpha 因子与已知风险因子的正交性(通过中性化实现),以确保 Alpha 的独立性。Alpha 因子之间是否正交可能不是首要目标,除非它们之间存在极高的相关性导致模型不稳定。
- 信息损失: PCA 等降维方法在正交化的同时会丢弃部分信息(解释力较弱的主成分)。
结论:
是否进行完全正交化取决于模型的目标。对于追求模型解释性和经济意义的风险模型和业绩归因模型,通常不进行完全正交化,而是接受并估计因子间的相关性。对于某些纯粹追求预测效果或需要输入正交因子的算法(可能在 Alpha 模型或某些量化策略中),可能会采用正交化,但必须接受其牺牲可解释性的代价。更常见的做法是对 Alpha 因子相对风险因子进行正交化 (中性化),而不是对所有因子进行完全正交化。
2.12 如何选择截面回归的频率?依据是什么?
选择截面回归的频率(即多久进行一次 Y = X*beta + e
的回归来估计因子收益率 beta
)是一个重要的实践问题。常用频率包括日频、周频、月频。
选择依据:
- 因子特性与更新频率:
- 高频因子: 如果模型包含基于日内或日度价量信息的高频因子(如短期反转、流动性冲击),这些因子暴露度变化快,可能需要日频回归来捕捉其快速变化的收益。
- 低频因子: 如果模型主要基于基本面数据(季报/年报)、低频风格因子(如价值、规模),这些因子暴露度变化较慢,月频回归通常足够。周频是介于两者之间的折中。
- 因子收益的持续性 (Factor Return Persistence):
- 如果因子收益率(真实的,非估计噪声)变化很快,自相关性低,那么需要更高频率的回归来捕捉其变化。如果因子收益相对稳定,低频回归也可以。
- 模型用途:
- 高频交易策略/日内风险管理: 需要日频甚至更高频率的因子收益估计。
- 中低频策略 (月度调仓)/长期风险预测: 月频通常是标准做法。提供了更平滑、噪声更小的因子收益率估计,也与许多机构的调仓周期匹配。
- 业绩归因: 归因频率应与所归因的组合管理频率或评估周期一致,常用月频。
- 数据质量与噪声:
- 日频数据噪声大: 日度收益率包含大量市场噪声,日频回归得到的因子收益率 (
beta_t
) 序列波动性会非常大,信噪比低。 - 低频数据更平滑: 使用月度收益率进行月频回归,可以在一定程度上平滑掉日度噪声,得到相对更稳定的因子收益率估计。
- 日频数据噪声大: 日度收益率包含大量市场噪声,日频回归得到的因子收益率 (
- 计算资源与效率:
- 日频回归计算量远大于月频回归。对于复杂的模型和庞大的股票池,计算成本是一个实际考量。
- 交易成本与策略执行:
- 回归频率(以及因子更新频率)往往与策略的调仓频率相关。如果策略是月度调仓,那么月频回归可能更自然。日频回归可能意味着需要更频繁的交易(如果基于日度信号调整),需要考虑交易成本。
常用选择与权衡:
- 月频 (Monthly): 最常用的选择,尤其对于基于风格因子和基本面因子的模型。它在平滑噪声、计算效率、匹配中长期投资视角方面取得了较好的平衡。
- 日频 (Daily): 用于高频策略、实时风险监控,或当模型包含需要日度更新的高频因子时。需要接受因子收益估计波动性大的缺点,并可能需要对估计结果进行平滑处理(如移动平均)。
- 周频 (Weekly): 一种折中方案,比日频平滑,比月频及时。
结论: 选择哪个频率没有绝对答案,需要根据因子特性、模型目标、数据噪声、计算资源和策略执行需求进行综合权衡。月频是多因子模型(尤其是风险和中低频 Alpha 模型)的标准实践频率。
2.13 回归模型涉及的个股收益率怎么计算?最简单的(又能保证一定精确度的)方法是什么?
回归模型中的因变量 Y
是个股在相应回归期(日、周、月)的收益率。计算方法需要考虑除权除息的影响,以保证收益率的准确性。
最简单且能保证较好精确度的方法:使用后复权价格 (Adjusted Closing Price)
-
方法:
- 获取可靠数据源提供的后复权收盘价 (Adjusted Close Price) 序列。后复权价格已经对历史上的分红、送股、配股等事件进行了处理,使得历史价格在可比口径上连续。
- 计算区间收益率:
- 日收益率:
Return_t = (AdjClose_t / AdjClose_{t-1}) - 1
- 周收益率:
Return_week = (AdjClose_{end_of_week} / AdjClose_{end_of_last_week}) - 1
- 月收益率:
Return_month = (AdjClose_{end_of_month} / AdjClose_{end_of_last_month}) - 1
- 日收益率:
-
优点:
- 简单方便: 直接利用数据供应商处理好的复权价格,避免了自行处理复杂的除权除息细节。
- 精度较高: 主流数据供应商(如 Wind, Choice, Bloomberg, Refinitiv 等)提供的复权价格通常经过仔细处理,精度足够满足大部分模型需求。
- 标准化: 使用广泛接受的数据源,结果易于复现和比较。
-
注意事项:
- 数据源可靠性: 确保使用的复权价格数据源是准确和及时的。
- 复权方式: 通常使用后复权 (Backward Adjusted) 价格,它保持当前价格不变,向前调整历史价格。前复权价格会改变当前价格,不适用于计算历史收益率序列。
- 计算区间: 确保收益率计算的起始和结束日期与回归期(日、周、月)对应。
更精确(但更复杂)的方法:基于未复权价格和权益事件自行计算
-
方法:
- 获取未复权收盘价序列。
- 获取详细的权益事件数据:现金分红(税前/税后)、送股比例、转增股比例、配股价格和比例、拆股/并股比例等,以及这些事件的除权除息日。
- 在每个除权除息日,根据相应事件调整前一天的收盘价,使其与除权后的价格可比。
- 现金分红:
Adjusted Previous Close = Previous Close - Dividend per Share
- 送股/转增:
Adjusted Previous Close = Previous Close / (1 + Ratio)
- 配股:
Adjusted Previous Close = (Previous Close * Total Shares + Rights Price * Rights Shares) / (Total Shares + Rights Shares)
(计算较复杂)
- 现金分红:
- 使用调整后的可比价格计算区间收益率。
-
优点:
- 理论上最精确,可以完全控制计算细节(如税费处理)。
-
缺点:
- 极其复杂,容易出错: 需要精确获取所有权益事件数据,并正确应用调整逻辑,任何一个环节出错都会导致收益率计算错误。
- 数据获取困难: 获取完整、准确的历史权益事件细节数据本身就是一个挑战。
- 性价比低: 付出的复杂度和潜在错误风险,相对于使用高质量后复权价格带来的精度提升,通常不成比例。
结论: 对于绝大多数多因子模型的应用,使用可靠数据源提供的后复权收盘价计算收益率,是最推荐的方法,它在简单性、准确性和标准化方面达到了最佳平衡。
- Python 代码示例 (使用后复权价格):
import pandas as pd
# 假设 df 包含 'date', 'stock_code', 'adj_close' (后复权收盘价)
# df = df.sort_values(['stock_code', 'date'])
# 计算日收益率
df['daily_return'] = df.groupby('stock_code')['adj_close'].pct_change()
# 计算月收益率 (示例:需要先将数据设为月度频率)
# df_monthly = df.groupby('stock_code').resample('M', on='date').last() # 获取每月最后一个交易日数据
# df_monthly['monthly_return'] = df_monthly.groupby(level=0)['adj_close'].pct_change()
# df_monthly = df_monthly.reset_index()
# 注意:直接用 pct_change 计算月收益,需要保证数据是连续月份的月末数据
# 更稳妥的方式是标记月份,然后 groupby('stock_code', 'month_indicator') 计算
def calculate_monthly_return(df):
"""更稳妥地计算月收益率"""
df = df.sort_values('date')
df['month'] = df['date'].dt.to_period('M')
# 获取每个股票每月的最后一个交易日数据
df_monthly_last = df.loc[df.groupby(['stock_code', 'month'])['date'].idxmax()]
# 计算月度收益率
df_monthly_last['monthly_return'] = df_monthly_last.groupby('stock_code')['adj_close'].pct_change()
return df_monthly_last[['stock_code', 'date', 'monthly_return']] # 选择需要的列
# monthly_returns = calculate_monthly_return(df)
# print(monthly_returns.head())
2.14 回归模型是否需要加入截距项(即常数项)?在什么情况下可以取,什么情况下不能取?【有行业因子时不能加入截距项,因为行业因子之和为全1向量,再加截距项就会导致回归系数不唯一确定】
在多因子模型的截面回归 Y = alpha + X*beta + e
中是否包含截距项 alpha
(常数项),取决于模型中包含的因子 X
的具体构成。
通常情况下:需要加入截距项
- 理论意义: 截距项
alpha
代表了当所有因子暴露都为零时,股票的预期收益率。在因子模型中,它通常被解释为:- 平均定价误差: 如果模型意图解释所有系统性收益,
alpha
代表了市场对样本股票平均的定价偏差(或模型未能捕捉的其他共同因素)。 - 基准组合收益: 如果因子是相对于某个基准构建的(如风格因子是多空组合),
alpha
可能代表了基准组合本身的平均收益。 - 平均特质收益: 在 Alpha 模型视角下,如果风险因子已包含在 X 中,
alpha
代表了样本股票的平均 Alpha 或未被模型解释的平均收益。
- 平均定价误差: 如果模型意图解释所有系统性收益,
- 统计需要: OLS 回归的标准假设之一是模型形式正确。省略截距项等于强加了一个“当所有因子暴露为零时,预期收益也必须为零”的约束,这在金融上通常不成立。包含截距项允许模型更好地拟合数据。
特殊情况:不能加入截距项 (或需要特殊处理)
-
当因子本身隐含了截距项时,加入显式截距项会导致完全多重共线性 (Perfect Multicollinearity),使得回归系数无法唯一确定(Dummy Variable Trap)。常见情况:
- 包含完整的行业虚拟变量集:
- 如果你使用了所有行业的虚拟变量(例如,对申万 28 个一级行业,你设置了 28 个 dummy variables,股票属于哪个行业,对应 dummy 为 1,其他为 0),并且没有省略任何一个行业作为参照组 (Reference Group),那么这些行业虚拟变量按行求和(对于每只股票,只有一个行业 dummy 为 1)结果恒等于 1。这个全 1 向量与截距项完全一样。
- 解决方法:
- 省略一个行业的虚拟变量: 将被省略的行业作为基准,其他行业的系数解释为相对于基准行业的超额收益。此时必须包含截距项,截距项代表基准行业的平均收益(在控制其他风格因子后)。
- 不包含截距项: 保留所有行业的虚拟变量,但不加截距项。此时每个行业虚拟变量的系数代表该行业自身的平均收益(在控制其他风格因子后)。
- 使用加权约束: Barra 等模型有时使用特定约束(如行业因子收益按市值加权和为 0),这种情况下截距项的处理方式需要根据具体模型设定。
- 因子本身经过特殊构造: 如果因子已经被中心化处理,并且其构造方式保证了样本的因子暴露加权和(使用与回归相同的权重)恒为零,那么截距项的解释会发生变化,但通常仍需包含。
- 包含完整的行业虚拟变量集:
-
提示的解释: 【有行业因子时不能加入截距项,因为行业因子之和为全1向量,再加截距项就会导致回归系数不唯一确定】这个说法的前提是使用了完整的、未省略参照组的行业虚拟变量集。这是最常见的导致不能加截距项的情况。
结论:
大多数情况下,多因子截面回归应该包含截距项。 唯一的例外是当因子集(X 矩阵)中存在一个或多个列向量的线性组合能够精确地产生一个全 1 的向量(即 X 矩阵的列空间包含常数向量)时。最常见的就是使用了完整的行业虚拟变量集而未省略基准行业。在实践中,如果使用 statsmodels
等包含 add_constant
功能的库,并且因子设计合理(如行业虚拟变量省略了基准组),则应加入截距项。
- Python 代码示例 (statsmodels):
import pandas as pd
import statsmodels.api as sm
# 假设 data 是包含收益率 Y 和因子暴露 X1, X2 的 DataFrame
# Y = data['return']
# X = data[['factor1', 'factor2']]
# 包含截距项 (常用)
X_with_intercept = sm.add_constant(X) # 在 X 左侧添加一列常数 1
model = sm.OLS(Y, X_with_intercept).fit()
# print(model.summary())
# 不包含截距项 (特殊情况)
# model_no_intercept = sm.OLS(Y, X).fit()
# print(model_no_intercept.summary())
# 处理行业虚拟变量 (假设已有 dummy_vars DataFrame, n-1 列)
# industry_dummies = pd.get_dummies(data['industry'], drop_first=True) # drop_first=True 省略第一类作为基准
# X_with_style_and_industry = pd.concat([X, industry_dummies], axis=1)
# X_final = sm.add_constant(X_with_style_and_industry) # 加入截距项
# model_full = sm.OLS(Y, X_final).fit()
2.15 回归时用OLS和WLS的区别在哪里?使用WLS的依据是什么?【Barra文档里提到两点:一是市场更关注那些流通市值更大的股票;二是对消除异方差有帮助,并且支出sqrt(流通市值)是对异方差的一个较好的估计,可以用作回归权重】
OLS (Ordinary Least Squares) vs. WLS (Weighted Least Squares):
- OLS (普通最小二乘法):
- 目标: 最小化残差平方和 (Sum of Squared Residuals):
min sum(e_i^2)
- 权重: 给予每个观测值(股票)相同的权重。
- 假设: 要求残差满足同方差性(Homoscedasticity),即所有观测值的误差项方差相同
Var(e_i) = σ^2
。
- 目标: 最小化残差平方和 (Sum of Squared Residuals):
- WLS (加权最小二乘法):
- 目标: 最小化加权残差平方和 (Weighted Sum of Squared Residuals):
min sum(w_i * e_i^2)
- 权重: 给予每个观测值(股票)不同的权重
w_i
。权重通常与误差项方差的倒数成正比w_i ∝ 1 / Var(e_i)
。 - 适用场景: 当残差存在异方差性 (Heteroscedasticity) 时,即不同观测值的误差项方差不同
Var(e_i) = σ_i^2
。
- 目标: 最小化加权残差平方和 (Weighted Sum of Squared Residuals):
使用 WLS 的依据 (Barra 文档提到的两点解释):
-
消除异方差 (Heteroscedasticity Correction):
- 金融市场现实: 在股票市场截面上,通常认为小市值股票的特异性收益(模型残差)波动性大于大市值股票。即存在异方差性,
Var(e_i)
与股票规模负相关。 - WLS 作用: 如果不处理异方差,OLS 估计的系数(因子收益率)虽然仍是无偏的,但不再是有效的 (不是 BLUE - Best Linear Unbiased Estimator),其标准误估计会产生偏差,导致 t 检验等统计推断不可靠。WLS 通过给方差较小(通常是大市值股票)的观测值赋予较大权重,给方差较大(通常是小市值股票)的观测值赋予较小权重,可以得到更有效率、标准误更可靠的系数估计。
sqrt(流通市值)
作为权重的依据: Barra 等模型发现,实证中股票特异性风险的标准差σ_i
大致与市值的平方根sqrt(Market Cap_i)
成反比。由于 WLS 的权重w_i
应与1 / Var(e_i) = 1 / σ_i^2
成正比,因此选择w_i
正比于(sqrt(Market Cap_i))^2 = Market Cap_i
似乎合理。但 Barra 模型的实际 WLS 回归权重通常直接设置为w_i = sqrt(流通市值_i)
。这背后的逻辑更精妙,它相当于将原始回归方程Y_i = alpha + X_i*beta + e_i
两边同时乘以sqrt(w_i) = MarketCap_i^(1/4)
(如果假设σ_i ∝ 1/sqrt(MC_i)
) 或者两边同时除以σ_i
(如果假设w_i = 1/σ_i^2
) 来进行变换,目标是使得变换后的方程误差项同方差。Barra 的选择w_i = sqrt(MC_i)
是基于实证研究和模型假设,认为这样做能较好地稳定估计结果并处理异方差。需要注意的是,这个权重选择并非理论上的最优异方差纠正权重,而是一个实践上有效且常用的选择。
- 金融市场现实: 在股票市场截面上,通常认为小市值股票的特异性收益(模型残差)波动性大于大市值股票。即存在异方差性,
-
经济重要性加权 (Weighting by Economic Importance):
- 市场关注点: 大型基金、指数、市场整体表现等更受大市值股票的影响。因子收益率如果是等权重估计出来的(OLS),可能主要反映了大量小市值股票的特征,而这与机构投资者和市场整体的感受可能不同。
- WLS 作用: 使用市值相关权重(如
sqrt(流通市值)
)进行 WLS 回归,使得大市值股票在因子收益率的估计中占有更大话语权。这样估计出的因子收益率更能反映市值加权的市场或投资组合中该因子的实际表现,更具“可投资”意义。
总结:
使用 WLS (通常以 sqrt(流通市值)
为权重) 的主要依据是:
- 统计上: 为了处理普遍存在的异方差问题,提高因子收益率估计的有效性和统计推断的可靠性。
- 经济上: 使因子收益率的估计更贴近市场(尤其是市值加权视角)的实际情况,反映经济上更重要的股票的影响。
在实践中,WLS 是多因子风险模型(如 Barra)和许多机构 Alpha 模型截面回归的标准做法。
- Python 代码示例 (OLS vs WLS):
import pandas as pd
import numpy as np
import statsmodels.api as sm
# 假设 data 是包含 Y, X, 和 market_cap 的 DataFrame
# Y = data['return']
# X = data[['factor1', 'factor2']]
# X = sm.add_constant(X) # 添加截距项
# weights = np.sqrt(data['market_cap']) # 使用市值平方根作为权重
# OLS 回归
# model_ols = sm.OLS(Y, X)
# results_ols = model_ols.fit()
# print("OLS Results:")
# print(results_ols.summary())
# WLS 回归
# model_wls = sm.WLS(Y, X, weights=weights)
# results_wls = model_wls.fit()
# print("\nWLS Results (weights = sqrt(market_cap)):")
# print(results_wls.summary())
2.16 如何评估或衡量多因子模型的效果?
评估多因子模型的效果需要从多个维度进行,具体指标侧重取决于模型的用途(收益预测、风险预测、业绩归因)。
通用评估维度:
-
模型解释力 (Explanatory Power):
- R-squared (R²): 截面回归的 R² 值,衡量模型中的因子在多大程度上解释了个股收益率的截面差异。通常看 R² 的时间序列均值、中位数和稳定性。
- Adjusted R-squared: 对加入过多因子进行惩罚的 R²。
- 高 R² 通常对风险模型更重要。
-
因子收益率的显著性与稳定性 (Factor Return Significance & Stability):
- 分析通过截面回归估计出的因子收益率 (
beta_t
) 时间序列:- 均值 (Mean): Alpha 因子应具有显著非零的均值,风险因子不一定。
- 标准差 (Std Dev): 衡量因子收益的波动性,越小越稳定。
- t 统计量序列: 来自每次截面回归的 t 值 (
beta_t / std_error(beta_t)
)。 - 平均绝对 t 值:
mean(abs(t_t))
,越高越好。 - |t|>2 占比: 因子显著的期数占比,越高越好。
- 因子夏普比率:
mean(beta_t) / std(beta_t)
(年化),衡量因子自身的风险调整后收益。
- 分析通过截面回归估计出的因子收益率 (
-
因子预测能力 (Predictive Power - 主要对 Alpha 模型):
- 信息系数 (IC): 因子暴露与未来收益率的截面相关性 (IC 序列)。
- 平均 IC:
mean(IC_t)
,越高越好。 - IC 标准差:
std(IC_t)
,越小越稳定。 - 信息比率 (IR):
IR = mean(IC_t) / std(IC_t)
,衡量预测能力稳定性,是评价 Alpha 因子/模型的核心指标。 - IC>0 (或<0) 占比: 预测方向正确的期数占比。
-
模型稳定性 (Model Stability):
- 因子暴露稳定性: 股票在因子上的暴露度是否随时间剧烈变化?(高换手率可能意味着模型不稳定或交易成本高)。
- 因子收益稳定性: 因子收益率序列的波动性、自相关性。
- 因子协方差矩阵稳定性 (对风险模型): 估计出的因子协方差矩阵随时间变化是否剧烈?(影响风险预测的可靠性)。
-
残差项分析 (Residual Analysis):
- 特异性收益 (Specific Return / Residual):
e = Y - X*beta
。 - 特异性风险 (Specific Risk): 残差的标准差。模型是否能有效降低特异性风险?残差的分布是否符合模型假设(如正态性)?
- 残差相关性: 残差之间是否还存在显著的截面相关性?如果是,可能意味着模型遗漏了重要的共同因子。
- 特异性收益 (Specific Return / Residual):
针对特定用途的评估:
- 风险模型:
- 风险预测准确性: 比较模型预测的组合波动率/VaR/Beta 与未来实现的波动率/VaR/Beta 是否接近。
- 协方差矩阵表现: 能否用于构建有效的最小方差组合或风险平价组合?
- Alpha 模型 / 策略回测:
- 因子组合/多空组合表现: 基于因子打分或预测构建的投资组合(如 Top vs Bottom 组合)的历史回测表现:收益率、夏普比率、最大回撤、信息比率 (相对于基准)。
- 策略整体表现: 经过优化和考虑交易成本后的完整策略回测表现。
- 业绩归因模型:
- 归因精度: 归因收益之和与实际收益的拟合程度(残差大小)。
- 归因解释性: 归因结果是否符合投资经理的预期和投资逻辑?
结论: 评估多因子模型是一个综合性的过程,需要结合定量指标(R², t-stats, IR, Sharpe Ratio 等)和定性分析(经济逻辑、稳定性、残差表现),并紧密围绕模型的预期用途进行。
2.17 如何判断现有因子是否足够解释收益率?【R^2可以辅助判断,也许有更好的标准?】
判断现有因子组是否“足够”解释收益率,没有一个绝对的阈值,需要结合模型的目的和多个角度来看:
-
R-squared (R²):
- 作用: R² 是最直接的衡量标准,表示模型中的因子解释了多少比例的样本内收益率方差(截面差异)。
- 局限:
- R² 是样本内指标,高 R² 不保证样本外表现。
- R² 会随因子数量增加而增加(或至少不减少),需要关注调整后 R² (Adjusted R²)。
- 没有公认的“足够”的 R² 水平。 对于风险模型,希望 R² 越高越好(常见 30%-60%),但过高也可能意味着过拟合。对于 Alpha 模型,可能不太关心 R²,而更关心 Alpha 预测的准确性。
- R² 值本身受市场状态影响很大。
-
残差分析 (Residual Analysis): 这是比 R² 更深入的判断方法。
- 残差的波动性 (Specific Risk): 如果模型的残差(特异性收益)波动率很大,说明有大量未被解释的风险。
- 残差的结构性:
- 残差自相关: 如果某只股票的残差序列自相关,说明模型未能完全捕捉其持续的特质性表现。
- 残差截面相关性: 如果不同股票在某一时期的残差显著相关,强烈暗示遗漏了重要的共同因子 (Missing Common Factors)。计算残差协方差矩阵,看非对角线元素是否接近于零。如果存在显著的非对角元素或模式(如行业内残差相关),则因子组不够充分。
- 残差与某些变量相关: 如果残差与某些未包含在模型中的变量(如某种宏观指标、某种新的另类数据)相关,说明这些变量可能代表了被遗漏的因子。
-
模型稳定性 (Model Stability):
- 如果加入新因子后,原有因子的收益率估计或因子协方差矩阵发生剧烈变化,可能说明原有因子组不够稳定或存在共线性问题,未能充分捕捉独立的风险维度。
-
与其他模型的比较:
- 将你的模型与公认的基准模型(如 Barra 模型、Fama-French 模型)在相同样本和时间段的表现进行比较(比较 R²、残差特性等)。
-
经济意义与先验知识:
- 现有因子组是否覆盖了已知的、重要的风险来源(市场、行业、主流风格)?是否有明显的遗漏?
更好的标准?
- 聚焦于残差的结构性分析,特别是残差的截面相关性,通常被认为是判断是否存在遗漏共同因子的更有力证据。一个好的风险模型,其残差(特异性收益)应该尽可能地“特质”,即彼此间低相关。
- 样本外表现 (Out-of-Sample Performance): 最终的检验标准是模型在样本外数据上的表现。如果模型在样本外能持续准确地预测风险(风险模型)或产生 Alpha(Alpha 模型),即使 R² 不是特别高,也可以认为是“足够”的。
结论: R² 是一个有用的初步指标,但不应作为唯一标准。更重要的是进行深入的残差分析(尤其是截面相关性),并结合模型的稳定性、经济意义和样本外表现来综合判断因子组的充分性。
2.18 中国股票市场多因子模型的R^2通常在什么量级?
中国 A 股市场多因子模型的截面 R² 没有一个固定值,它会受到多种因素的影响而变化,包括:
- 模型包含的因子类型和数量: 只包含少量风格因子的模型 R² 会低于包含行业因子和更多风格因子的模型。
- 市场环境:
- 风格/行业轮动明显的时期: 因子解释力会增强,R² 较高。
- 个股行情主导、市场分化小的时期: 共同因子解释力下降,R² 较低。
- 高波动时期: R² 可能升高,因为共同风险因素影响更大。
- 回归频率: 日频 R² 通常低于周频或月频 R²,因为日度数据噪声更大。
- 样本空间: 全市场股票的 R² 可能与特定指数成分股(如沪深 300)的 R² 不同。
- 模型具体设定: 如是否使用 WLS、因子定义细节等。
大致量级参考:
- 对于一个比较标准的、包含行业因子和主流风格因子(如 Barra CNE5 或类似框架)的月频风险模型,其截面 R² 的时间序列均值通常在 30% 到 60% 的范围内。
- 在某些市场环境下(如 2017 年大盘蓝筹行情,或 2021 年新能源行情),R² 可能超过 60% 甚至更高。
- 在某些市场环境下(如市场风格混乱、缺乏主线时),R² 可能低于 30%。
- 如果模型只包含风格因子(无行业因子),R² 通常会显著低于包含行业因子的模型,可能在 10% 到 40% 的范围。
- 如果是日频模型,R² 会更低,可能在 10% 到 30% 甚至更低的范围波动。
- Alpha 模型(如果指对原始收益率回归),R² 可能与风险模型相似。但如果 Alpha 模型关注的是对风险模型残差的解释,其 R² 通常会非常低,因为大部分波动已被风险因子解释。
重要提示: R² 只是模型评估的一个维度,并非越高越好。过高的 R² 可能意味着模型过度拟合了样本内数据,或者因子间存在高度共线性。对于风险模型,R² 的稳定性和残差的良好特性(低相关性)通常比追求极致的 R² 更重要。
2.19 为了提高R^2,尽可能多地加入各种因子,会导致什么问题?
这种“厨房水槽式 (Kitchen Sink)”的做法,即为了最大化 R² 而不加选择地堆砌因子,会导致一系列严重问题:
- 过拟合 (Overfitting): 这是最主要的问题。模型过度拟合了样本内的噪声和偶然关系,导致其在样本外(未来)的表现非常差。R² 提高的可能只是对噪声的解释,而不是对真实经济关系的捕捉。
- 多重共线性 (Multicollinearity): 加入大量因子,它们之间很可能存在较高的线性相关性。这会导致:
- 回归系数估计不稳定: 系数估计值对数据的微小变动非常敏感。
- 系数标准误增大: 使得单个因子的统计显著性下降,难以判断哪些因子真正重要。
- 系数符号或大小反常: 可能与经济直觉相悖。
- 模型不稳定 (Model Instability):
- 因子收益率估计不稳定,随时间波动剧烈。
- 因子协方差矩阵估计困难且不稳定,尤其当因子数量接近或超过时间序列长度时。
- 可解释性差 (Poor Interpretability): 包含大量(可能冗余或缺乏清晰逻辑的)因子的模型,很难理解每个因子的真实作用和经济含义,模型变成一个难以理解的“黑箱”。
- 数据挖掘偏差 (Data Mining Bias): 加入的因子越多,越有可能仅仅因为偶然性(而非真实效果)发现某些“显著”的因子,增加了模型基于虚假发现的风险。
- 交易成本增加 (Increased Transaction Costs): 基于复杂模型的策略可能需要更频繁的交易来调整对众多因子暴露的敞口,导致更高的交易成本,侵蚀实际收益。
- 计算复杂度与维护成本: 模型变得复杂,计算量大,数据需求多,维护成本高。
理论依据:
- 奥卡姆剃刀原则 (Occam’s Razor): 如无必要,勿增实体。在解释力相近的情况下,应选择更简单的模型。
- 信息准则 (Information Criteria): AIC (赤池信息准则) 和 BIC (贝叶斯信息准则) 等模型选择标准,会在模型拟合优度(似然函数值,与 R² 相关)和模型复杂度(因子数量)之间进行权衡,对过于复杂的模型进行惩罚。
结论: 盲目追求高 R² 而大量堆砌因子是构建多因子模型的大忌。应该基于经济逻辑、实证稳健性、因子间的低相关性以及模型目标,审慎地选择因子,构建简洁、稳健、可解释的模型。
2.20 如果一个因子与现有因子组均低相关,而且能够显著提高R^2,那么什么样的理由可能会使我们选择不加入这个因子?【因子收益率不稳定】
即使一个新因子 F_new 满足以下条件:
- 与现有因子组 F_existing 中的所有因子都低相关。
- 加入模型后能够显著提高 R²(或调整后 R²)。
我们仍可能选择不将其加入模型,主要理由包括:
- 缺乏经济逻辑或可解释性 (Lack of Economic Rationale - 最重要):
- 如果无法为这个新因子找到合理的经济、金融或行为学解释,说明它为何能解释收益率,那么它很可能是数据挖掘的产物或纯粹的统计巧合。这样的因子很可能在样本外失效。模型的可信度和稳健性建立在逻辑基础之上。
- 因子收益率不稳定 (Unstable Factor Return):
- 虽然该因子在样本内显著提高了 R²,但通过截面回归估计出的该因子的收益率序列 (
beta_t
) 可能极其不稳定:- 高波动性:
std(beta_t)
非常大。 - 低显著性: 因子收益率的 t 统计量序列
t_t
的均值(尤其是绝对值均值)可能不高,或者|t|>2
的占比很低,说明其效果在大部分时间里并不显著。 - 符号频繁变动:
beta_t
的正负号变化无常,没有明确的经济含义。
- 高波动性:
- 一个因子收益率不稳定的因子,即使能解释过去的波动,也难以用于未来的风险预测(协方差矩阵不稳定)或收益预测(预期收益不可靠)。正如提示所言,因子收益率不稳定是拒绝它的一个核心原因。
- 虽然该因子在样本内显著提高了 R²,但通过截面回归估计出的该因子的收益率序列 (
- 因子暴露本身不稳定 / 高换手率 (Unstable Exposure / High Turnover):
- 即使因子收益率相对稳定,如果股票在该因子上的暴露度变化非常快,导致基于该因子构建的组合需要极高的换手率,那么其带来的 R² 提升可能会被高昂的交易成本所抵消,使得该因子在实践中无法利用。
- 可投资性差 / 容量有限 (Poor Investability / Low Capacity):
- 该因子可能主要在流动性差、容量小的股票上表现出解释力。对于大型投资组合而言,无法在这些股票上建立足够的头寸,导致该因子的效果无法在实际投资中大规模复制。
- 数据质量问题或前视偏差 (Data Quality Issues or Lookahead Bias):
- 该因子的计算可能依赖于有问题的、不干净的数据,或者在计算过程中不经意地引入了前视偏差(使用了未来信息)。这使得其表现看起来很好,但实际上是虚假的。
- 与模型目标不符:
- 例如,在构建一个简洁、稳健、专注于核心风险的风险模型时,即使某个因子能略微提高 R²,但如果它逻辑不清晰、不稳定或增加了模型复杂度,也可能选择不加入。
结论: 显著提高 R² 只是因子价值的一个方面。经济逻辑、因子收益的稳定性、因子暴露的稳定性、可投资性、数据质量等都是必须考虑的重要因素。缺乏这些支撑,即使 R² 贡献显著,也应谨慎对待甚至拒绝该因子。
2.21 对于回归法因子测试,能否直接用不同截面的数据叠加在一起进行回归(即面板回归)?可能产生的后果是什么?【牛熊市数据可能分层了,掩盖真正的规律】
直接将不同截面(时间点)的数据叠加在一起,形成一个大的面板数据 (Panel Data),然后进行一次回归(如 Pooled OLS),理论上可以做,但在金融因子测试和建模实践中通常不推荐,除非使用特定的面板模型并谨慎解释。
直接使用简单面板回归(如 Pooled OLS)的后果:
-
忽略因子收益的时间变化 (Ignoring Time-Varying Factor Returns):
- 核心问题: Pooled OLS 假设因子对收益率的影响系数(即因子收益率
beta
)在所有时间截面上都是恒定的。这与金融市场的实际情况严重不符。因子(如价值、动量、规模)在不同市场环境(牛市/熊市、不同宏观周期)下的表现(收益率)是时变的。 - 后果: 用一个固定的
beta
去拟合所有时期的数据,会得到一个“平均”的系数,这个平均值可能掩盖了因子在不同时期的真实表现模式(如牛市有效、熊市失效,或符号反转)。如提示所言,“牛熊市数据可能分层了,掩盖真正的规律”。
- 核心问题: Pooled OLS 假设因子对收益率的影响系数(即因子收益率
-
未考虑时间固定效应 (Omitting Time Fixed Effects):
- 不同时间截面上的平均收益率水平是不同的(受整体市场涨跌影响)。Pooled OLS 如果不包含时间虚拟变量(Time Fixed Effects),就会将这种整体市场的时变效应错误地归因到其他因子上,导致系数估计偏差。
-
忽略个体固定效应 (Omitting Individual Fixed Effects):
- 不同股票可能有其固有的、不随时间变化的特性(如长期稳健的商业模式、特定的管理层风格等)会影响其平均收益水平。Pooled OLS 如果不包含个体虚拟变量(Individual Fixed Effects),可能会将这些个体异质性错误地归因于因子。
-
误差项相关性问题:
- 序列相关 (Serial Correlation): 同一只股票在不同时间点的误差项(特异性收益)可能存在自相关。
- 截面相关 (Cross-Sectional Dependence): 不同股票在同一时间点的误差项可能存在相关性(如存在未捕捉的共同冲击)。
- 异方差性 (Heteroskedasticity): 不同股票或不同时间的误差项方差可能不同。
- Pooled OLS 的标准误在存在这些相关性时是无效的,需要使用聚类稳健标准误 (Clustered Standard Errors) 或更复杂的面板模型(如 Fama-MacBeth 回归、固定效应/随机效应模型、动态面板模型)来处理。
更合适的处理方法:
-
Fama-MacBeth 回归 (Fama-MacBeth Regression): 这是金融领域处理面板数据进行资产定价测试的标准方法。
- 第一步 (Cross-Sectional Regression): 在每一个时间截面
t
上,进行截面回归Y_it = alpha_t + X_it * beta_t + e_it
,得到每个因子在该期的收益率估计值beta_t
。 - 第二步 (Time-Series Analysis): 将得到因子收益率时间序列
beta_t
,计算其均值、标准误、t 统计量等,以判断因子平均是否有效以及效果的稳定性。
- 优点: 明确允许因子收益率
beta_t
随时间变化,更符合金融实际。
- 第一步 (Cross-Sectional Regression): 在每一个时间截面
-
面板固定效应/随机效应模型 (Panel Fixed/Random Effects Models):
- 可以控制个体固定效应(FE)或假设个体效应是随机的(RE)。通过加入时间虚拟变量,也可以控制时间固定效应,间接允许因子收益率在不同时间有不同的基准水平。但标准的 FE/RE 模型仍假设因子系数
beta
是时不变的,除非进行扩展(如交互项)。
- 可以控制个体固定效应(FE)或假设个体效应是随机的(RE)。通过加入时间虚拟变量,也可以控制时间固定效应,间接允许因子收益率在不同时间有不同的基准水平。但标准的 FE/RE 模型仍假设因子系数
结论:
直接用 Pooled OLS 对叠加的截面数据进行回归,以期望得到因子平均收益,是一种非常粗糙且可能产生严重误导的方法,因为它忽略了因子收益的时变性以及复杂的误差结构。Fama-MacBeth 回归是进行因子有效性测试的标准方法。 如果确实需要使用面板模型,必须选择能够处理个体效应、时间效应以及误差相关性的高级面板模型,并谨慎解释结果。
2.22 进行多元回归时,如何检验共线性、异方差问题?如何解决?
在进行多元回归(如截面回归估计因子收益率)时,检验并处理多重共线性和异方差性是保证模型结果可靠性的重要步骤。
1. 多重共线性 (Multicollinearity): 指自变量(因子)之间存在较强的线性相关关系。
-
检验方法:
- 相关系数矩阵 (Correlation Matrix): 计算因子之间的两两相关系数。如果存在绝对值很高(如 > 0.7 或 0.8)的相关系数,则可能存在共线性问题。这是初步判断,不一定能发现涉及多个变量的共线性。
- 方差膨胀因子 (Variance Inflation Factor, VIF): 这是最常用且推荐的方法。对每个自变量
X_k
,将其作为因变量,对其他所有自变量进行回归,得到 R²_k。则VIF_k = 1 / (1 - R²_k)
。- 判读:
- VIF = 1: 不存在共线性。
- 1 < VIF < 5: 存在一定的共线性,通常可接受。
- 5 ≤ VIF ≤ 10: 存在较强的共线性,可能需要关注。
- VIF > 10: 存在严重的共线性,需要处理。
(这些阈值是经验法则,并非绝对)。
- 判读:
- 特征值分析 (Eigenvalue Analysis): 分析自变量矩阵
X'X
的特征值。如果存在非常接近于 0 的特征值,或者条件数 (Condition Number,最大特征值与最小特征值之比的平方根) 很大(如 > 30),则表明存在共线性。
-
解决方法:
- 剔除变量 (Variable Exclusion): 移除导致严重共线性的一个或多个因子。通常移除 VIF 最高的那个,或者根据经济意义判断哪个因子更冗余。
- 因子合并 (Factor Combination): 将高度相关的因子(如果它们代表相似的经济概念)合并成一个综合因子(如通过 PCA 或简单加权平均)。
- 逐步回归 (Stepwise Regression): 使用统计方法自动选择最优的因子子集(注意:可能导致模型不稳定或缺乏理论基础)。
- 主成分回归 (Principal Component Regression, PCR): 用少数几个互不相关的原始因子主成分来代替原始因子进行回归。缺点是主成分缺乏经济可解释性。
- 岭回归 (Ridge Regression): 在 OLS 的目标函数中加入一个 L2 范数惩罚项
lambda * sum(beta_j^2)
。它通过牺牲系数的无偏性来换取更稳定、方差更小的估计,对共线性不敏感。适用于因子数量较多或存在共线性时。 - Lasso 回归: 使用 L1 范数惩罚项
lambda * sum(|beta_j|)
,可以在估计系数的同时进行变量选择(将某些系数压缩为 0)。
2. 异方差性 (Heteroskedasticity): 指误差项的方差随观测值(或自变量)变化而变化。
-
检验方法:
- 残差图 (Residual Plots):
- 绘制残差 vs. 拟合值 (Fitted Values) 的散点图。如果残差呈现某种模式(如喇叭形、扇形),则表明存在异方差。
- 绘制残差 vs. 某个自变量 (因子) 的散点图。如果残差的离散程度随该自变量变化,表明异方差与该因子有关。
- 统计检验 (Statistical Tests):
- Breusch-Pagan (BP) 检验: 检验残差平方和是否与自变量相关。原假设是同方差。适用于线性形式的异方差。
- White 检验: 更通用的检验,允许异方差形式更复杂(包括自变量的平方和交叉项)。原假设是同方差。缺点是如果自变量较多,自由度消耗大。
- Goldfeld-Quandt (GQ) 检验: 用于检验异方差是否与某个特定变量(如市值)的排序有关。
- 残差图 (Residual Plots):
-
解决方法:
- 加权最小二乘法 (Weighted Least Squares, WLS): 如果知道异方差的结构(即知道误差方差
σ_i^2
与哪些变量成比例),可以使用 WLS,赋予方差较小的观测值更大的权重。如前所述,在金融中常用weights = sqrt(流通市值)
作为一种处理与规模相关的异方差的实用方法。 - 使用稳健标准误 (Robust Standard Errors): 这是最常用且方便的方法。它不改变 OLS/WLS 的系数估计值,但会修正标准误的计算公式,使其在存在异方差时仍然有效。
- White (HC0) 标准误: 最基础的稳健标准误。
- HC1, HC2, HC3 标准误: 对 White 标准误在小样本或高杠杆点情况下的修正。HC3 通常被认为在小样本下表现最好。
statsmodels
中可以通过results.get_robustcov_results(cov_type='HC1')
(或其他 HC 类型) 获得。
- 变量变换 (Variable Transformation): 对因变量 Y(收益率)或自变量 X(因子)进行变换(如取对数、Box-Cox 变换),有时可以稳定方差。但在金融中对收益率做变换较少。
- 模型重新设定 (Model Respecification): 异方差有时是因为模型形式设定不当(如遗漏变量、非线性关系未捕捉)。改进模型本身可能有助于解决异方差。
- 加权最小二乘法 (Weighted Least Squares, WLS): 如果知道异方差的结构(即知道误差方差
实践建议:
-
优先使用 VIF 检验共线性,并根据 VIF 值和经济意义决定处理方式(剔除、合并或使用 Ridge/Lasso)。
-
优先使用残差图和 White/BP 检验判断异方差。
-
对于异方差,使用稳健标准误 (如 HC1 或 HC3) 是最常用、最便捷的处理方式,因为它不要求知道异方差的具体形式。如果追求更有效的系数估计且对异方差结构有较强假设(如与市值相关),则 WLS 是一个选项。
-
Python 代码示例:
import pandas as pd
import numpy as np
import statsmodels.api as sm
from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.stats.diagnostic import het_breuschpagan, het_white
# 假设 results 是 OLS 或 WLS 回归的结果对象
# 假设 X 是包含截距项的自变量 DataFrame (n_samples, n_features+1)
# 假设 model 是拟合的模型对象
# --- 检验共线性 ---
def check_vif(X_df):
"""计算 VIF"""
# VIF 需要至少两个自变量 (加上截距项至少3列)
if X_df.shape[1] < 3:
print("需要至少两个自变量来计算VIF。")
return None
# 确保 X_df 是 DataFrame
if not isinstance(X_df, pd.DataFrame):
X_df = pd.DataFrame(X_df)
# 可能需要添加列名
X_df.columns = [f'feature_{i}' for i in range(X_df.shape[1])]
# VIF 需要排除截距项计算
X_vars = X_df.drop(columns=X_df.columns[0]) # 假设第一列是截距
vif_data = pd.DataFrame()
vif_data["feature"] = X_vars.columns
vif_data["VIF"] = [variance_inflation_factor(X_vars.values, i) for i in range(X_vars.shape[1])]
return vif_data
# vif_results = check_vif(X)
# if vif_results is not None:
# print("Variance Inflation Factor (VIF):")
# print(vif_results)
# --- 检验异方差 ---
# residuals = results.resid
# fitted_values = results.fittedvalues
# X_for_test = results.model.exog # 获取模型使用的自变量(可能包含截距)
# # 1. 残差图 (需要 matplotlib)
# import matplotlib.pyplot as plt
# plt.figure(figsize=(8, 5))
# plt.scatter(fitted_values, residuals)
# plt.xlabel("Fitted Values")
# plt.ylabel("Residuals")
# plt.title("Residuals vs Fitted Values Plot")
# plt.axhline(0, color='red', linestyle='--')
# plt.show()
# # 2. Breusch-Pagan 检验
# bp_test = het_breuschpagan(residuals, X_for_test)
# labels = ['LM Statistic', 'LM-Test p-value', 'F-Statistic', 'F-Test p-value']
# print("\nBreusch-Pagan Test:")
# print(dict(zip(labels, bp_test))) # p-value < 0.05 通常拒绝同方差的原假设
# # 3. White 检验
# white_test = het_white(residuals, X_for_test)
# labels = ['LM Statistic', 'LM-Test p-value', 'F-Statistic', 'F-Test p-value']
# print("\nWhite Test:")
# print(dict(zip(labels, white_test))) # p-value < 0.05 通常拒绝同方差的原假设
# --- 解决异方差:使用稳健标准误 ---
# results_robust = results.get_robustcov_results(cov_type='HC1') # HC0, HC1, HC2, HC3可选
# print("\nResults with Robust Standard Errors (HC1):")
# print(results_robust.summary())
2.23 无风险资产在各个市场应该如何选择?中国市场有哪些选择?各自的利弊(例如历史长度、数据完整性、代表性等)?
无风险利率 (Risk-Free Rate) 是多因子模型(尤其是计算 Alpha、Beta、夏普比率等指标时)和资产定价中的一个重要基准。理想的无风险资产应具备零违约风险、零再投资风险,且与投资者的投资期限相匹配。实践中不存在完美的无风险资产,需要选择合适的代理 (Proxy)。
选择原则:
- 违约风险极低: 通常选择由信用等级最高的政府发行的短期债务。
- 流动性好: 市场交易活跃,价格能够及时反映信息。
- 期限匹配: 无风险利率的期限应与所评估的投资或现金流的期限相匹配。但在因子模型中,通常使用短期无风险利率作为基准。
- 数据可得性: 具有足够长的历史数据,且数据质量可靠、更新及时。
中国市场的无风险利率选择:
中国市场常用的无风险利率代理包括:
-
银行间回购利率 (Interbank Repo Rate):
- 代表: DR007 (存款类机构间 7 天期质押式回购加权平均利率)、R007 (银行间 7 天期质押式回购加权平均利率)。DR 系列质押品等级更高,更能反映银行体系流动性成本。
- 优点:
- 市场化程度高,能较好反映短期资金成本和流动性状况。
- 交易活跃,数据实时性好。
- DR007 已成为央行货币政策操作的重要参考,代表性强。
- 缺点:
- 历史相对较短: DR 系列是 2014 年底推出的,更长历史可能需要用 R 系列或其他指标替代/拼接。
- 波动性可能较大: 受短期流动性冲击影响明显。
- 严格来说是有抵押的回购利率,并非完全无风险(尽管风险极低)。
-
上海银行间同业拆放利率 (SHIBOR - Shanghai Interbank Offered Rate):
- 代表: 隔夜 (O/N)、1 周、2 周、1 个月、3 个月、6 个月、9 个月、1 年期 SHIBOR。常用 3 个月或 1 年期。
- 优点:
- 反映银行间无抵押拆借成本。
- 期限品种较多。
- 数据比较规范,有一定历史长度(2006 年开始)。
- 缺点:
- 报价机制: SHIBOR 是报价利率,可能不如基于实际交易的回购利率灵敏和真实。
- 存在一定的信用风险(无抵押)。
- 近年来其基准性有所下降(相对于 DR 系列)。
-
短期国债收益率 (Short-term Treasury Bill Yield):
- 代表: 3 个月、6 个月、1 年期国债到期收益率。
- 优点:
- 理论上最接近无风险: 由中央政府发行,违约风险最低。
- 概念清晰,符合金融理论定义。
- 缺点:
- 二级市场流动性可能不足: 中国短期国债市场相对于银行间市场,其流动性和交易活跃度可能稍差,导致收益率曲线有时不够平滑或不能完全反映市场即时信息。
- 数据获取: 获取高质量、高频率的二级市场到期收益率数据可能需要专业数据终端。一级市场发行利率不完全代表市场利率。
-
银行存款利率 (Bank Deposit Rate):
- 代表: 一年期定期存款基准利率(或实际利率)。
- 优点:
- 历史悠久: 数据可追溯时间很长。
- 非常稳定: 波动性极小。
- 数据容易获取。
- 缺点:
- 非市场化: 受到央行基准利率和利率上限的严格管制,不能反映市场真实的资金供求和风险定价。
- 代表性差: 与金融市场的实际回报率脱节。
- 忽略再投资风险: (虽然短期也存在)。
- 目前基本不被用作因子模型中的无风险利率基准。
常用选择与建议:
- 对于需要高频、市场化无风险利率的场景(如高频策略、日度风险计算),DR007 或 R007 是较好的选择。
- 对于中低频模型(月度)或学术研究,3 个月或 1 年期国债到期收益率 或 3 个月 SHIBOR 是常用的选择。国债理论上更优,但需要关注数据质量;SHIBOR 数据较易得。
- 一致性很重要: 在同一个模型体系内(如计算 Alpha、Beta、夏普率),应使用统一的无风险利率定义。
- 历史数据拼接: 如果需要很长的历史,可能需要将不同指标(如 R007 拼接 DR007,或用早期定存利率/国债发行利率拼接)进行合理处理。
结论: 中国市场无风险利率的选择需要在理论适当性、市场化程度、数据可得性和历史长度之间权衡。DR007、3 个月国债收益率、3 个月 SHIBOR 是当前比较主流和合理的选择,具体取决于应用场景。
2.24 计算beta值的基准(benchmark)如何选择?不同选择对整个模型影响有哪些方面?
计算 Beta 值(系统性风险)时,基准 (Benchmark) 的选择至关重要,因为它直接定义了“系统性风险”是什么。Beta 衡量的是个股(或组合)收益率相对于所选基准收益率的敏感度。
基准的选择:
常见的基准选择包括:
-
全市场指数 (Broad Market Index):
- 代表: 沪深 300 指数、中证 500 指数、中证 800 指数、中证全指、万得全 A 等。
- 目标: 衡量股票相对于整个 A 股市场的系统性风险。这是最常用的选择,尤其是在经典的 CAPM 框架下。
- 选择考虑: 指数的覆盖范围(大盘/中小盘/全市场)、编制方法(市值加权/等权)、流动性。
-
特定风格指数 (Style Index):
- 代表: 创业板指、科创 50 指数、国证 2000 指数 (小盘股)、上证 50 指数 (大盘蓝筹) 等。
- 目标: 衡量股票相对于特定市场板块或风格的 Beta。例如,计算一只创业板股票相对于创业板指的 Beta,可能比相对于沪深 300 的 Beta 更能反映其在该板块内的相对风险。
-
行业指数 (Industry Index):
- 代表: 申万一级行业指数、中信一级行业指数等。
- 目标: 衡量股票相对于其所属行业的 Beta。用于分析股票在行业内的相对波动性,或进行行业中性策略的风险控制。
-
自定义基准 (Custom Benchmark):
- 代表: 根据特定投资策略或组合特征构建的组合(如等权重市场组合、特定因子组合)。
- 目标: 衡量股票相对于特定投资策略或风险暴露的敏感度。
不同选择对模型的影响:
基准选择的改变会系统性地影响模型的多个方面:
-
Beta 值的改变:
- 最直接的影响。同一只股票,相对于沪深 300 的 Beta (β_300) 和相对于中证 1000 的 Beta (β_1000) 通常是不同的。Beta 值的大小和甚至排序都可能改变。
-
Alpha 值的改变:
- Alpha 通常定义为总收益扣除由 Beta 和基准收益解释的部分后的残差收益 (
Alpha = Return - Beta * Benchmark_Return - RiskFreeRate (如果用超额收益计算)
或从多元回归截距项得到)。基准变了,Beta 变了,基准收益也变了,因此计算出的 Alpha 也会改变。一个相对于沪深 300 有正 Alpha 的股票,可能相对于创业板指是负 Alpha。
- Alpha 通常定义为总收益扣除由 Beta 和基准收益解释的部分后的残差收益 (
-
风险分解的改变:
- 总风险可以分解为系统性风险 (Beta² * Benchmark_Variance) 和特异性风险 (Residual_Variance)。改变基准会改变系统性风险和特异性风险的划分比例。通常,选择与股票本身特征更相关的基准(如小盘股用小盘指数作基准),可能会解释更多的波动,使得分解出的特异性风险更小。
-
因子模型中“市场因子”的定义:
- 如果多因子模型中明确包含一个“市场 Beta”因子,那么这个因子的暴露度就是相对于所选基准计算的 Beta。改变基准等于改变了这个市场因子的定义和暴露度,会影响其他因子(如风格因子、行业因子)的系数估计(因为它们是控制了市场因子后的边际效应)。
-
业绩归因结果:
- 业绩归因通常会将组合收益分解为市场时机(来自基准暴露)、风格/行业暴露、选股能力(Alpha)等部分。基准的选择直接影响市场时机部分的贡献,并间接影响其他部分的归因结果。
结论:
Beta 基准的选择没有绝对的对错,关键在于与分析的目标和模型的应用场景保持一致。
- 对于衡量整体市场风险、应用 CAPM 或作为通用风险模型,通常选择广泛的、市值加权的全市场指数。
- 对于特定策略(如行业轮动、风格轮动)的风险管理或业绩归因,可能需要选择相应的行业指数或风格指数作为基准。
- 最重要的是:一旦选择了基准,就要在整个模型分析和应用中保持一致性,并且清楚所选基准对 Beta、Alpha 及其他结果的含义和局限性。
2.25 似乎研究者已经惯于用线性模型来解释收益率,为什么不用更复杂的模型?(或者已经存在什么非线性的结果?)
线性模型(如 Y = alpha + X*beta + e
)在金融收益率建模中占据主导地位,主要原因包括:
线性模型的优势:
- 简洁性与易解释性 (Simplicity & Interpretability): 线性关系最容易理解和解释。系数
beta
的含义清晰:因子暴露每增加一个单位,预期收益率变化多少。这对于理解风险来源、构建可解释的投资策略至关重要。 - 理论基础 (Theoretical Foundation): 许多经典的资产定价理论,如 CAPM 和 APT,本身就是线性模型。这为线性模型提供了强大的理论支撑。
- 稳健性与数据需求 (Robustness & Data Requirements): 金融数据通常信噪比低(噪声远大于信号)。复杂的非线性模型更容易拟合噪声,导致过拟合,在样本外表现很差。线性模型相对更稳健,对数据量的要求也低于复杂模型。
- 计算与处理的便利性 (Computational Tractability): 线性模型的估计(OLS, WLS)、推断(t 检验, F 检验)以及在组合优化中的应用(如均值方差优化框架通常基于线性的预期收益和二次型的风险)都相对成熟和高效。
非线性模型的使用与存在的问题:
尽管线性模型是主流,但研究和实践中也越来越多地探索和应用非线性模型,因为认识到市场并非完全线性:
-
存在的非线性结果/现象:
- 因子效应的阈值/区间效应 (Threshold Effects): 某些因子可能只在特定取值范围或超过某个阈值后才有效。例如,极低估值或极高动量的股票效应可能更强。
- 因子间的交互效应 (Interaction Effects): 不同因子的组合效果可能不是简单的线性叠加。例如,价值因子可能在高质量股票上效果更好(Value * Quality 交互)。
- 风险因子的非线性暴露 (Non-linear Risk Exposure): 股票对市场风险的暴露(Beta)可能随市场状态变化(如熊市时 Beta 可能更高)。期权等衍生品本身就具有非线性收益结构。
- 市场状态依赖 (State Dependency): 因子效果可能依赖于宏观经济状态(如利率水平、通胀预期)或市场情绪(如 VIX 指数)。
-
处理非线性的方法:
- 在因子层面处理 (Factor Engineering):
- 非线性变换: 对原始因子进行非线性变换(如平方项、对数、分箱/虚拟变量化)后再纳入线性模型。
- 交互项: 在线性模型中明确加入因子之间的交互项 (
X1 * X2
)。 - 条件因子: 构建随市场状态变化的因子暴露。
- 使用非线性模型 (Non-linear Models):
- 机器学习模型:
- 树模型 (Tree-based Models): 如随机森林 (Random Forest)、梯度提升树 (GBDT, XGBoost, LightGBM)。能够自动捕捉高维数据的非线性和交互效应,常用于股票排序或分类预测。
- 神经网络 (Neural Networks): 能够拟合极其复杂的非线性关系,但需要大量数据,且是“黑箱”,可解释性差。
- 核方法 (Kernel Methods): 如支持向量回归 (SVR) 使用核技巧将数据映射到高维空间寻找线性关系。
- 分位数回归 (Quantile Regression): 估计因子对收益率分布的不同分位数(而不仅仅是均值)的影响,可以捕捉异质性效应。
- 阈值模型/状态转换模型 (Threshold/Regime-Switching Models): 明确假设模型参数随某个观测变量(阈值)或不可观测的状态(如牛熊市)变化。
- 机器学习模型:
- 在因子层面处理 (Factor Engineering):
-
非线性模型的挑战:
- 过拟合风险高: 非常容易拟合样本内噪声。
- 可解释性差: 尤其是机器学习模型,难以理解为何模型做出某个预测(“黑箱”问题)。这对于风险管理和投资决策的信任度是很大障碍。
- 模型不稳定: 模型可能对输入数据的微小变化非常敏感。
- 数据需求大: 复杂模型通常需要更多数据来有效训练。
- 计算成本高: 训练和预测可能需要更多计算资源。
结论:
线性模型因其简洁性、可解释性、理论基础和稳健性而成为主流。然而,市场存在非线性特征,研究者和实践者正在越来越多地通过因子工程(在因子层面引入非线性)或直接应用非线性模型(尤其是机器学习)来捕捉这些复杂性。后者面临的主要挑战是过拟合和可解释性。未来可能会看到更多线性模型与非线性技术相结合的应用,以在提升预测能力和保持模型稳健性、可解释性之间取得平衡。
2.26 拟合多因子模型时,数据挖掘问题有多严重?怎样降低过拟合的程度?
数据挖掘 (Data Mining) / 过拟合 (Overfitting) 问题的严重性:
在多因子模型(尤其是 Alpha 因子挖掘)中,数据挖掘和过拟合问题极其严重。原因包括:
- 低信噪比 (Low Signal-to-Noise Ratio): 金融市场数据包含大量噪声,真实的、可持续的信号(Alpha)非常微弱。
- 多重测试偏差 (Multiple Testing Bias): 研究者通常会测试成百上千甚至更多的潜在因子。在如此多的测试中,即使所有因子都无效,也几乎必然会因为随机性而发现一些在样本内看起来“显著”的因子(假阳性)。
- 出版偏差/幸存者偏差 (Publication Bias / Survivorship Bias): 学术界和业界更倾向于报告和发表成功的因子,而忽略大量失败的尝试。这使得文献中看到的因子表现被高估。
- 模型复杂度易增: 研究者有动机不断尝试更复杂的因子定义或模型结构来“发现”Alpha。
- 数据共享与模仿: 一旦某个因子被发现并公开,其有效性可能会因为拥挤交易而迅速衰减。
后果: 基于数据挖掘或过拟合得到的因子模型,在样本内可能表现优异(高 R²、高夏普率),但在实际应用(样本外)中往往效果大打折扣,甚至亏损。
降低过拟合程度的方法 (Mitigation Strategies):
- 强调经济逻辑 (Emphasize Economic Rationale):
- 先有理论/逻辑,再找数据验证,而不是反过来。 优先考虑那些有坚实经济、金融或行为学基础支持的因子。对缺乏逻辑支撑但统计显著的因子保持高度怀疑。
- 严格的样本外测试 (Rigorous Out-of-Sample Testing):
- 时间分割: 将数据分为训练集 (In-Sample, IS) 和测试集 (Out-of-Sample, OOS)。所有因子发现、模型选择和参数调整只能在训练集上进行,最终效果必须在从未用于模型构建的测试集上进行评估。测试集应足够长,并包含不同的市场环境。
- 滚动/扩展窗口: 使用滚动窗口或扩展窗口进行回测,模拟模型在实际应用中不断用新数据更新的过程。
- 跨市场测试 (Cross-Market Validation): 如果可行,在其他国家或地区的市场测试因子的有效性。
- 交叉验证 (Cross-Validation):
- 在训练集内部使用交叉验证(如 K-Fold CV,或针对时间序列的 TimeSeriesSplit)来选择模型、调整超参数,以获得更稳健的性能估计。
- 保持模型简洁 (Promote Parsimony - Occam’s Razor):
- 限制因子数量: 倾向于使用更少的、解释力强的因子,而不是大量弱因子。
- 使用调整后 R² 或信息准则 (AIC/BIC): 这些指标会对模型复杂度进行惩罚,帮助选择更简洁的模型。
- 因子筛选标准从严 (Raise the Bar for Significance):
- 更高的 t 值门槛: 考虑到多重测试问题,一些研究建议将因子显著性的 t 值门槛提高到 3 或更高(而不是传统的 2)。
- 关注稳定性: 不仅看平均效果,更要看效果的稳定性(如 IR,低波动因子收益)。
- 因子半衰期: 估计因子的信息衰减速度,偏好更持久的因子。
- 稳健性检查 (Robustness Checks):
- 测试因子效果对不同定义方式、不同样本空间、不同时间段、不同预处理方法(如 Winsorization 阈值)的敏感性。稳健的因子应该对这些变动不敏感。
- 使用正则化方法 (Regularization Techniques):
- 岭回归 (Ridge): 通过 L2 惩罚项压缩系数,降低模型复杂度,提高稳定性。
- Lasso 回归: 通过 L1 惩罚项进行变量选择,剔除冗余或不重要的因子。
- Elastic Net: 结合 L1 和 L2 惩罚。
正则化有助于在拟合数据的同时控制模型复杂度,降低过拟合风险。
- 记录研究过程 (Document the Process):
- 详细记录所有尝试过的因子、模型和参数,以帮助评估可能存在的数据挖掘程度。
- 独立验证 (Independent Validation):
- 由独立的团队或研究者使用相同或不同数据源对模型进行验证。
结论: 数据挖掘和过拟合是多因子建模(尤其是 Alpha 挖掘)中的核心挑战。降低其风险需要严谨的研究方法论,包括强调经济逻辑、严格的样本外测试、保持模型简洁、从严设定标准、进行稳健性检查以及利用正则化等技术手段。没有单一方法能完全消除风险,需要多管齐下。

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)