1. 数据处理专题:去极值、标准化
导语:一般的数据预处理中常提及到的处理:去极值、标准化。我们将向大家讲述这常见的数据处理操作。
注意: 该笔记只能在mindgo网站的notebook中实现。
1.1 去极值
在分析上市公司当季净利润同比增长率数据时,我们往往会被其中一些公司的数据干扰,如图中江西长运,2017三季度净利润同比增长率高达32836.04%!而实际上大部分公司的当季净利润同比增长率的数值都远远达到这个值的百分之一。那么数据去极值操作就显得尤为关键,可以剔除掉数据干扰项,提高数据结论的准确性。
一般去极值的处理方法就是确定该项指标的上下限,然后超过或者低于限值的数据统统即为限值。其中上下限数值判断标准有三种,分别为 MAD、 3σ、百分位法。
以沪深300成分股的pe
值为原始数据,向大家阐述MAD
、 3σ
、百分位法。
import numpy as np
import pandas as pd
import math
from statsmodels import regression
import statsmodels.api as sm
import matplotlib.pyplot as plt
date='20180125'
stock=get_index_stocks('000300.SH',date)
q = query(
valuation.symbol,
valuation.pe_ttm,
valuation.current_market_cap
).filter(valuation.symbol.in_(stock))
print(type(q))
data = get_fundamentals(q,date=date)
print(type(data))
print(data.head())
# 修改索引名字
data.columns = [['symbol','pe_ratio','market_cap']]
print(data.keys())
data = data.set_index(data.symbol.values)
print(data.keys())
del data['symbol']
data['1/PE'] = 1/data['pe_ratio']
data.head()
将1/PE
的数据分布,运用绘图函数展示出来:
1/PE就市盈率的倒数,即每股收益相对你付出每股价格的投资回报率。20倍PE则说明如果不增长的前提下,每股收益相对于你付出的价格的回报率是5%,20年回本。所以,1/PE是从投资回报率以及投资回收年限的角度来分析。一般来说,如果单纯的每年5%的回报率,大家是不满意的,更多人还是因为公司会不断发展,利润会不断增加,那么回报率也会增加,投资回收年限减少。
fig = plt.figure(figsize = (20, 8))
ax = data['1/PE'].plot.kde(label = 'Original_PE')
ax.legend()
1.1.1 MAD法
MAD(mean absolute deviation)又称为绝对值差中位数法,是一种先需计算所有因子与平均值之间的距离总和来检测离群值的方法,处理的逻辑:
第一步,找出所有因子的中位数 Xmedian
第二步:得到每个因子与中位数的绝对偏差值 Xi−Xmedian
第三步:得到绝对偏差值的中位数 MAD
第四步:确定参数 n,从而确定合理的范围为 [Xmedian−nMAD,Xmedian+nMAD]
,并针对超出合理范围的因子值做如下的调整:
MAD法代码实现:
def filter_extreme_MAD(series,n): #MAD:中位数去极值
median = series.quantile(0.5)
new_median = ((series - median).abs()).quantile(0.50)
max_range = median + n*new_median
min_range = median - n*new_median
return np.clip(series,min_range,max_range)
对原始数据进行MAD处理后的结果:
fig = plt.figure(figsize = (20, 8))
ax = data['1/PE'].plot.kde(label = 'Original_PE')
ax = filter_extreme_MAD(data['1/PE'],5).plot.kde(label = 'MAD')
ax.legend()
1.1.2 3σ法
3σ法又称为标准差法。标准差本身可以体现因子的离散程度,是基于因子的平均值 Xmean
而定的。在离群值处理过程中,可通过用 Xmean±nσ
来衡量因子与平均值的距离。
标准差法处理的逻辑与MAD法类似:
第一步:计算出因子的平均值与标准差
第二步:确认参数 n(这里选定 n = 3)
第三步:确认因子值的合理范围为 [Xmean−nσ,Xmean nσ]
,并对因子值作如下的调整:
3σ代码实现:
def filter_extreme_3sigma(series,n=3): #3 sigma
mean = series.mean()
std = series.std()
max_range = mean + n*std
min_range = mean - n*std
return np.clip(series,min_range,max_range)
对原始数据进行3σ处理后的结果:
fig = plt.figure(figsize = (20, 8))
ax = data['1/PE'].plot.kde(label = 'Original_PE')
ax = filter_extreme_3sigma(data['1/PE']).plot.kde(label = '3sigma')
ax.legend()
1.1.3 百分位法:
将因子值进行升序的排序,对排位百分位高于97.5%或排位百分位低于2.5%的因子值,进行类似于 MAD 、 3σ 的方法进行调整。
百分位法代码实现:
def filter_extreme_percentile(series,min = 0.10,max = 0.90): #百分位法
series = series.sort_values()
q = series.quantile([min,max])
return np.clip(series,q.iloc[0],q.iloc[1])
fig = plt.figure(figsize = (20, 8))
ax = data['1/PE'].plot.kde(label = 'Original_PE')
ax = filter_extreme_percentile(data['1/PE']).plot.kde(label = 'Percentile')
ax.legend()
1.2 标准化
继续深入的做股票数据分析,假设我们需买入当季净利润同比增长率较高和股息率较高的股票,如果单纯的将两个指标相加,然后取最终值较大的那些股票,那么会面临一个非常严重的问题:两个指标的数值意义不同。上市公司达到股息率10%难于净利润同比增长率10%,一般股息率都小于5%,而净利润增长率则远远超过5%的数值,因此简单的相加,然后选股会淡化股息率指标。
那么这种情况下,数据标准化处理可以解决问题。
标准化在统计学中有一系列含义,一般使用z-score的方法。处理后的数据从有量纲转化为无量纲,使得不同的指标能够进行比较和回归。
z-score的方法介绍
标准化后的数值 = (原始值-单个指标内所有值的均值)/单个指标内所有值的标准差
z-score的方法代码实现:
def standardize_series(series): #原始值法
std = series.std()
mean = series.mean()
return (series-mean)/std
fig = plt.figure(figsize = (20, 8))
new = filter_extreme_3sigma(data['1/PE'])
ax = standardize_series(new).plot.kde(label = 'standard_1')
ax.legend()