← 返回模块
4.2.3.3beta 可读 · 未来付费校验通过内容版本 2026-05-24

正交化与残差化

4.2.3 · 信号评估与合成 · 量化全流程

周四早上,你在上海的一家 量化 私募 的 因子 评估 会 上。 桌面 上 堆 着 K 条 信号 的 L1 + L2 诊断 包: 12-1 动量、 账面市值比、 毛利率 质量、 PEAD (post-earnings-announcement-drift) ——每 一条 都 通过 了 L2 的 break-even IC 门槛、 每 一条 月度 IC 都 在 0.025-0.035 之间。 研究 主管 提 一 句: 把 它 们 合 起来 复合 信号 IC 应该 在 0.10 附近 吧? 不。 你 算 出来 是 0.034。 拿 四 个 0.03 月度 IC 的 信号 等 权重 合 成,IC 几乎 没有 提升——因为 它 们 互相 之间 高度 相关 (沪深300 上 动量 与 价值 的 横截面 IC 相关 ~-0.4, 与 质量 ~0.3, 价值 与 质量 ~0.2)。 复合 信号 的 边际 信息 几乎 被 共同 因子 吃光 了。 这 一 课 教 你 解 决: 正交化 (orthogonalisation) 和 残差化 (residualisation) ——多 信号 评估 的 卫生 步骤,把 K 条 相关 信号 转 化 为 K 条 互 不 相关 的 正交 信号,只 拿 它 们 的 边际 IC 作为 复合 输入。

四 个 正交化 方法

业内 有 四 种 标准 方法,顺序 与 适用 场景 各 异:

(1) sequential_residualisation (顺序 残差化, 依赖 排序 的 OLS 残差 链): 第 一条 信号 保留 完整 IC; 后续 信号 各 自 对 之前 信号 做 OLS 回归 取 残差。 排序 是 研究 选择: 经济 优先 顺序 (动量 -> 价值 -> 质量 -> 事件) 或 研究 时序 顺序。

(2) symmetric_gram_schmidt (对 称 Gram-Schmidt, 通过 QR 分解 或 Löwdin S * (S^T S)^{-1/2} 实现): 无 排序 依赖, 同时 正交化 全部 信号; 产生 Frobenius 范数 最 接近 原始 信号 的 基底。 业内 没有 经济 排序 时 的 量产 默认。

(3) pca_orthogonalisation (PCA 主成分分析 正交化, 协方差矩阵 特征分解): 取 解释 ≥ 95% 方差 的 前 k 个 主成分; 解决 K > T 时 的 协方差矩阵 病态 问题, 代价 是 主成分 不可 直观 解释 (动量 + 价值 + 质量 三个 信号 的 PC1 通常 是 「factor 1」 而 不是 「动量」)。

(4) factor_neutralisation (因子 中性化, 残差 对 Barra-风格 行业 + 风格 因子暴露): 横截面 OLS 残差; 产生 idiosyncratic alpha (个 别 残差 alpha) ——剔除 已知 系统性 暴露 后 的 独立 信号。 沪深300 上 业内 用 Barra CNE6 + CITIC 一级 行业 30 类 作为 因子模型。

规则: ​每 一 条 候选 信号 加入 量产 复合 之前 都 先 对 已有 信号 簿 做 正交化; 决定 是否 接 纳 的 是 正交 IC (边际 贡献), 不是 raw IC。​

五 元 诊断 包

四 个 信号 正交化 之 后 携带 五 个 诊断 数字:

(1) raw_ic_correlation_matrix (K × K, 原始 IC 相关 ——问题 的 量化); (2) orth_ic_correlation_matrix (K × K, 正交化 后 应 近 对角 ——证 据); (3) orthogonal_ic_per_signal (每 条 信号 的 边际 贡献); (4) orthogonal_ic_ratio (正交 IC / raw IC, 接近 1 = 独立, 接近 0 = 冗余); (5) method_and_ordering (sequential / symmetric-GS / PCA / factor-neutralisation, 附 文档 化 的 排序 或 因子模型 引用)。

规则: ​任何 候选 信号 在 正交 IC 低于 L2 break-even IC 时 都 是 冗余, 从 复合 中 剔除。​

四 条 走 通 信号

整 课 的 工作 例 案 用 四 条 信号: (1) mom_12_1 (4.2.2 L2 的 12-1 月 动量); (2) book_to_market (4.2.2 L2 的 价值因子); (3) gross_profitability (4.2.2 L2 的 质量因子); (4) pead_sue (4.2.2 L3 的 PEAD 信号)。 横截面 IC 相关 的 典型 模式 在 沪深300 上 是: 动量 ↔ 价值 ~ -0.4, 动量 ↔ 质量 ~ 0.3, 价值 ↔ 质量 ~ 0.2, PEAD ↔ 其他 三 个 ~ 0.1。 规则: ​PEAD 通常 在 正交 IC 上 贡献 最高, 即使 它 raw IC 较低 ——动量 + 价值 + 质量 跨越 了 共同 因子 空间, PEAD 加 入 的 是 事件驱动 信息。​

