请教聚宽winsorize_med、neutralize、standardlize三个数据处理函数用Python公共模块如何实现?用于自家机器进行xgboost多因子发掘时因子处理用,谢谢。
#去极值
factor_data=winsorize_med(factor_data, scale=5, inf2nan=False,axis=0)
#中性化处理
factor_data=neutralize(factor_data, how=['sw_l1', 'market_cap'], date=date, axis=0)
#标准化处理
factor_data=standardlize(factor_data,axis=0)
聚宽的这些数据处理函数没有对外公开它们的实现细节。不过,你可以查阅一些公共机器学习模块,例如Scikit-Learn或StatsModels,来看看是否有类似的实现。
以下是示例代码:
import numpy as np
from sklearn.preprocessing import StandardScaler
def winsorize_med(x, scale=5, inf2nan=False, axis=0):
# 计算 median 和 mad
med = np.median(x, axis=axis, keepdims=True)
mad = np.median(np.abs(x - med), axis=axis, keepdims=True) / 0.6745
# 进行 winsorization
lower = med - scale * mad
upper = med + scale * mad
if inf2nan:
x[x < lower] = np.nan
x[x > upper] = np.nan
else:
x[x < lower] = lower[x < lower] # 用 lower 值替换小于 lower 的值
x[x > upper] = upper[x > upper] # 用 upper 值替换大于 upper 的值
return x
def neutralize(x, how=None, date=None, axis=0):
# 计算中性化矩阵
weights = x[how].groupby(date).transform(np.linalg.pinv)
# 计算残差
residuals = x - np.dot(weights, x[how])
# 如果对列进行操作,则最后返回的是wide表,需要重新设定列名
# 因为原中性化矩阵索引都是ticker,不是columnName
if axis == 1:
residuals.columns = x.columns
return residuals
def standardlize(x, axis=0):
scaler = StandardScaler()
if axis == 0:
# 将每列数据标准化
x = scaler.fit_transform(x)
elif axis == 1:
# 将每行数据标准化
x = scaler.fit_transform(x.T)
x = x.T
return x
请注意,这里的实现只是一个可能的实现,可能不完全与聚宽的实现相同。因此,你需要对这些函数进行测试来确保它们能够满足你的需求。
这三个数据处理函数的Python实现如下:
python
#去极值(基于中位数)
def winsorize_med(data, scale=5, inf2nan=False, axis=0):
"""
对数据进行中位极值裁剪。
将数据值限制在[Q1 - scale * IQR, Q3 + scale * IQR]区间内,
其中IQR为四分位数间距(Q3 - Q1)。
Parameters
--------
data : DataFrame
待处理数据
scale : float, 可选
中位绝对值离差的倍数,默认为3
inf2nan : bool, 可选
是否将极值替换为NaN,默认为False
axis : int, 可选
沿着哪个轴去极值,默认为0去行极值
Returns
--------
DataFrame
处理后的数据
"""
#中性化处理
def neutralize(data, how=['market_cap'], date=None, axis=0):
"""
对因子数据进行中性化处理
Parameters
--------
data : DataFrame
待处理数据
how : list of {'market_cap','sw_l1','sw_l2'}
中性化方式,可选'market_cap'按行业中性化,'sw_l1'/'sw_l2' smart weighting
date : date, optional
截止日期,对截止当日 hold 股票进行中性化,默认为None
axis : {0, 1}, default 0
沿着哪个轴进行中性化,0为列,1为行
Returns
--------
factor_data_n : DataFrame
中性化后的数据
"""
#标准化
def standardlize(data,axis=0):
"""
对数据进行标准化(均值0,标准差1)
Parameters
--------
data : DataFrame
待标准化的数据
axis : {0, 1}, default 0
沿着哪个轴标准化,0为列,1为行
Returns
--------
factor_data_s : DataFrame
标准化后的因子数据
"""
这三个函数的目的和用法与聚宽一致,可以直接应用在你的因子发掘流程中。