量化交易 第十二课 因子数据处理之市值中性化

概述

众所周知, 行业和市值是两个十分显著对因子有影响力的因素. 在进行截面回归判断每个单因子的收益情况和显著性时,需要特别关注这两个十分显著的因素. 市值中性化是为了在因子选股回测的时候, 防止选到的股票集中在固定的某些股票当中.
在这里插入图片描述

市值影响

大部分因子当中都包含了市值的影响. 所以当我们通过一些指标选择股票的时候, 每个因子都会提供市值的因素. 选择的股票就会比较集中, 及选股的标准不太好.

举个栗子, 市净率与市值有很高的相关性. 这时我们使用未进行市值中性化的市净率, 选股的结果会比较集中.

怎么去除市值影响

在这里插入图片描述

回归法

我们只会用到线性回归中最基础的内容. 不熟悉线性回归的同学可以看看我写的这篇博客:

回归 总结

简介

简单的来说我们将要去除市值影响的因子定义为 y, 市值因子定义为 x.
预测得到的偏差 (残差值) 即为市值对该因子的影响.
在这里插入图片描述

流程分析

我们拿市净率做为栗子, 来简单阐述一下市净率与市值之间的联系. 流程:

  1. 获取两个因子数据
  2. 对目标值因子市净率进行去极值
  3. 建立市值与市净率回归方程
  4. 通过回归系数, 预测新的因子结果 y_predict
  5. 求出市净率与 y_predict 的偏差即为新的因子值

代码实现

import numpy as np
from sklearn.linear_model import LinearRegression

def mad(factor):
    """3倍中位数去极值"""
    
    # 求出因子值的中位数
    median = np.median(factor)
    
    # 求出因子值与中位数的差值, 进行绝对值
    mad = np.median(abs(factor - median))
    
    # 定义几倍的中位数上下限
    high = median + (3 * 1.4826 * mad)
    low = median - (3 * 1.4826 * mad)
    
    # 替换上下限
    factor = np.where(factor > high, high, factor)
    factor = np.where(factor < low, low, factor)
    return factor

def stand(factor):
    """数据标准化"""
    mean = factor.mean()
    std = factor.std()
    return (factor - mean) / std

# 获取市净率和市值的数据
q = query(
    fundamentals.eod_derivative_indicator.pb_ratio,  # 市净率
    fundamentals.eod_derivative_indicator.market_cap  # 市值
)

# 获取截面数据
fund = get_fundamentals(q, entry_date="2021-01-03").iloc[:,0,:]
print(fund["pb_ratio"])  # 调试输出
print("--------------------------------------")

# 对pb_ration 进行去极值标准化处理
fund["pb_ratio"] = mad(fund["pb_ratio"])
fund["pb_ratio"] = stand(fund["pb_ratio"])

# 回归数据提取 x: 市值, y: 因子数据
x = fund["market_cap"].values.reshape(-1,1)
y = fund["pb_ratio"]

# 建立回归方程
lr = LinearRegression()
lr.fit(x, y)  # 拟合
y_predict = lr.predict(x)  # 预测

# 去除残差
fund["pb_ratio"] = y - y_predict
print(fund["pb_ratio"])  # 调试输出

输出结果:

688526.XSHG     7.4964
688286.XSHG     6.3164
688356.XSHG     7.9386
688004.XSHG     3.8863
688558.XSHG     2.9505
688418.XSHG     4.1119
688589.XSHG     5.1825
688569.XSHG     2.0132
688586.XSHG     6.5884
688077.XSHG     3.4511
688229.XSHG     5.4251
688065.XSHG     3.4576
688050.XSHG    12.2044
688106.XSHG     5.4171
688379.XSHG     2.4582
688580.XSHG      5.152
688060.XSHG     5.6061
688508.XSHG     8.5341
688600.XSHG     2.9436
688311.XSHG      8.758
688390.XSHG    15.0377
688155.XSHG     4.9158
688577.XSHG     3.1298
688556.XSHG     4.6791
688336.XSHG     3.2521
688585.XSHG     5.0047
688156.XSHG     2.7639
688157.XSHG     6.1503
688518.XSHG     3.2895
688208.XSHG    12.8005
                ...   