对 称 Gram-Schmidt

业内 没 有 经济 排序 的 默认 工作: 把 信号 矩阵 同时 正交化, 不 区分 优先级。 三 步 计算 顺序:

(1) S = stack_signals_as_columns(signals) ——构 建 T × K 信号 矩阵, 每 列 一 个 标准化 (z-score 或 rank 化) 信号; (2) Q, R = numpy.linalg.qr(S) ——QR 分解, Q 的 各 列 是 正交 基底; (3) orthogonal_signals = Q * diag(sign_correction) ——可选 的 符号 修正, 让 每 一 列 Q 与 原 信号 相关 系数 为 正, 保留 可解释 性。

规则: ​没 有 经济 排序 时, 对 称 Gram-Schmidt 是 量产 默认。​

numpy.linalg.qr 是 QR 分解 (基于 奇异值分解 (SVD) 的 一 种 数值 稳定 实现 选择 也 可); 协方差矩阵 在 病态 时 不影响 QR (QR 不需要 矩阵 求逆)。 实现:

import numpy as np

def symmetric_orthogonalise(signal_matrix: np.ndarray) -> np.ndarray:
    # 1. 接收 T × K 标准化 信号 矩阵
    # 2. QR 分解: 列 Q 是 正交 基底
    Q, R = np.linalg.qr(signal_matrix)
    # 3. 符号 修正: 每 列 Q 与 原 信号 的 相关 取 正
    signs = np.sign(np.diag(R))
    return Q * signs

symmetric_orthogonalise 的 函数名、 参数 signal_matrix、 NumPy API numpy.linalg.qr、 以及 返回 形状, 在 中英 两版 中 字节 一致; 仅 注释 翻译。

因子 中性化

业内 量产 复合 通常 同时 做 信号-对-信号 的 正交化 信号-对-因子 的 中性化。 因子 中性化 是 把 每 条 信号 残差 对 已知 因子模型 (Barra CNE6 + CITIC 行业 dummies)的 暴露; 输出 是 该 信号 的 特征 alpha (idiosyncratic alpha), 即 与 已知 系统性 暴露 正交 的 部分。

三 步 计算:

(1) F_t = factor_exposures_at_date(t) ——在 调仓 日 t 取 N × F 因子暴露 矩阵 (Barra CNE6 风格 因子 + 行业 dummies); (2) beta_t = numpy.linalg.lstsq(F_t, s_t) ——横截面 OLS 回归 信号 对 因子暴露; (3) s_t_neutral = s_t - F_t @ beta_t ——横截面 残差, 即 idiosyncratic alpha。

规则: ​因子 中性化 剔除 已知 系统性 暴露; 信号 正交化 剔除 与 同 簿 信号 的 相关; 量产 复合 两 者 都 做。​

实现:

import numpy as np
import pandas as pd

def factor_neutralise(signal: pd.Series, factor_exposures: pd.DataFrame) -> pd.Series:
    # 1. 接收 (date, symbol) MultiIndex 的 信号 序列 与 因子暴露 DataFrame
    # 2. 按 date 分组, 横截面 OLS lstsq(F_t, s_t)
    def _resid(group):
        F = group[factor_exposures.columns].values
        s = group['s'].values
        beta, *_ = np.linalg.lstsq(F, s, rcond=None)
        # 3. 返回 残差 = idiosyncratic alpha
        return pd.Series(s - F @ beta, index=group.index)
    joined = factor_exposures.copy()
    joined['s'] = signal
    return joined.groupby(level='date').apply(_resid)

factor_neutralise 的 函数名、 参数 signal / factor_exposures、 以及 NumPy / pandas API 名 字, 在 中英 两版 中 字节 一致; 仅 注释 翻译。

Formula Explorer

s_neutral = s - F * beta

顺序 残差化 与 PCA: 何 时 用

顺序 残差化 适合 经济 排序 清晰 的 情形 ——研究 主管 已 经 决定 「动量 是 主 信号, 价值 是 增量, 质量 是 二阶 增量, PEAD 是 事件 修正」, 你 用 那 个 顺序 链式 残差化, 第 一条 保留 raw IC, 后续 保留 边际 IC。 缺点 是 排序 选择 对 边际 IC 有 实质 影响; 不同 顺序 给 出 不同 的 后续 信号 IC 数字。

