题目:
1. 用三种方式去极值
1.1 方式一:分位数去极值
1.2 方式二:中位数绝对偏差去极值
1.3 方式三:正态分布去极值
2. 以2021-01-04的PE数据作为例子数据
概念:
1. 什么是因子去极值
去极值并不是删除“异常数据”,而是将这些数据“拉回”到正常的值
注:极值可以理解离群值或异常数据
方式一:分位数去极值
分位数:中位数、四分位数、百分位数
分位数去极值:将指定分位数区间以外的极值用分位点的值替换掉
import pandas as pd
import numpy as np
from scipy.stats.mstats import winsorize
df_pe_20210104 = pd.read_csv('./pe_20210104.csv',encoding='utf-8')
df_pe_20210104 = df_pe_20210104.loc[:,['secID','tradeDate','closePrice','PE']]
df_pe_20210104.head()
df_pe_20210104['pe_25'] = winsorize(df_pe_20210104['PE'],limits=0.025)
df_pe_20210104['PE'].plot()
df_pe_20210104['pe_25'].plot()
# 由于数据太多,我截取一小段,效果可以看得清楚些
df_pe_20210104.iloc[-700:-200]['PE'].plot()
df_pe_20210104.iloc[-700:-200]['pe_25'].plot()
# 自实现分位数去极值
def quantile(factor,up,down):
up_scale = np.percentile(factor,up)
down_scale = np.percentile(factor,down)
factor = np.where(factor>up_scale,up_scale,factor)
factor = np.where(factor<down_scale,down_scale,factor)
return factor
df_pe_20210104['pe_25_00'] = quantile(df_pe_20210104['PE'],97.5,2.5)
df_pe_20210104.iloc[-700:-200]['PE'].plot()
df_pe_20210104.iloc[-700:-200]['pe_25_00'].plot()
方式二: 中位数绝对值偏差去极值
中位数绝对值偏差去极值英文缩写为MAD, MAD是一种先需计算所有因子与中位数之间的距离总和来检测离群值的方法
计算方法:
1). 找出因子的中位数 median
2). 得到每个因子值与中位数的绝对偏差值|x-median|
3). 得到绝对偏差值的中位数,MAD, median(|x-median|)
4). 计算MAD_e = 1.4826*MAD,然后确定参数n, 作出调整
# 自实现3倍中位数绝对偏差去极值
def mad(factor):
me = np.median(factor)
mad = np.median(abs(factor - me))
# 求出3倍中位数的上下限制
up = me + (3*1.4826*mad)
down = me - (3*1.4826*mad)
# 利用3倍中位数的值去极值
factor = np.where(factor>up,up,factor)
factor = np.where(factor<down,down,factor)
return factor
df_pe_20210104['pe_mad'] = mad(df_pe_20210104['PE'])
df_pe_20210104.iloc[-700:-200]['PE'].plot()
df_pe_20210104.iloc[-700:-200]['pe_mad'].plot()
方式三:正态分布去极值
正态分布去极值的理论:
# 3sigma原则
def three_sigma(factor):
mean = factor.mean()
std = factor.std()
up = mean + 3*std
down = mean - 3*std
# 替换极值
factor = np.where(factor>up,up,factor)
factor = np.where(factor<down,down,factor)
return factor
df_pe_20210104['pe_3sigma'] = three_sigma(df_pe_20210104['PE'])
df_pe_20210104.iloc[-700:-200]['PE'].plot()
df_pe_20210104.iloc[-700:-200]['pe_3sigma'].plot()
# 使用少量数据已经看不出效果,使用全部数据
df_pe_20210104['PE'].plot()
df_pe_20210104['pe_3sigma'].plot()
三种方式比较
全部数据
中位数去极值 | 中位数绝对偏差去极值 | 正态分布去极值 |
部分数据(为了图像放大可以看得清效果)
中位数去极值 | 中位数绝对偏差去极值 | 正态分布去极值 |
结论:
三种方式中,中位数绝对偏差去极值效果最好
PS:
所使用数据
链接:https://pan.baidu.com/s/11GubyLR2ZkuiXhyk5n6MzA
提取码:n14t