605168.XSHG     8.7524
605166.XSHG     2.8279
605177.XSHG     4.2882
605169.XSHG      5.862
605178.XSHG     1.7349
605179.XSHG     9.3183
605183.XSHG     4.0715
605186.XSHG    11.2112
605198.XSHG     3.9775
605188.XSHG      4.542
605199.XSHG     11.092
605218.XSHG     2.7977
605222.XSHG     3.1673
605255.XSHG     2.3709
605258.XSHG     5.8935
605266.XSHG     7.7229
605288.XSHG     3.2855
605299.XSHG     5.6859
605318.XSHG     2.3269
605336.XSHG     2.4506
605333.XSHG      7.976
605338.XSHG     5.9966
605358.XSHG    26.9882
605366.XSHG      2.443
605369.XSHG     3.8247
605377.XSHG     3.2595
605376.XSHG    18.0658
605388.XSHG     5.0266
605399.XSHG     3.0122
605500.XSHG     3.6253
Name: pb_ratio, Length: 4140, dtype: object
--------------------------------------
688526.XSHG      1.70633
688286.XSHG       1.2302
688356.XSHG      1.90345
688004.XSHG     0.225928
688558.XSHG    -0.163364
688418.XSHG     0.316995
688589.XSHG     0.762834
688569.XSHG    -0.553206
688586.XSHG      1.33677
688077.XSHG    0.0448572
688229.XSHG     0.862351
688065.XSHG    0.0130358
688050.XSHG      2.05539
688106.XSHG     0.848339
688379.XSHG    -0.366186
688580.XSHG      0.74662
688060.XSHG     0.937184
688508.XSHG      2.06342
688600.XSHG    -0.164907
688311.XSHG      2.06013
688390.XSHG      2.05246
688155.XSHG     0.650357
688577.XSHG   -0.0876943
688556.XSHG     0.552952
688336.XSHG   -0.0506448
688585.XSHG     0.687238
688156.XSHG    -0.239058
688157.XSHG      1.16128
688518.XSHG   -0.0237863
688208.XSHG       2.0419
                 ...    
