施密特正交化_量化投资因子正交化

施密特正交化_量化投资因子正交化原创 量化小白 H 量化小白上分记本系列的第一篇因子加权方法中提到 对于因子间有相关性的情况 可以通过最大化 IR 来解决 但也会存在另一个问题 因子协方差矩阵的估计 文中对比了最原始的样本协差阵和 Ledoit 压缩估计量结果的差异 表明协方差矩阵的估计效果对于结果有很大影响 本文给出另一种更为常用的解决因子间相关性的方法 因子正交化 01 背景因子多重共线性如上一篇所述 传统的多因子模型一般

原创: 量化小白H 量化小白上分记 

本系列的第一篇因子加权方法中提到,对于因子间有相关性的情况,可以通过最大化IR来解决,但也会存在另一个问题:因子协方差矩阵的估计,文中对比了最原始的样本协差阵和Ledoit压缩估计量结果的差异,表明协方差矩阵的估计效果对于结果有很大影响。本文给出另一种更为常用的解决因子间相关性的方法:因子正交化。

01

背景

因子多重共线性

如上一篇所述,传统的多因子模型一般采用IC加权、ICIR加权等方法,这些方法都是以IC为基础确定各因子在模型中的权重。而IC是当期因子暴露与下一期收益间的相关系数。如果因子间存在较强的相关性/相关性,通过上述加权方式,最终会导致因子对于某种风格的因子重复暴露。使得整个组合的表现严重偏向于该因子,削弱其他因子的效果。具体来说,当因子表现好时,组合会获得更高的超额收益,但因子表现不好时,也会出现更大幅的回撤。

举个栗子,在上篇三因子组合市净率1个月动量市值的基础上,加入流通市值因子进行四因子组合。采用过去24个月ICIR加权、月度调仓的方式。组合从2012年1月-2018年12月的表现如下

ee7f7871ff1998810dc087e7826357a0.png

基准采用沪深300指数,显然,四因子组合由于在估摸因子上的重复暴露,导致15年股灾之后,相较于三因子组合出现了超额增长,但在17年规模因子失效后出现了更大回撤。

正交相关定义

首先给出正交相关的一些概念,忘记的可以再翻一翻线性代数/高等代数。

fe8d06dd75891898dd37020b0ca88560.png

此外,有兴趣可以再去看看正交变换、旋转放缩变换的矩阵表达式,可以加深理解。

因子正交化统一框架

对于因子多重共线性的问题,可以通过因子正交化的方法来解决。因子正交化有多种方式。目前应用最多的有四种:回归取残差施密特正交化规范正交化对称正交化。其中,后三种都是通过因子旋转的方式来消除因子间的相关性,而第一种,后文会给出证明,实质上跟施密特正交化是一致的。因此,首先对后三种正交化方式给出统一说明(这部分参考了报告[1][2],觉得描述不清楚的可以再去看看报告):

250b874230ee3b4c0922ef13c58b8112.png

标准化的意义在于,正交跟不相关的概念本来是不等价的,正交不一定不相关,但加上Z-SCORE标准化之后,正交等价于线性相关系数为0

e653cbb8888c12e24f76efb5b3fd7af7.png

5136445a6d1d6e012e04aeb6693fede5.png

4b321be90042c803e09b8bab4ac7d9c1.png

以上是因子正交框架,不同的正交化方法具有不同的特性,接下来一一说明,并给出代码。

02

施密特正交化

施密特正交化就是高等代数教科书上的方法,给定一组向量后,分两步操作,第一步按照一定顺序把每个向量与之前所有向量进行正交。第二步对于正交后的向量进行归一化,最终得到的所有向量两两正交且模为1,正交后的因子暴露矩阵为正交阵,用公式表达为

34fb8cac9edba26e597a29902d9769a5.png

d4d2248aa9280b6aecd91005b91738f6.png

这里给出的代码里正交顺序是直接按照输入因子矩阵的顺序,从左向右依次正交。输入factors为已经标准化后的因子矩阵,返回Q为正交因子矩阵。

# 固定顺序的施密特正交化
   def Schimidt(self,factors):
       class_mkt = factors[['mkt_cap','classname']]
       factors1 = factors.drop(['mkt_cap','classname'],axis = 1)
       col_name = factors1.columns
       factors1 = factors1.values
      
       R = np.zeros((factors1.shape[1], factors1.shape[1]))
       Q = np.zeros(factors1.shape)
       for k in range(0, factors1.shape[1]):
           R[k, k] = np.sqrt(np.dot(factors1[:, k], factors1[:, k]))
           Q[:, k] = factors1[:, k]/R[k, k]
           for j in range(k+1, factors1.shape[1]):
               R[k, j] = np.dot(Q[:, k], factors1[:, j])
               factors1[:, j] = factors1[:, j] - R[k, j]*Q[:, k]

       Q = pd.DataFrame(Q,columns = col_name,index = factors.index)
       Q = pd.concat([Q,class_mkt],axis = 1)
       return Q




















































注意这里不能用python中的QR分解函数np.linalg.qr计算,施密特正交化是QR分解的一种方法,但numpy的QR分解函数并不是用这种方法做的。

03

回归取残差

回归取残差的方法过程类似施密特正交化,按照一定的顺序将每个向量同之前的所有向量回归取残差代替原值。接下里证明,施密特正交化与最小二乘下的回归取残差是一致的。差别仅在于,施密特正交化多了一步归一化。