PCA 正交化 适合 信号 数 K 接近 或 大于 时序 长度 T 的 场景。 沪深300 上 2015-2024 提供 ~2400 个 交易 日; 50+ 信号 的 协方差矩阵 在 短 子样 上 病态。 此时 取 前 k 主成分 (解释 ≥ 95% 方差) 把 K 维 降 到 k 维 (典型 k = 5-10), 协方差矩阵 在 主成分 空间 良态。 代价 是 主成分 不可 直观 解释。

四 个 方法 选 哪 个: 经济 排序 可 辩护 -> sequential; 协方差矩阵 良态 且 无 排序 -> symmetric Gram-Schmidt; K > T 或 协方差矩阵 病态 -> PCA; 量产 需要 与 风险 模型 暴露 隔离 -> factor neutralisation (常 与 前 三 个 之一 叠加)。

走 通 的 例子: 沪深300 四 信号

在 沪深300 universe 上 2018-2023 拿 四 条 信号: mom_12_1, book_to_market, gross_profitability, pead_sue。 月度 调仓, 21 日 前瞻 收益。

(1) 算 raw IC 相关 矩阵 4 × 4。 典型 模式: 动量 ↔ 价值 ~ -0.4 (动量 与 价值 经济 上 反 相关 ——价值 信号 买 估值 低 的 股票, 动量 信号 买 近期 上涨 的 股票, 这 两 类 部分 反 相关), 动量 ↔ 质量 ~ 0.3 (质量 因子 有 部分 趋势 表现), 价值 ↔ 质量 ~ 0.2 (低估 + 高质量 = Buffett 因子), PEAD ↔ 其他 ~ 0.1。

(2) 应用 对 称 Gram-Schmidt numpy.linalg.qr 得 4 列 正交 基底。 算 正交化 后 4 × 4 IC 相关 矩阵; 应 近 对角 (off-diagonal ≈ 0)。

(3) 算 每 条 正交 信号 的 IC; 算 正交 IC / raw IC 比 率。 典型 结果: 动量 raw 0.030 -> 正交 0.025 (比率 0.83 ——大部分 IC 是 独立 的); 价值 raw 0.030 -> 正交 0.020 (比率 0.67 ——价值 与 动量 部分 重叠 后, 边际 贡献 降低); 质量 raw 0.028 -> 正交 0.018 (比率 0.64); PEAD raw 0.026 -> 正交 0.024 (比率 0.92 ——事件驱动 信号 与 因子 信号 几乎 独立)。 PEAD 在 正交 IC 上 排名 第 二 仅 次 于 动量, 即 使 它 raw IC 最低。

(4) 应用 因子 中性化 (Barra CNE6 风格 因子 + CITIC 一级 行业 30 类 dummies); 算 中性化 残差 的 正交 IC。 期望 观察: 动量 的 正交 IC 显著 下降 (它 本 身 就 是 Barra 风格 因子 之 一 「Momentum」); 价值 的 正交 IC 也 下降 (Barra「Value」 因子 直接 残差 掉); 质量 的 正交 IC 略 降 (Barra「Profitability」 部分 重叠); PEAD 的 正交 IC 几 乎 不变 (PEAD 不 在 Barra CNE6 中)。

(5) 用 L2 的 break-even IC ≈ 0.02 月度 作 门槛 把 四 条 信号 过 关: 动量、 PEAD 通过, 价值、 质量 边际 不足 (但 因为 它 们 raw IC 仍然 显著, 实际 业内 会 保 留 它 们 在 复合 中, 只 是 权重 降低 ——L4 的 主题)。 转 入 L4 复合 构造。

与 L4 的 衔接

L1 + L2 完成 单 信号 评估, L3 完成 多 信号 卫生 步骤 ——你 现在 拥 有 一 组 互相 正交 的 信号 与 它 们 各自 的 边际 IC。 但 「正交 信号」 ≠ 「复合 信号」: 还 需 要 一 个 加权 方案 把 K 条 正交 信号 合 成 单 一 评分。 L4 教 你 怎么 加权: 等 权重 (w = 1/K)、 Markowitz 最优 (w = Σ^{-1} * IC)、 Ledoit-Wolf 收 缩 Markowitz (协方差矩阵 收 缩 防 病态)、 stacking (元 模型 学习 加 权)、 ensembling (多 种子 / 多 视界 / 多 模型 家族 平均)。 在 短 验证 集 上 (沪深300 ~1500 个 后-2015 交易 日 是 短 的) 等 权重 通常 击败 Markowitz; 收 缩 Markowitz 是 业内 量产 默认。 接下来 L4 把 你 在 L3 得 到 的 四 条 正交 信号 合 成 一 个 复合 评分 并 评估 样本外 IR ——这 就 是 整 个 4.2.3 craft 的 capstone。

课程 组件 (Lesson components)

