为了说明量化投资研究服务平台因子合成流程,本文将以等权合成为例,介绍因子合成的流程及使用方法 > 等权合成 – 通过多个因子的排名之和来生成一个新的因子。
因子合成是指多个因子通过计算或训练的方法生成一个新的因子,新产生的因子可以通过回测产生交易策略,或通过因子分析来研究市场规律。
使用因子合成需要自定义一个继承自Ai_Factor的类,从smartbeta.ai_factor导入。
[ ]:
import pandas as pd
from smartbeta.ai_factor import AiFactor
from data_provider.nestlib.market_info import Frequency
from smartbeta.factor_training_feed import FactorTrainingFeed
from datetime import datetime
from data_provider.datafeed.universe import Universe
from smartbeta.factor_training_feed import (
FactorTrainingFeed,
standardization_zscore,
standardization_mean,
standardization_std,
outline_sigma,
standardization_rank,
)
自定义标准化方法,该方法将对每一个因子进行调用,将因子转化成为模型所需的形式,如归一化,去极值,zscore等,用户也可以自己定义一个因子标准化方法。
要使用自定义的方法,需要实现一个回调函数并在AiFactor
子类中的_x_rules
中设置此方法, 见下文说明 这里,我们实现一个简单的归一化方法, 即 value = factor_value / factor_count
factor_data
: (dataframe)包含所有的因子值direction
: 因子方向, 1为升序,即因子值越小,因子排名越靠前。params
: (dict) 保留项,用于某些自定义的参数。[5]:
def standardization_normalization(factor_data, direction=1, params={"direction": 1}):
count = factor_data.groupby("tdate")["factor_value"].count()
count.name = "count"
factor_data = factor_data.set_index(["tdate"])
factor_data["factor_value"] = factor_data["factor_value"] / count
return factor_data.reset_index()
实现自定义合成因子类,x_rules指定因子处理方式,处理后的结果将传送给_build_ai_model进行建模。 该模型对所有传入的因子的排名进行相加,生成新因子
factor_parameters参数说明:
treat_na
: 对因子缺失值的处理,默认’drop’。可选’mean’、‘median’、‘drop’、‘keep’、float。’drop’表示drop任何有na的行,’drop14’表示当一行中非na的元素个数小于14时,drop该行.浮点数表示将na填充为该浮点数
subFactors
: (list)用于合成新因子的因子集合,每个因子使用dict表示,需包含factor_name, factor_direction, frequency三项。
frequency
: 生成的新因子所对应的调仓周期。
生成一个新因子,需要重写其_build_ai_model
以及_x_rules
方法。如没有标准化需求则可在_x_rules
放回空数组。
[6]:
class EqualWeightFactor(AiFactor):
def __init__(
self,
factor_name,
factorDirection=1,
tickers="A",
industry_wise=False,
factor_parameters={
"subFactors": [],
"lagCycleNumber": 0,
"frequency": "month_end",
"treat_na": 'drop',
},
):
# Initialize super class.
super(EqualWeightFactor, self).__init__(
factor_name=factor_name,
factor_direction=factorDirection,
tickers=tickers,
industry_wise=industry_wise,
factor_parameters=factor_parameters,
)
self.use_factor_cache = False # do not cache trainning set
def _x_rules(self):
"""
通过自定义x_rules回调,可以实现自定义的因子预处理方式
返回训练用的标准化规则方式。重写该方法来设置所需的标准化方法。
这里我们只需将所有的因子,先排名,再归一化。
"""
return [{"func": standardization_rank}, {"func": standardization_normalization}]
def _build_ai_model(self, dateTime, training_set):
"""
返回series组,key为securityId, 值为factor value
"""
# self.ff._get_training_XY用来获取因子的集合,分为训练集和预测集,在此例中我们不需要使用历史数据进行训练,仅使用预测集,即调仓日当天的因子数据
# _get_training_XY返回的集合由factor_parameter中的lagCycleNumber参数决定训练集使用多少历史的因子数据
# [0]第一个元素为training_set的X,所有因子经过转化的结果,也就是当前月份往前1个月+lag_period的因子集合pandas对象
# [1]第二个元素为trainning_set的Y, 即X对应的结果集,根据设置可以为后一个月的return,也可以是good/bad,根据AIFactor的factor_parameter决定
# [2]第三个元素为当前月份的因子,用于预测
# 这里我们因为对因子等权叠加,所以只需要当前月份的因子值排名即可。
# self.ff对象为一个FactorTrainingFeed对象,详细功能参见FactorTrainingFeed Reference部分
ret = self.ff._get_training_XY(dateTime, training_set)
result = ret[2]
# 最后返回因子排名相加的值,由于在创建对象时,我们使用了standardization_rank的预处理方式,
# 该处理方式已经将因子值转化成了排名,所以这里只需要简单做Sum运算便可。
data = result.sum(axis=1).reset_index().set_index("security_code")[0]
return data
使用新的合成因子类计算新因子。
[7]:
subFactors = [
{
"factor_name": "MonthlyReturn",
"factor_direction": 1,
"frequency": Frequency.MONTH,
},
{
"factor_name": "MonthlyTradeAmount",
"factor_direction": 1,
"frequency": Frequency.MONTH,
},
{
"factor_name": "RoeGrowth1",
"factor_direction": -1,
"frequency": Frequency.MONTH
},
]
from_dt = "20170101"
to_dt = "20171023"
ab = EqualWeightFactor(
factor_name="equal_weight_factors",
tickers="A",
factor_parameters={
"subFactors": subFactors,
"frequency": "month_end",
"lagCycleNumber": 0,
"treat_na": 'drop',
},
)
ab.del_factor() # 从数据库清空因子,以便重新录入
%time ab.generate_factor_and_store(from_dt, to_dt, echo=False)
Can not find the factor: equal_weight_factors in sys
2018-08-31 17:22:17,116 - factor_training_feed.py:275 - INFO - 正在计算训练集. lagCycle: 0, frequency: month_end
loading monthlyreturn time cost 2.14s
2018-08-31 17:22:20,093 - factor_training_feed.py:203 - INFO - 是否对当前因子按升序排列: True
loading monthlytradeamount time cost 1.83s
2018-08-31 17:22:23,350 - factor_training_feed.py:203 - INFO - 是否对当前因子按升序排列: True
loading roegrowth1 time cost 1.99s
2018-08-31 17:22:26,678 - factor_training_feed.py:203 - INFO - 是否对当前因子按升序排列: False
2018-08-31 17:22:27,834 - factor_training_feed.py:344 - INFO - 加载行情数据...
2018-08-31 17:22:41,486 - factor_training_feed.py:354 - INFO - 统计收益...
2018-08-31 17:22:41,600 - factor_training_feed.py:403 - INFO - 合并因子至单个dataframe...
CPU times: user 20.1 s, sys: 4.49 s, total: 24.6 s
Wall time: 26.9 s
可以通过 set_industry 接口,对行业进行过滤。设置后,因子合成时只会考虑所选行业中的股票。
industry
: 类型 str, list, 传入单个申万行业分类代码,或分类代码列表[8]:
ab.set_industry('SW801790')
# 或
ab.set_industry(['SW801790','SW851231'])
对生成的因子进行回测, 使用默认设置,全A选股,对冲中证500指数
[9]:
from smartbeta.backtest.factor_backtest import FactorBackTest
uni = Universe()
factors = [{"name": "equal_weight_factors", "direction": 1}]
bt = FactorBackTest(
"000905.SH", from_dt, to_dt, factors, holding_count=200, freq="month_end"
) # '000905.SH'
%time bt.run()
bt.analy_plot()
loading dailyreturn time cost 1.76s
加载中: equal_weight_factors
loading equal_weight_factors time cost 0.63s
因子加载完成
CPU times: user 5.42 s, sys: 276 ms, total: 5.7 s
Wall time: 7.03 s
[10]:
help(AiFactor)
Help on class AiFactor in module smartbeta.ai_factor:
class AiFactor(smartbeta.factorbase.BaseFactor)
| Ai因子基础类,提供基于机器学习合成因子的功能,
| 用户需要提供自定义的_generate_ai_factor方法,使用训练集提供的内容来进行新因子的训练合成。
|
| Method resolution order:
| AiFactor
| smartbeta.factorbase.BaseFactor
| builtins.object
|
| Methods defined here:
|
| __init__(self, factor_name, factor_direction=1, tickers='A', industry_wise=False, factor_parameters={'subFactors': [], 'frequency': 'month_end', 'lagCycleNumber': 12, 'rolling_frequency': 'default', 'use_ranks_as_x': False, 'use_ranks_as_y': True, 'class_percentile': 10, 'class_remove_neural': True, 'treat_null_factor_as_zero': True})
| :param factor_name: 因子名称,要求唯一。
| :param factor_direction: 因子值排名的方向,1:升序(值越小排名越前) -1:降序
| :param tickers: 股票范围, 支持3种格式: 1. 'A' 2.数组['600000.SH', '600100.SH', ...] 3.指数,表示指数成份['000905.SH']
| :param industry_wise: 是否针对行业板块分别训练,将影响_generate_ai_factor中trainning_set的输入。
| :param factor_parameters: (dict)用于自定义的合成因子的参数,但必须包含subFactors以及frequency.
| subFactors:(list)用于合成新因子的因子集合,每个因子使用dict表示,需包含factor_name, factor_direction, frequency三项。 frequency: 生成的新因子所对应的调仓周期。
| lagCycleNumber: (int)窗口周期,subFactors所需的窗口周期数,如果是用于训练模型,则相当于训练集的所需的历史周期数
| use_ranks_as_x:(bool)是否将因子值(训练集的X)转化为排名。
| use_ranks_as_y: (bool) 是否将表现(训练集的Y)转化为排名。
| class_percentile: (int) 训练集的Y(即表现)的好坏筛选百分比。仅对use_ranks_as_y为True时有效。
| class_remove_neural: (int)是否将训练集Y(即表现)的中间位置去除。仅对se_ranks_as_y有效,如class_percentile 为10%时,
| 排名前10%将被标记为good(1), 后10%为bad(-1),中间80%是否去除(0值)。
| treat_null_factor_as_zero:是否将因子sub_factors中出现的空值赋为0.
|
| set_industry(self, industry)
| 设置行业范围
|
| Parameters
| ----------
| industry: str, list
| 申万行业id,或行业id列表
|
| set_use_factor_cache(self, use_it)
| 是否使用缓存,当使用多个因子进行合并的时候,使用缓存将所有用到的标准化后的因子数据进行一次性缓存,即缓存trainning_set对象。
| 对于_build_ai_model的调参尤其有效,该参数默认开启。
| :param use_it: (bool)是否使用缓存
|
| ----------------------------------------------------------------------
| Methods inherited from smartbeta.factorbase.BaseFactor:
|
| add_factor_definition(self, category=None, create_by='', cn_name='', description='', cal_alg='', storage_method='db', create_time=None)
| 加入因子定义相关信息
| :param category: 因子大类
| :param create_by: 创建者
| :param description: 描述
| :param cal_alg: 计算方法
| :param storage_method: 存储方式,目前有实时计算和落入数据库两种
| :param create_time: 创建时间,如果为None值,就填充为当前时间
| :return:
|
| calculate(self, ticker, from_date, to_date)
|
| clear_factor(self)
| 对当天的因子进行清洗,主要有:
| 1. 过滤掉无穷大和无穷小的值
| 2. 过滤掉nan值
| 3. 过滤掉未上市的股票(未上市可能已经有财报发布,导致会出现一些值)
| 4. 过滤掉已经退市的股票
| :return: 过滤后的因子值
|
| deal_his_data(self, from_date, to_date)
| 根据起止时间,处理已有历史数据
|
| del_factor(self, factor_name=None)
| 将因子数据从数据库中删除
|
| del_factor_definition(self, factor_name=None)
| 将因子定义从因子定义表中删除
|
| generate_factor_and_store(self, from_date, to_date, save_method=None, echo=False)
| 计算因子并录入数据库
| params:
| from_date: (str)起始时间
| to_date: (str)结束时间
| echo: (bool)是否打印进度条和信息
| save_method: 保存方式,当前仅支持覆盖,即此参数不起作用
| returns:
| (str)执行结果信息
|
| generate_factor_and_store_origin(self, from_date, to_date, save_method=None, echo=False)
| 计算因子并录入数据库
| params:
| from_date: (str)起始时间
| to_date: (str)结束时间
| echo: (bool)是否打印进度条和信息
| save_method: 保存方式,
| 'override'/ None 表示若库中已有这些天的记录,则删除再插入这些天的记录;
| 'join' 表示更新这些天的记录,对于那天已有股票因子值的记录,则更新
| e.g:
| 原有记录:
| [{'td': 201701011, 'factor_info':
| [
| {'tk': '000001.SZ', 'fv': 0.5},
| {'tk': '000002.SZ', 'fv': 0.9}
| ]
| }]
| 保存记录:
| [{'td': 201701011, 'factor_info':
| [
| {'tk': '000002.SZ', 'fv': 0.5},
| {'tk': '000003.SZ', 'fv': 0.9}
| ]
| }]
| override方式保存,则现有记录:
| [{'td': 201701011, 'factor_info':
| [
| {'tk': '000002.SZ', 'fv': 0.5},
| {'tk': '000003.SZ', 'fv': 0.9}
| ]
| }]
| join方式保存,则现有记录:
| [{'td': 201701011, 'factor_info':
| [
| {'tk': '000001.SZ', 'fv': 0.5},
| {'tk': '000002.SZ', 'fv': 0.5},
| {'tk': '000003.SZ', 'fv': 0.9}
| ]
| }]
| returns:
| (str)执行结果信息
|
| get_factor_df(self)
| :return: 获取该因子的所有数据,格式为pd.DataFrame
|
| get_factor_direction(self)
| 获取因子方向
| 返回:(1或-1)
| 1: 因子值升序,因子值越小,得分越高
| -1:降序, 因子值越大越好,得分越高
|
| get_factor_name(self)
| 获取因子唯一名称
| 返回:(str)因子名
|
| get_factor_param(self)
| 获取参数
| 返回:(dict)因子自定义参数
|
| get_factor_value(self, dt)
| 获取因子值
| params:
| dt: 'str', 输入需要获取的因子值的日期
|
| return:
| (dict)ticker-factor_value键值对
|
| get_first_record_date(self)
|
| get_last_record_date(self)
|
| get_last_record_date_origin(self)
|
| get_trading_days(self)
| 获取计算因子的交易日历
| 返回交易日历
|
| has_definition(self)
| 因子是否有相关的定义
| :return:
|
| load(self, begin_day, end_day, ticker=None, factor_name=None, use_cache=False)
| 从mongo中读取因子数据
| :param factor_name: 因子的名称
| :param begin_day: 开始日期,int类型YYYYMMDD, 也可以是datetime/str
| :param end_day: 结束日期,int类型YYYYMMDD, 也可以是datetime/str
| :param ticker: 股票代码。如果没有传入ticker的list,默认取出所有股票的因子值
| :param use_cache: 是否使用缓存,default False
| :return: 因子数据,pandas.DataFrame类型, 若不存在,返回panddas.DataFrame()
|
| print_test(self, ticker, from_date, to_date)
|
| save(self, save_method='override')
| 因子数据保存到arctic_factor_data.factor_symbol
| Args:
| save_method: 保存方式,
| 'override'/ None 表示若库中已有这些天的记录,则删除再插入这些天的记录;
| 'join' 表示更新这些天的记录,对于那天已有股票因子值的记录,则更新
| Returns:
| 'ok' if save successfully else raise exception
|
| save_origin(self, save_method='override')
| 将因子写入mongo数据库,默认数据库collection已经创建好,后续可以优化
| Args:
| save_method: 保存方式,
| 'override'/ None 表示若库中已有这些天的记录,则删除再插入这些天的记录;
| 'join' 表示更新这些天的记录,对于那天已有股票因子值的记录,则更新
| Returns:
| 'ok' if save successfully else raise exception
|
| set_cache_folder(self, folder)
|
| set_factor_name(self, factor_name)
|
| set_factor_value(self, factor_df)
| 直接set因子值
| :param factor_df: 要有三列值:'tdate', 'security_code', 'factor_value'。其中tdate为类似"20170929"类型的string
| :return:
|
| set_frequency(self, frequency)
|
| set_should_write_cache(self, write)
|
| set_tickers(self, tickers)
|
| ----------------------------------------------------------------------
| Data descriptors inherited from smartbeta.factorbase.BaseFactor:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
[11]:
help(AiFactor._build_ai_model)
Help on function _build_ai_model in module smartbeta.ai_factor:
_build_ai_model(self, dateTime, training_set)
通过模型生成因子值,该方法必须被子类重写
:param dateTime: 需要生成的因子的时间
:param training_set: 用于训练模型的输入,包含训练所需的训练集和结果集。
:return 因子Series, index为security_code, 值为因子值
600100.SH 0.0012
600101.SH 0.0051
...
[12]:
help(AiFactor._x_rules)
Help on function _x_rules in module smartbeta.ai_factor:
_x_rules(self)
返回训练用的标准化规则方式。重写该方法来设置所需的标准化方法。
factorTrainingFeed类用于ai_factor内部提供各类因子集合处理的服务。在AiFactor._build_ai_model可以通过self.ff对象获取各类训练集处理的功能。
[13]:
help(FactorTrainingFeed)
Help on class FactorTrainingFeed in module __main__:
class FactorTrainingFeed(builtins.object)
| 此类用于提供因子的标准化数据处理服务,提供将因子及其表现转化为各类标准化的训练集X和结果集Y的输出。
| AiFactor类使用此类作为内部数据集的处理。
|
| Methods defined here:
|
| __init__(self, factor_params, industry=None, use_factor_cache=True)
| 构造函数
| :param factor_params: (list)每个元素为一个dict,包含数据集所要管理的因子信息。
| 每个dict需包含factor_name, factor_direction, frequency三项。
| factor_name:(str)因子名称
| factor_direction:(int)因子方向,1位升序,-1为降序
| frequency: (string))对应周期(week_end/month_end/daily)。
| :param use_factor_cache: (bool)是否使用缓存因子进行因子读取加速。
|
| calc_training_sets(self, from_date, to_date, lagCycleNumber=12, adjust_frequency='month_end', treat_null_factor_as_zero=True, rolling_frequency='default', include_latest=False, treat_na='drop')
| 将因子合并成训练所需的X、Y集合
| :params tickers: 可以为string'A'表示全A市场,或'000016.SH'表示指数成份
| :params lagCycleNumber: 单个ticker应具备的训练集大小,如:使用过去12个月,按月度采样,则该值为12
| :params occurred_at: 样本采集频率, [daily/week_start/week_end/month_start/month_end]
| :return (x:样本集,y:结果集)
|
| filter_by_tickers(self, tickers, trainning_set_pd=None, inplace=True)
| 从训练集中筛选股票。
| :param tickers: 需要筛选的tickers,可以是指数成分如'000905.SH'或tickers数组['600000.SH', '002100.SZ' ...]
| :param trainning_set_pd: (dataframe)需要筛选的trainning_set对象, 如果为none则表示self内部管理的training_set
| :param inplace:(bool)是否更新到内部的trainning_set对象
|
| get_training_XY(self, dt)
| 根据输入日期,拆分训练集,将最近的一个数据样本作为需要预测的数据
| :params dt:需要拆分训练集的日期
| :returns tuple(train_x, train_y, predict_x, predict_y): 其中predict_y可用于验证,是带未来值
|
| handle_x_standardization_rules(self, factor_data, factor_direction=1)
| 使用预先设置的x_rules对训练集进行标准化处理。
| :param factor_data: (dataframe)因子数据, columns为factor_value、 security_code、tdate。
| :param factor_direction: (bool)因子方向,1为升序,-1为降序
| :return 处理后的factor_data对象
|
| set_X_process_rules(self, rules)
| 设置训练集的处理规则
| :param rules: (list)每个元素必须为rule方法,系统提供standardization_zscore等标准化方法。
|
| set_rolling_frequency(self, rolling_frequency)
| 设置训练集的滚动频率,如为日频,则表示生成日级别的训练集数据。
| 如adjust_frequency为week_end, rolling_frequency为daily则表示按日频滚动训练,
| 并以周评调仓,结果集以T+5也就是周收益进行计算
| :param rolling_frequency: daily, week_end, month_end, default。default表示与adjust_frequency一致
|
| transform_to_percentile(self, training_set, percentile, remove_neutral=True, inplace=True)
| 将y收益率y排序, 根据百分位数计算优劣并合并至原有Y集合
| :params: percentile 百分位数,0~100
| :return: 合并后的y集合,包含满足百分位数的值
|
| transform_to_rank(self, training_set, inplace=True)
| 将y收益率转化为排名
| :return: 合并后的y集合,包含收益排名
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
[14]:
help(FactorTrainingFeed.set_X_process_rules)
Help on function set_X_process_rules in module __main__:
set_X_process_rules(self, rules)
设置训练集的处理规则
:param rules: (list)每个元素必须为rule方法,系统提供standardization_zscore等标准化方法。
[15]:
help(FactorTrainingFeed.calc_training_sets)
Help on function calc_training_sets in module __main__:
calc_training_sets(self, from_date, to_date, lagCycleNumber=12, adjust_frequency='month_end', treat_null_factor_as_zero=True, rolling_frequency='default', include_latest=False, treat_na='drop')
将因子合并成训练所需的X、Y集合
:params tickers: 可以为string'A'表示全A市场,或'000016.SH'表示指数成份
:params lagCycleNumber: 单个ticker应具备的训练集大小,如:使用过去12个月,按月度采样,则该值为12
:params occurred_at: 样本采集频率, [daily/week_start/week_end/month_start/month_end]
:return (x:样本集,y:结果集)
[16]:
help(FactorTrainingFeed.filter_by_tickers)
Help on function filter_by_tickers in module __main__:
filter_by_tickers(self, tickers, trainning_set_pd=None, inplace=True)
从训练集中筛选股票。
:param tickers: 需要筛选的tickers,可以是指数成分如'000905.SH'或tickers数组['600000.SH', '002100.SZ' ...]
:param trainning_set_pd: (dataframe)需要筛选的trainning_set对象, 如果为none则表示self内部管理的training_set
:param inplace:(bool)是否更新到内部的trainning_set对象
[17]:
help(FactorTrainingFeed.transform_to_percentile)
Help on function transform_to_percentile in module __main__:
transform_to_percentile(self, training_set, percentile, remove_neutral=True, inplace=True)
将y收益率y排序, 根据百分位数计算优劣并合并至原有Y集合
:params: percentile 百分位数,0~100
:return: 合并后的y集合,包含满足百分位数的值
[18]:
help(FactorTrainingFeed.get_training_XY)
Help on function get_training_XY in module __main__:
get_training_XY(self, dt)
根据输入日期,拆分训练集,将最近的一个数据样本作为需要预测的数据
:params dt:需要拆分训练集的日期
:returns tuple(train_x, train_y, predict_x, predict_y): 其中predict_y可用于验证,是带未来值
数据集的标准化方法用于AI_Factor的_x_rules,用于预处理因子并将其转化成已有的形式,支持用户自定义的处理方式,但是我们也提供以下标准化方法。
[19]:
import smartbeta.factor_training_feed as ftf
[20]:
help(ftf.standardization_mean)
Help on function standardization_mean in module smartbeta.factor_training_feed:
standardization_mean(factor_data, direction=1, params={})
标准化处理方法-去均值。按factor_data中的tdate分组计算均值。
return new_factor_value = origin_factor_value - mean
该方法可在ai_factor._x_rules设定用于标准训练集的处理。
[21]:
help(ftf.standardization_std)
Help on function standardization_std in module smartbeta.factor_training_feed:
standardization_std(factor_data, direction=1, params={})
标准化处理方法-标准差。按factor_data中的tdate分组计算标准差。
return new_factor_value = origin_factor_value / std
该方法可在ai_factor._x_rules设定用于标准训练集的处理。
[22]:
help(ftf.standardization_zscore)
Help on function standardization_zscore in module smartbeta.factor_training_feed:
standardization_zscore(factor_data, direction=1, params={})
标准化处理方法-标准差。按factor_data中的tdate分组计算zscore。
return new_factor_value = (origin_factor_value - mean) / std
该方法可在ai_factor._x_rules设定用于标准训练集的处理。
[23]:
help(ftf.outline_sigma)
Help on function outline_sigma in module smartbeta.factor_training_feed:
outline_sigma(factor_data, direction=1, params={'sigmaThreshold': 3.0})
标准化处理方法-sigma去极值。将超出阀值的值拉回阀值。
upThreshold = mean + (sigmaThreshold * sigmaThreshold)
downThreshold = mean - (sigmaThreshold * sigmaThreshold)
该方法可在ai_factor._x_rules设定用于标准训练集的处理。
[24]:
help(ftf.standardization_rank_pct)
Help on function standardization_rank_pct in module smartbeta.factor_training_feed:
standardization_rank_pct(factor_data, direction=1, params={})
标准化处理方法-转户为排名。按factor_data中的tdate分组转化为排名
该方法可在ai_factor._x_rules设定用于标准训练集的处理。
: direction: 1为升序(因子值越小,转化为的排名越靠前,其值越小),其余值为降序。
[ ]:
import pandas as pd
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from smartbeta.ai_factor import AiFactor
from smartbeta.factor_training_feed import (
FactorTrainingFeed,
standardization_zscore,
standardization_mean,
standardization_std,
outline_sigma,
standardization_rank,
)
class AdaBoostFactor(AiFactor):
def __init__(
self,
factor_name="adaBoostAlpha",
factorDirection=1,
tickers="A",
industry_wise=False,
factorParameters={
"subFactors": [],
"frequency": "month_end",
"lagCycleNumber": 12,
"classifierNumber": 20,
"dc_depth": 5,
"use_ranks_as_x": False,
"use_ranks_as_y": True,
"class_percentile": 10,
"class_remove_neural": True,
"treat_na": 'drop'
},
):
# Initialize super class.
super(AdaBoostFactor, self).__init__(
factor_name=factor_name,
factor_direction=factorDirection,
tickers=tickers,
industry_wise=industry_wise,
factor_parameters=factorParameters,
)
def _x_rules(self):
"""
返回训练用的标准化规则方式。重写该方法来设置所需的标准化方法。
"""
if self._factor_param["use_ranks_as_x"] == True:
return [
{"func": outline_sigma, "params": {"sigmaThreshold": 3.0}},
{"func": standardization_zscore},
{"func": standardization_rank},
]
else:
return [
{"func": outline_sigma, "params": {"sigmaThreshold": 3.0}},
{"func": standardization_zscore},
]
def _build_ai_model(self, dateTime, training_set):
ret = self.ff._get_training_XY(dateTime, training_set)
trainX = ret[0]
trainY = ret[1]
predictX = ret[2]
true_predictY = ret[3]
classifierNumber = self._factor_param["classifierNumber"]
dt_stump = DecisionTreeClassifier(
max_depth=self._factor_param["dc_depth"], min_samples_leaf=1
)
n_estimators = classifierNumber
learning_rate = 1
ada_discrete = AdaBoostClassifier(
base_estimator=dt_stump,
learning_rate=learning_rate,
n_estimators=n_estimators,
algorithm="SAMME",
)
xx = trainX.values
yy = trainY.values
tresult = ada_discrete.fit(xx, yy)
score = ada_discrete.score(xx, yy)
if predictX.shape[0] == 0:
return None
predictY = ada_discrete.predict_proba(predictX.values)
pX = predictX.reset_index()
predictionClass = ada_discrete.predict(predictX.values)
badProba = predictY[:, 0]
goodProba = predictY[:, 1]
predictionMatrix = pd.DataFrame(
{
"security_code": pX["security_code"],
"badProba": badProba,
"goodProba": goodProba,
"predictionClass": predictionClass,
}
)
data1 = pd.DataFrame(predictionMatrix).sort_values(
by=["goodProba"], ascending=False
)
data = pd.Series(
dict(zip(list(data1["security_code"]), list(data1["goodProba"])))
)
print(
"datetime: %s, fitting score: %f, training_set: %s, predict_set: %s"
% (dateTime, score, xx.shape, predictX.shape)
)
return data
微信扫码分享本页