95120f8bb426bd9851ddf9216c3f3440.png

2d7c3d68d3f97211e8cf3cab0142f276.png

54fe13f794267f948894f2b27232bbde.png

840a82a91d43d081d2ee14faedf80058.png

58f057aca3d96af38b0190e2da612ccd.png

04

规范正交化

规范正交化实际上跟主成分分析思路是一样的,但主成分分析在截面上应用可以,用在时间序列上就会出现对应关系不一致的问题,这也是规范正交化的问题。

d1ff9554b2f76c539c84e3aa9dfde9f0.png

# 规范正交
   def Canonial(self,factors):
       class_mkt = factors[['mkt_cap','classname']]
       factors1 = factors.drop(['mkt_cap','classname'],axis = 1)
       col_name = factors1.columns     
       D,U=np.linalg.eig(np.dot(factors1.T,factors1))
       S = np.dot(U,np.diag(D(-0.5)))
       
       Fhat = np.dot(factors1,S)
       Fhat = pd.DataFrame(Fhat,columns = col_name,index = factors.index)
       Fhat = pd.concat([Fhat,class_mkt],axis = 1)        

       return Fhat


































05

对称正交化

e83cc2e17e59a7685678559d00aaa06b.png

86eaf47de78ae7566e49cd47c541b4d0.png

# 对称正交
   def Symmetry(self,factors):
       class_mkt = factors[['mkt_cap','classname']]
       factors1 = factors.drop(['mkt_cap','classname'],axis = 1)
       col_name = factors1.columns     
       D,U=np.linalg.eig(np.dot(factors1.T,factors1))
       S = np.dot(U,np.diag(D(-0.5)))
       
       Fhat = np.dot(factors1,S)
       Fhat = np.dot(Fhat,U.T)
       Fhat = pd.DataFrame(Fhat,columns = col_name,index = factors.index)
       Fhat = pd.concat([Fhat,class_mkt],axis = 1)        

       return Fhat





































06

方法汇总与对比

038fd2374e9fb626322ab5cf0a408a6d.png

对于四因子组合,分别用上述三种因子正交化方法正交之后,组合表现如下

09f556192c06cbb8649198c66f521fb1.png

可以看出,对称正交化后的四因子组合表现与三因子表现几乎完全一致,表明对称正交非常完美的剔除了因子相关性的影响,其他三种正交化方法的效果一般,这也与文献【1】【2】中的结论一致。

07

参考文献

【1】-天风证券-天风证券金工专题报告:因子正交全攻略,理论、框架与实践

【2】-光大证券-光大证券多因子系列报告之十:因子正交与择时,基于分类模型的动态权重配置

【3】-海通证券-选股因子系列研究(十七):选股因子的正交

621aebef208fadc329a8422e0db3cc93.png

多因子尝试(一):因子加权

资产瞎配模型(一):MVO、风险平价等

资产瞎配模型(二):对(一)的纠正

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/209907.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 上午8:12
下一篇 2026年3月19日 上午8:12


相关推荐

  • OpenClaw架构解析:理解其模块化设计哲学

    OpenClaw架构解析:理解其模块化设计哲学

    2026年3月16日
    4
  • python:最大公约数和最小公倍数

    python:最大公约数和最小公倍数任务目标:1.输入两个数2.打印这两个数的最大公约数3.打印这两个数的最小公倍数实验环境:pycharm的python3.6实现代码:#最大公约数和最小公倍数a=int(input(‘请输入第一个数:’))b=int(input(‘请输入第二个数:’))Min=min(a,b)Gys=1foriinrange(1,int(Min+1)):…

    2022年5月13日
    44
  • linux smb访问windows(windows smb共享 设置)

    【SMB】windows配置访问smb服务器windows如何访问SMB服务器,大致有以下几种方法,建议采用第三种方式:使用windows系统自带的smb客户端进行访问通过windows自带的smb客户端进行访问的方式不可取,在勒索病毒事件后,445端口被禁用了,而windowssmb客户端默认访问445端口,因此使用该方法必然不可行使用代理的方式进行访问(不建议使用)Samba:基于公网IP的服务访问采用以上方式配置代理进行访问SMB服务器,成功

    2022年4月13日
    77
  • sendto & recvfrom 详解

    sendto & recvfrom 详解参考一:sendto和recvfrom一般用于UDP协议中,但是如果在TCP中connect函数调用后也可以用.sendto()和recvfrom()——利用数据报方式进行数据传输 1.在无连接的数据报socket方式下,由于本地socket并没有与远端机器建立连接,所以在发送数据时应指明目的地址,sendto()函数原型为:   intsendto(intsockf

    2022年7月23日
    34
  • Kerberos安装及集成hdfs、hive

    Kerberos安装及集成hdfs、hive环境 1 台 Centos6 5 主机部署 masterKDC2 台 Centos6 5 主机部署 KerberosClie Master 主机安装 Kerberosyumi serverkrb5 libskrb5 workstation y1 1 配置 kdc confvim var kerberos krb5kdc kdc conf kdcde

    2026年3月18日
    2
  • 测试用例编写_根据接口文档生成测试用例

    测试用例编写_根据接口文档生成测试用例前言写用例之前,我们应该熟悉API的详细信息。建议使用抓包工具Charles或AnyProxy进行抓包。har2case我们先来了解一下另一个项目har2case他的工作原理就是将当前主流的抓

    2022年7月30日
    9

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号