4、行业中性化原理:为什么要做行业中性化、行业分类标准、中性化数学原理

这一节,我们来聊聊行业中性化。

说实话,这是我在实际工作中踩坑最多的地方之一。刚入行那会儿,我辛辛苦苦挖了一个因子,回测曲线漂亮得不行,结果拿去实盘,直接翻车。后来一查,好家伙,因子暴露全压在某个行业上,市场风格一转,直接把我打回原形。

所以,行业中性化不是锦上添花,而是保命用的。

4.1 为什么要做行业中性化

先问一个问题:你选出来的股票,到底是因子在起作用,还是行业在起作用?

举个例子。你发现市盈率低的股票表现好。但仔细一看,这些低市盈率的股票全是银行股。那到底是「低市盈率」这个因子有效,还是「银行板块」本身在涨?

你想想看,如果不做行业中性化,你的因子组合其实偷偷暴露了行业风险。一旦银行板块暴跌,你的因子组合也跟着崩。这锅背得冤不冤?

核心观点:行业中性化的目的,就是剥离掉行业对因子收益的影响,让因子纯粹地反映个股自身的选股能力。

我在项目中遇到过一件事。有个同事做了一个「营收增长因子」,回测年化超额收益15%。我一看持仓,80%的仓位在新能源行业。那段时间新能源正好是风口,猪都能飞。后来风口过了,因子直接变成负收益。这就是典型的「行业伪装成因子」。

所以,行业中性化要解决三个问题:

  • 消除行业偏差:不让某个行业主导因子的表现
  • 提升因子纯净度:让因子真正反映个股的alpha能力
  • 增强组合稳健性:避免因子收益被行业轮动带偏

4.2 行业分类标准

做中性化,首先得有个分类标准。总不能你说这是科技股,我说这是消费股,那还怎么玩?

目前主流的行业分类标准,我列一下:

分类标准 全称 层级 常见应用
GICS 全球行业分类标准 11个行业、24个行业组、69个行业 MSCI、标普指数
ICB 行业分类基准 11个行业、20个超行业、45个行业 富时罗素、欧洲市场
申万 申银万国行业分类 31个一级行业、134个二级行业 A股市场主流
中信 中信证券行业分类 30个一级行业、110个二级行业 国内机构常用

我个人习惯用申万一级行业分类做中性化。为什么?因为A股市场里,申万分类的覆盖面最广,数据也最容易获取。而且31个行业,数量适中,既不会太粗导致中性化效果差,也不会太细导致每个行业里股票太少。

小提示:行业分类不是越细越好。如果某个行业里只有三五只股票,中性化之后因子值会被严重压缩,反而失去区分度。我一般建议一级行业至少要有20只以上的股票。

4.3 中性化数学原理

好了,到了硬核部分。行业中性化到底怎么做?

说白了,就是两步:

  1. 识别行业暴露:每个股票属于哪个行业,这就是它的行业暴露
  2. 剥离行业影响:把因子值中能被行业解释的部分去掉,剩下的就是纯净的因子

数学上,我们通常用回归的方法。假设因子值为 \( y \),行业虚拟变量为 \( X \),那么:

y = X * β + ε

其中:

  • \( y \) 是原始因子值(比如市盈率倒数、动量等)
  • \( X \) 是行业虚拟变量矩阵(每个股票属于哪个行业,对应位置为1,其余为0)
  • \( β \) 是行业收益系数
  • \( ε \) 是残差,也就是中性化之后的纯净因子

我们真正要的,就是 \( ε \)。它代表「剔除了行业影响之后,个股在因子上的独特表现」。

关键公式:

中性化因子 = 原始因子 - 行业均值

或者更精确地:中性化因子 = 原始因子 - 行业虚拟变量回归的拟合值

嗯,这里要注意。最简单的做法是直接减去行业均值。但这样做有个问题——它假设每个行业对因子的影响是线性的、同质的。实际上,不同行业的因子分布可能差异很大,直接用均值减,效果不一定好。

我建议用回归法。代码实现也很简单:

import pandas as pd
import statsmodels.api as sm

# 假设 df 包含因子值 factor 和行业标签 industry
# 生成行业虚拟变量
dummies = pd.get_dummies(df['industry'], prefix='ind')
# 添加截距项(注意:要drop掉一个虚拟变量避免多重共线性)
X = sm.add_constant(dummies.iloc[:, 1:])
y = df['factor']

# 回归
model = sm.OLS(y, X).fit()
# 残差就是中性化后的因子
df['factor_neutral'] = model.resid

这段代码我用了很多年。每次跑完回归,我都会看一眼残差的分布。如果残差还有明显的行业聚集,说明中性化不彻底,得检查一下是不是行业分类太粗或者数据有问题。

避坑指南:我曾经犯过一个低级错误——做回归时忘了drop掉一个虚拟变量。结果模型报错说「奇异矩阵」,我查了半天才发现是多重共线性。记住,k个行业只需要k-1个虚拟变量,剩下的那个作为基准组。

4.4 行业中性化的可视化理解

光说数学可能有点抽象。我画了一张图,帮你直观理解:

行业中性化原理示意图 原始因子分布 行业A 行业B 行业C 行业A因子值偏高 行业B因子值中等 行业C因子值偏低 减去 行业 均值 中性化后因子分布 行业A 行业B 行业C 各行业因子值趋于一致 行业差异被剥离 保留个股自身alpha 原始因子中,行业A明显偏高,行业C明显偏低 中性化后,各行业因子均值归零,只保留个股差异

你看,左边是原始因子,行业A的因子值明显高于行业C。如果不做中性化,你选出来的股票大概率集中在行业A。右边是中性化之后,各行业的因子均值被拉平了,这时候选股才真正看的是个股本身的质量。

4.5 实战中的几个细节

最后,分享几个我在实战中总结的经验:

  • 频率问题:行业中性化一般每月做一次就够了。太频繁反而引入噪音,太稀疏又跟不上行业变化。
  • 极端值处理:做中性化之前,先把因子值的极端值处理一下(比如MAD缩尾)。否则一个极端值会把整个行业的均值拉偏。
  • 行业合并:如果某个行业股票太少(比如少于10只),我建议合并到相近的行业里,或者直接用二级行业分类。
  • 交叉验证:中性化之后,我习惯算一下每个行业的因子均值。如果某个行业的均值显著不为零,说明中性化没做干净。

一个小技巧:做完行业中性化之后,可以画一张箱线图,看看每个行业的因子分布是否真的对齐了。如果还有明显的偏移,赶紧回去检查代码。

好了,行业中性化的原理就讲到这里。说白了,就是让因子回归它本来的样子——选股,而不是选行业。


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