问题描述
我在网上看求IC的时候有两种处理方法:
第一种是直接用因子和收益率的数值调用 corr(method='spearman')方法求秩相关系数
第二种是先把因子和收益率分别取rank()
再调用 corr(method='spearman')方法求秩相关系数
请问哪种方法是对的?
解决方案
结论
第一种方法是正确且最标准的做法。
即:直接用因子和收益率的原始数值调用 corr(method='spearman')。
原理解析
要理解为什么第一种方法是对的,我们需要了解 Spearman秩相关系数(Spearman's rank correlation coefficient) 的数学定义以及 Pandas 库的底层实现逻辑。
1. Spearman 相关系数的本质
Spearman 秩相关系数的本质,就是先将原始数据转换为排名(Rank),然后对这些排名计算 Pearson(皮尔逊)线性相关系数。
2. Pandas 中 corr(method='spearman') 的底层逻辑
当你调用 Pandas 的 df.corr(method='spearman') 时,Pandas 内部会自动帮你完成以下两步:
- 对传入的数值列自动执行
rank()操作。 - 对 rank 后的结果计算 Pearson 相关系数。
因此,第一种方法直接调用 corr(method='spearman') 已经完整且正确地实现了 Rank IC 的计算。
3. 为什么第二种方法是“画蛇添足”?
如果你采用第二种方法(先手动 rank(),再调用 corr(method='spearman')),你的操作流程实际上变成了:
- 手动对原始数据取
rank()。 - Pandas 接收到你的 rank 数据后,因为你指定了
method='spearman',它会再次对你的 rank 数据取rank()。 - 最后计算 Pearson 相关系数。
虽然对排名数据再次取排名(排名的排名),在没有重复值(ties)的情况下结果和原来是一样的,最终算出来的 IC 值可能也完全相同,但这在逻辑上是重复操作,不仅增加了计算开销,而且在处理重复值时可能会引入微小的误差。
如果你非要手动先取 rank(),那么正确的做法应该是:
先取 rank(),然后调用 corr(method='pearson')。
在 JoinQuant 平台中的应用
在 JoinQuant(聚宽)平台进行单因子分析时,平台已经为你封装好了极其简便的 API,你甚至不需要手动去调用 Pandas 的 corr 方法。
使用聚宽的单因子分析工具 analyze_factor 后,可以直接调用相关方法计算 Rank IC:
from jqfactor import analyze_factor
# 假设你已经获取了因子数据并进行了分析
far = analyze_factor(factor=factor_data, ...)
# 计算每日因子信息系数(IC值),指定 method='rank' 即可直接计算 Rank IC
ic_df = far.calc_factor_information_coefficient(method='rank')
# 计算因子信息系数均值(IC值均值)
ic_mean = far.calc_mean_information_coefficient(method='rank')
在 JoinQuant 的底层实现中,当指定 method='rank' 时,系统正是采用了标准的第一种逻辑来为你计算秩相关系数的。