​Inline-code 列表 四 个 经典 正交化 方法​​:

  1. sequential_residualisation (顺序 残差化, 依赖 排序 的 OLS 残差 链);
  2. symmetric_gram_schmidt (对 称 Gram-Schmidt, QR 分解 或 Löwdin 形 式);
  3. pca_orthogonalisation (PCA 主成分分析 正交化, 协方差矩阵 特征分解);
  4. factor_neutralisation (因子 中性化, 残差 对 Barra-风格 因子暴露)。

每 条 候选 信号 加 入 量产 复合 之前 都 先 正交化; 边际 IC 是 加 入 的 门槛。

​Inline-code 列表 五 元 正交化 诊断 包​​: raw_ic_correlation_matrixorth_ic_correlation_matrixorthogonal_ic_per_signalorthogonal_ic_ratiomethod_and_ordering。 正交 IC 低 于 L2 break-even IC 的 信号 是 冗余, 从 复合 中 剔除。

​Inline-code 列表 四 条 走 通 信号​​: mom_12_1book_to_marketgross_profitabilitypead_sue。 沪深300 上 经典 IC 相关 模式: 动量 ↔ 价值 ~ -0.4, 动量 ↔ 质量 ~ 0.3, 价值 ↔ 质量 ~ 0.2, PEAD ↔ 其他 ~ 0.1。

​Inline-code 列表 对 称 Gram-Schmidt 三 步 计算​​: S = stack_signals_as_columns(signals)Q, R = numpy.linalg.qr(S)orthogonal_signals = Q * diag(sign_correction)

​Inline-code 列表 因子 中性化 三 步 计算​​: F_t = factor_exposures_at_date(t)beta_t = numpy.linalg.lstsq(F_t, s_t)s_t_neutral = s_t - F_t @ beta_t

两 个 fenced python 块: symmetric_orthogonalise 函数 (QR 分解 + 符号 修正) 和 factor_neutralise 函数 (横截面 OLS 残差)。

L3 用 到 的 数学 词汇: 正交 (orthogonal, 内积 为 零 的 两 个 向 量); 主成分分析 (PCA); 奇异值分解 (SVD); 协方差矩阵; 特征分解 (eigendecomposition); 特征值 (eigenvalue); 特征向量 (eigenvector)。 信息比率 在 L3 边际 IC 度量 中 复用 ——边际 IR = 边际 IC * sqrt(BR); Alpha 衰减 的 词汇 在 L3 的 正交 IC 历史 退 化 上 重 现。 因子模型、 因子暴露 是 L3 因子 中 性 化 的 核 心 词汇 ——具 体 因子模型 (Barra CNE6 / Barra USE4) 是 4.3.1 的 主题。

练习

Exercise

给定 一个 signals_df (以 (date, symbol) 为 MultiIndex, 四 列: mom_12_1, book_to_market, gross_profitability, pead_sue) 和 一个 returns_df (以 (date, symbol) 为 MultiIndex, 列 fwd_21d_return), 在 沪深300 universe 上 2018-2023 范围 内 完成 五 项 任务。

(i) 算 4 × 4 raw rank-IC 相关 矩阵; 验证 经典 模式 (动量 ↔ 价值 ~ -0.4; 动量 ↔ 质量 ~ 0.3; 价值 ↔ 质量 ~ 0.2; PEAD ↔ 其他 ~ 0.1)。

(ii) 通过 numpy.linalg.qr 应用 对 称 Gram-Schmidt 正交化 产 出 4 列 正交 基底; 算 4 × 4 正交化 后 IC 相关 矩阵 并 验证 它 近 对角。

(iii) 算 每 个 信号 的 正交 IC; 算 正交 IC / raw IC 比 率; 找 出 正交 IC 贡献 最高 的 信号。

(iv) 应用 Barra CNE6 风格 因子 + CITIC 行业 dummies 的 因子 中性化; 算 中性化 残差 的 正交 IC; 观察 动量 的 正交 IC 显著 下降 (它 本 身 就 是 Barra 风格 因子) 而 PEAD 几 乎 不 变 (它 不 在 Barra 中)。

(v) 用 L2 的 IC_break_even ≈ 0.02 月度 把 四 条 信号 过 关; 说 明 哪 些 信号 通过 正交 IC 门槛 并 进入 L4 复合 构造。

提示
raw 相关 矩阵 是 signals_df.groupby(level='date').apply(lambda g: g.corr()) 的 跨 日 平均; QR 分解 是 numpy.linalg.qr(signal_matrix), 列 Q 即 正交 基底; 符号 修正 用 R 的 对角 符号。
提示
因子 中性化 是 横截面 OLS 残差: 在 每 个 调仓日 numpy.linalg.lstsq(F_t, s_t) 取 残差; PEAD 的 正交 IC 不 变 是 关键 验证, 它 不 在 Barra 中。