[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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章