605168.XSHG      2.06131
605166.XSHG    -0.213845
605177.XSHG     0.391245
605169.XSHG      1.04437
605178.XSHG     -0.66783
605179.XSHG      2.06724
605183.XSHG     0.298125
605186.XSHG      2.07071
605198.XSHG     0.257471
605188.XSHG     0.495605
605199.XSHG       2.0645
605218.XSHG    -0.226267
605222.XSHG   -0.0788161
605255.XSHG    -0.402446
605258.XSHG      1.05833
605266.XSHG      1.81468
605288.XSHG    -0.027241
605299.XSHG     0.970047
605318.XSHG    -0.420426
605336.XSHG    -0.371327
605333.XSHG      1.91961
605338.XSHG      1.09455
605358.XSHG      2.02334
605366.XSHG    -0.374542
605369.XSHG     0.198264
605377.XSHG    -0.035712
605376.XSHG      2.06168
605388.XSHG     0.691721
605399.XSHG     -0.13748
605500.XSHG     0.116246
Name: pb_ratio, Length: 4140, dtype: object
<think>嗯,用户想了解Excel中的VLOOKUP函数的用法和参数含义。首先,我需要回忆一下VLOOKUP的基本结构。VLOOKUP是垂直查找函数,用于在表格的首列查找指定的值,然后返回该行中指定列的数据。它的四个参数分别是查找值、表格范围、列索引号和匹配模式。 接下来,我得确认每个参数的具体作用。第一个参数是lookup_value,也就是用户要查找的值,比如产品ID或者姓名。第二个参数是table_array,即查找的范围,这里要注意的是,查找值必须位于这个范围的第一列,否则函数无法正确工作。第三个参数是col_index_num,也就是用户想要返回的数据在表格范围中的第几列,这个列数是从表格范围的第一列开始算起的,不是整个工作表的列。第四个参数是range_lookup,决定是精确匹配还是近似匹配,通常用FALSE或0来指定精确匹配,避免错误。 然后,用户可能需要一个具体的例子来理解如何使用。比如,假设有一个产品价格表,用户想根据产品ID查找对应的价格。这时候,VLOOKUP就可以在ID列查找,然后返回价格列的数据。同时,要提醒用户注意表格范围最好使用绝对引用,比如$A$2:$C$100,这样在拖动公式时范围不会变化。 可能遇到的问题也需要考虑。比如,如果查找值不在表格的第一列,或者列索引号超过了表格的列数,函数会返回错误。此外,数据格式不一致也可能导致问题,比如查找值是数字,而表格中是文本格式的数字,这时候需要统一格式。还有,当出现#N/A错误时,可能是查找值不存在,或者匹配模式设置不正确,需要检查参数是否正确。 用户可能还会问到如何避免常见的错误,比如部分数据匹配出错的情况。这时候需要检查是否有多余的空格,或者数据格式不一致,或者表格范围没有锁定导致拖动时偏移。此外,XLOOKUP作为VLOOKUP的升级版,可能在某些情况下更方便,比如可以向左查找或者返回多列数据,这也是可以提及的内容。 最后,整理步骤,从基础语法到参数说明,再到具体案例,逐步引导用户理解如何使用VLOOKUP函数。同时,提供常见错误和解决方法,帮助用户在实际应用中避免问题。如果有必要,还可以比较VLOOKUP和其他查找函数的区别,比如HLOOKUP或XLOOKUP,但根据用户的问题,主要集中在VLOOKUP本身即可。</think>### Excel VLOOKUP函数详解 #### 一、基础语法与参数说明 VLOOKUP函数的语法为: $$=VLOOKUP(lookup\_value, table\_array, col\_index\_num, [range\_lookup])$$ 包含4个参数: 1. **lookup_value**(必填):要查找的值(如单元格引用或具体值) 2. **table_array**(必填):包含数据的表格范围(必须包含查找列和返回列) 3. **col_index_num**(必填):返回值所在列的序号(从table_array第一列开始计数) 4. **range_lookup**(可选):匹配类型 - `TRUE`/`1`:近似匹配(默认值,需数据升序排列) - `FALSE`/`0`:精确匹配(常用选项) [^1][^2] #### 二、使用步骤演示(工资表查询案例) 假设需要根据员工编号查询工资: 1. 建立查询单元格(如`B12`) 2. 输入公式: ```excel =VLOOKUP(A12, $A$2:$D$100, 4, 0) ``` - `A12`:待查询的员工编号 - `$A$2:$D$100`:锁定数据区域(绝对引用) - `4`:返回第4列(工资列) - `0`:精确匹配 [^2][^3] #### 三、常见错误与解决方法 | 错误现象 | 原因 | 解决方案 | |---------|------|---------| | #N/A | 查找值不存在 | 检查数据源或改用`IFERROR`容错 | | #REF! | 列序号超出范围 | 确认col_index_num ≤ 表格列数 | | 部分匹配失败 | 数据格式不一致 | 统一数值/文本格式 | | 结果错位 | 表格未锁定 | 使用`$`符号固定区域引用 | [^3][^4] #### 四、进阶技巧 1. **多条件查询**: 使用辅助列合并多个条件字段 ```excel =VLOOKUP(A2&B2, $D$2:$F$100, 3, 0) ``` 2. **通配符匹配**: `"*"`匹配任意字符,`"?"`匹配单个字符 ```excel =VLOOKUP("张*", $A$2:$C$100, 3, 0) ``` 3. **跨表查询**: 引用其他工作表数据 ```excel =VLOOKUP(A2, Sheet2!$A$2:$D$100, 4, 0) ``` [^1][^4]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值