[B6]多因子数据的处理方式

多因子数据的处理:主要包括三种方式-----------去极值;标准化;中性化

1.去极值
去极值不是删除而是拉回正常值
(1)分位数去极值
(2)3倍中位数去极值(3mad)
(3)正太分布去极值(3sigma)

首先安装以下需要的工具包

from scipy.stats.mstats import winsorize

from sklearn.preprocessing import StandardScaler

from sklearn.linear_model import LinearRegression

import numpy as np

import pandas as pd

(1)分位数去极值
获取数据,选择revenue和cost_of_goods_sold两个特征

q = query(fundamentals.income_statement.revenue,
          fundamentals.income_statement.cost_of_goods_sold
         )

fund = get_fundamentals(q, entry_date="2017-01-03")

#换成截面数据
fund[:,"2017-01-03",:]

在这里插入图片描述

#对pe_ratio去极值
#分位数去极值
fund = pe_ratio = get_fundamentals(query(fundamentals.eod_derivative_indicator.pe_ratio), entry_date="2018-01-03")[:,"2018-01-03",:]

fund['pe_ratio_winsorize'] = winsorize(fund['pe_ratio'], limits=0.025)

选取500个数据查看情况

fund['pe_ratio'][:500].plot()
fund['pe_ratio_winsorize'][:500].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

quantile(fund['pe_ratio'], 97.5, 2.5)

(2)3倍中位数绝对偏差去极值
#1.找出中位数
#2.得到每个因子值与中位数的绝对偏差 / x - median/
#3.得到绝对偏差值的中位数 MAD, median(/ x - median/)
#4.计算MAD_e = 1.4826*MAD,然后确定参数n,做出调整

#===实现3倍中位数绝对偏差去极值==

def mad(factor):
    
    #1.找出中位数
    me = np.median(factor)
    
    #2.得到每个因子值与中位数的绝对偏差  / x - median/
    #3.得到绝对偏差值的中位数  MAD, median(/ x - median/)
    
    mad = np.median(abs(factor - me)) 
    
    #4.计算MAD_e = 1.4826*MAD,然后确定参数n,做出调整
    #求出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
#对pe_ratio去极值
fund['pe_ratio_3mad'] = mad(fund['pe_ratio'])

选取500数据查看

fund['pe_ratio'][:500].plot()
fund['pe_ratio_3mad'][:500].plot()

在这里插入图片描述
效果明显比之前好很多

(3)正态分布去极值 (3sigma方法去极值)
自定义一个函数

def threesigma(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
fund['pe_ratio_3sigma'] = threesigma(fund['pe_ratio'])

选取500查看情况

fund['pe_ratio'][:500].plot()
fund['pe_ratio_3sigma'][:500].plot()

在这里插入图片描述
这个效果就不太好了,所以日常主要用第二种方法。

2.标准化

std = StandardScaler()

std.fit_transform(fund['pe_ratio_3mad'].dropna())

或者自实现一个标准化函数

def stand(factor):
    
    mean = factor.mean()
    std = factor.std()
    
    return (factor - mean)/ std

stand(fund["pe_ratio_3mad"])

在这里插入图片描述
3.中性化
将市值进行中性化处理

#获取两个因子数据
#对目标值因子-市净率进行去极值和标准化处理
#建立市值与市净率回归方程
#通过回归系数,预测新的因子结果y_predict
#求出市净率与y_predict的偏差即为新的因子值

#1.获取数据
q = query(
    fundamentals.eod_derivative_indicator.pb_ratio,
    fundamentals.eod_derivative_indicator.market_cap
    )

fund = get_fundamentals(q, "2018-01-03")[:,"2018-01-03",:]
fund

在这里插入图片描述

#2.对因子数据进行处理,3倍中位数,stand
fund['pb_ratio']= mad(fund['pb_ratio'])
fund['pb_ratio']= stand(fund['pb_ratio'])
#3.确定建立回归方程特征值和目标值
#感谢大神,这里传入训练的特征值是二维的形状
x = fund['market_cap'].values.reshape(-1, 1)
y = fund['pb_ratio']
#4.利用线性回归进行预测
lr = LinearRegression()
lr.fit(x,y)
#5.得出每个预测值,让因子的真实值-预测值得出的误差,就是我们中性化处理后的结果
y_predict = lr.predict(x)

res = y - y_predict

fund['pb_ratio'] =res
fund

在这里插入图片描述
这便是经过中性化处理的市值数据。

发布了8 篇原创文章 · 获赞 0 · 访问量 2119
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章