Commit da79d3d5 authored by iLampard's avatar iLampard

Add keras example in notebooks

parent 2727902e
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* 本例展示如何在alpha-mind中使用深度学习模型。\n",
" - 为方便比较,使用的数据参数与[机器学习模型示例](https://github.com/alpha-miner/alpha-mind/blob/master/notebooks/Example%2012%20-%20Machine%20Learning%20Model%20Prediction.ipynb)一致。\n",
" - 本例以Keras实现深度学习模型,故需要预装Keras。\n",
"\n",
"* 请在环境变量中设置`DB_URI`指向数据库"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"\n",
"import os\n",
"import datetime as dt\n",
"import numpy as np\n",
"import pandas as pd\n",
"from alphamind.api import *\n",
"from PyFin.api import *\n",
"from keras.models import Sequential\n",
"from keras.layers import Dense \n",
"from alphamind.model.modelbase import create_model_base"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 使用Keras构建模型(以线性回归为例)\n",
"\n",
"### 构建Keras的接口模型\n",
"\n",
"- alpha-mind中所有的模型算法都是通过底层接口模型实现的。在接口模型中都有统一的训练与预测方法,即*fit* 和 *predict*。\n",
"- 下面的代码就是创建一个接口类,使用Keras实现线性回归的算法。*fit* 和 *predict* 分别对应拟合与预测功能。"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"class LinearRegressionImpl(object):\n",
" def __init__(self, **kwargs):\n",
" self.learning_rate = kwargs.get('learning_rate', 0.01)\n",
" self.training_epochs = kwargs.get('training_epochs', 10)\n",
" self.display_steps = kwargs.get('display_steps', None)\n",
" self.W = None\n",
" self.b = None\n",
"\n",
" def result(self):\n",
" with tf.Session() as sess:\n",
" ret = [sess.run(self.W), sess.run(self.b)]\n",
" return ret\n",
"\n",
" def fit(self, x, y):\n",
" num_samples, num_features = x.shape\n",
"\n",
" output_dim = 1\n",
" input_dim = num_features\n",
" model = Sequential()\n",
" model.add(Dense(output_dim, input_dim=input_dim, kernel_initializer='normal', activation='linear'))\n",
" model.compile(loss='mean_squared_error', optimizer='adam')\n",
" model.fit(x, y, epochs=self.training_epochs, verbose=)\n",
"\n",
" print('Optimization finished ......')\n",
" self.model = model\n",
"\n",
" def predict(self, x):\n",
" ret = self.model.predict(x)\n",
" return np.squeeze(ret)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"为了与alpha-mind的框架对接,还需要定义如下一个wrapper。这个wrapper需要实现*load* 和*save* 两种方法。"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"class LinearRegressionKS(create_model_base()):\n",
" def __init__(self, features, fit_target, **kwargs):\n",
" super().__init__(features=features, fit_target=fit_target)\n",
" self.impl = LinearRegressionImpl(**kwargs)\n",
"\n",
" @classmethod\n",
" def load(cls, model_desc: dict):\n",
" return super().load(model_desc)\n",
"\n",
" def save(self):\n",
" model_desc = super().save()\n",
" model_desc['weight'] = self.impl.result()\n",
" return model_desc\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 测试Keras模型\n",
" \n",
"### 数据配置\n",
"------------"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"freq = '60b'\n",
"universe = Universe('zz800')\n",
"batch = 1\n",
"neutralized_risk = industry_styles\n",
"risk_model = 'short'\n",
"pre_process = [winsorize_normal, standardize]\n",
"post_process = [standardize]\n",
"warm_start = 3\n",
"data_source = os.environ['DB_URI']\n",
"horizon = map_freq(freq)\n",
"\n",
"engine = SqlEngine(data_source)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"我们使用当期的`roe_q`因子,来尝试预测未来大概一个月以后的`roe_q`因子。\n",
"\n",
"* 训练的股票池为`zz800`;;\n",
"* 因子都经过中性化以及标准化等预处理;\n",
"* 预测模型使用线性模型,以20个工作日为一个时间间隔,用过去4期的数据作为训练用特征。"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"\n",
"kernal_feature = 'roe_q'\n",
"regress_features = {kernal_feature: LAST(kernal_feature),\n",
" kernal_feature + '_l1': SHIFT(kernal_feature, 1),\n",
" kernal_feature + '_l2': SHIFT(kernal_feature, 2),\n",
" kernal_feature + '_l3': SHIFT(kernal_feature, 3)\n",
" }\n",
"fit_target = [kernal_feature]\n",
"\n",
"data_meta = DataMeta(freq=freq,\n",
" universe=universe,\n",
" batch=batch,\n",
" neutralized_risk=neutralized_risk,\n",
" risk_model=risk_model,\n",
" pre_process=pre_process,\n",
" post_process=post_process,\n",
" warm_start=warm_start,\n",
" data_source=data_source)\n",
"\n",
"regression_model_ks = LinearRegressionKS(features=regress_features, fit_target=fit_target, training_epochs=400)\n",
"regression_composer_ks = Composer(alpha_model=regression_model_ks, data_meta=data_meta)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 模型对比(sklearn线性回归模型 v.s. keras线性回归模型): IC 系数\n",
"------------------"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### model train and predict\n",
"- train: 给定ref_date, 模型提取ref_date之前的所有训练日期的因子数据,以及ref_date当日的收益率数据进行训练。\n",
"- predict: 给定ref_date, 模型提取ref_date当日的因子数据,预测下一期的收益率数据。\n",
"- ic:给定ref_date, 模型用预测的结果与下一期真实的收益率数据求相关性。"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
"ref_date = '2017-01-31'\n",
"ref_date = adjustDateByCalendar('china.sse', ref_date).strftime('%Y-%m-%d')"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"regression_model_sk = LinearRegression(features=regress_features, fit_target=fit_target)\n",
"regression_composer_sk = Composer(alpha_model=regression_model_sk, data_meta=data_meta)"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"E:\\workarea\\software\\conda3\\lib\\site-packages\\alpha_mind-0.2.0-py3.6-win-amd64.egg\\alphamind\\data\\transformer.py:76: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n",
" dropna=False)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Optimization finished ......\n",
"\n",
"Sklearn Regression Testing IC: 0.5464\n",
"Keras Regression Testing IC: 0.5462\n"
]
}
],
"source": [
"regression_composer_sk.train(ref_date)\n",
"regression_composer_ks.train(ref_date)\n",
"print(\"\\nSklearn Regression Testing IC: {0:.4f}\".format(regression_composer_sk.ic(ref_date=ref_date)))\n",
"print(\"Keras Regression Testing IC: {0:.4f}\".format(regression_composer_ks.ic(ref_date=ref_date)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 回测( simple long short strategy)\n",
"--------------------------"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 策略的初始化\n",
"\n",
"#### 加载数据: fetch_data_package\n",
"- 因子数据\n",
"- 行业数据\n",
"- 风险模型数据\n",
"- 数据的预处理"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2018-08-09 13:35:24,689 - ALPHA_MIND - INFO - Starting data package fetching ...\n",
"E:\\workarea\\software\\conda3\\lib\\site-packages\\alpha_mind-0.2.0-py3.6-win-amd64.egg\\alphamind\\data\\transformer.py:76: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n",
" dropna=False)\n",
"2018-08-09 13:35:25,457 - ALPHA_MIND - INFO - factor data loading finished\n",
"2018-08-09 13:36:15,526 - ALPHA_MIND - INFO - fit target data loading finished\n",
"2018-08-09 13:36:15,774 - ALPHA_MIND - INFO - industry data loading finished\n",
"2018-08-09 13:36:15,918 - ALPHA_MIND - INFO - benchmark data loading finished\n",
"2018-08-09 13:36:16,656 - ALPHA_MIND - INFO - data merging finished\n",
"2018-08-09 13:36:16,714 - ALPHA_MIND - INFO - Loading data is finished\n",
"2018-08-09 13:36:16,748 - ALPHA_MIND - INFO - Data processing is finished\n"
]
}
],
"source": [
"start_date = '2011-01-01'\n",
"end_date = '2012-01-01'\n",
"\n",
"data_package2 = fetch_data_package(engine,\n",
" alpha_factors=[kernal_feature],\n",
" start_date=start_date,\n",
" end_date=end_date,\n",
" frequency=freq,\n",
" universe=universe,\n",
" benchmark=906,\n",
" warm_start=warm_start,\n",
" batch=1,\n",
" neutralized_risk=neutralized_risk,\n",
" pre_process=pre_process,\n",
" post_process=post_process)\n",
"\n",
"model_dates = [d.strftime('%Y-%m-%d') for d in list(data_package2['predict']['x'].keys())]\n",
"\n",
"\n",
"industry_name = 'sw_adj'\n",
"industry_level = 1\n",
"\n",
"industry_names = industry_list(industry_name, industry_level)\n",
"industry_total = engine.fetch_industry_matrix_range(universe, dates=model_dates, category=industry_name, level=industry_level)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 运行策略:(sklearn线性回归模型 v.s.keras线性回归模型)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2018-08-09 13:36:59,018 - ALPHA_MIND - INFO - 2011-01-04 full re-balance: 799\n",
"E:\\workarea\\software\\conda3\\lib\\site-packages\\alpha_mind-0.2.0-py3.6-win-amd64.egg\\alphamind\\data\\transformer.py:76: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n",
" dropna=False)\n",
"2018-08-09 13:37:03,020 - ALPHA_MIND - INFO - 2011-01-04 is finished\n",
"2018-08-09 13:37:03,028 - ALPHA_MIND - INFO - 2011-04-07 full re-balance: 798\n",
"2018-08-09 13:37:06,784 - ALPHA_MIND - INFO - 2011-04-07 is finished\n",
"2018-08-09 13:37:06,794 - ALPHA_MIND - INFO - 2011-07-04 full re-balance: 798\n",
"2018-08-09 13:37:10,646 - ALPHA_MIND - INFO - 2011-07-04 is finished\n",
"2018-08-09 13:37:10,655 - ALPHA_MIND - INFO - 2011-09-27 full re-balance: 797\n",
"2018-08-09 13:37:14,539 - ALPHA_MIND - INFO - 2011-09-27 is finished\n",
"2018-08-09 13:37:14,548 - ALPHA_MIND - INFO - 2011-12-27 full re-balance: 798\n",
"2018-08-09 13:37:18,448 - ALPHA_MIND - INFO - 2011-12-27 is finished\n"
]
}
],
"source": [
"rets1 = []\n",
"rets2 = []\n",
"\n",
"\n",
"\n",
"for i, ref_date in enumerate(model_dates):\n",
" py_ref_date = dt.datetime.strptime(ref_date, '%Y-%m-%d')\n",
" industry_matrix = industry_total[industry_total.trade_date == ref_date]\n",
" dx_returns = pd.DataFrame({'dx': data_package2['predict']['y'][py_ref_date].flatten(),\n",
" 'code': data_package2['predict']['code'][py_ref_date].flatten()})\n",
" \n",
" res = pd.merge(dx_returns, industry_matrix, on=['code']).dropna()\n",
" codes = res.code.values.tolist()\n",
" \n",
" alpha_logger.info('{0} full re-balance: {1}'.format(ref_date, len(codes)))\n",
" \n",
" ## sklearn regression model\n",
" \n",
" raw_predict1 = regression_composer_sk.predict(ref_date).loc[codes]\n",
" er1 = raw_predict1.fillna(raw_predict1.median()).values\n",
" \n",
" target_pos1, _ = er_portfolio_analysis(er1,\n",
" res.industry_name.values,\n",
" None,\n",
" None,\n",
" False,\n",
" None,\n",
" method='ls')\n",
" \n",
" target_pos1['code'] = codes\n",
" result1 = pd.merge(target_pos1, dx_returns, on=['code'])\n",
" ret1 = result1.weight.values @ (np.exp(result1.dx.values) - 1.)\n",
" rets1.append(np.log(1. + ret1))\n",
"\n",
" ## keras regression model\n",
" \n",
" raw_predict2 = regression_composer_ks.predict(ref_date).loc[codes]\n",
" er2 = raw_predict2.fillna(raw_predict2.median()).values\n",
" \n",
" target_pos2, _ = er_portfolio_analysis(er2,\n",
" res.industry_name.values,\n",
" None,\n",
" None,\n",
" False,\n",
" None,\n",
" method='ls')\n",
" \n",
" target_pos2['code'] = codes\n",
" result2 = pd.merge(target_pos2, dx_returns, on=['code'])\n",
" ret2 = result2.weight.values @ (np.exp(result2.dx.values) - 1.)\n",
" rets2.append(np.log(1. + ret2))\n",
" ## perfect forcast\n",
" \n",
" alpha_logger.info('{0} is finished'.format(ref_date))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 收益图对比"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x12194748>"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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2vD0009z1113/eU1U6dOZerUqTRo0ADwFdlr167lqquuolevXowZMwaAzZs3s3btWkqVKkVoaCjt2rX7035uvfVWABo2bMjXX3+d6+MVERERyS8ysxyhIfn7QgeBGHFOASpnW64EbM22XAyoA8w0s41AY2B8TicIOuf6OefinXPxZcqUCUC0wLvwwgtJSkqibt26PPfcc7z22msANGnShEmTJuGc+8trnHM899xzLF68mMWLF7Nu3Truu+8+Zs6cybRp05g7dy5LliyhQYMGf1xOLioqitDQ0D/tJzIyEoDQ0FAyMjLO8pGKiIiI5I1tqYe4/oNZ/LTurxdbyE8CMeK8AKhuZtWALUB7oMPRjc65VKD00WUzmwl0c84l5qbTk40Mny1bt24lLi6Ojh07EhMTw6BBgwB47bXXeP3113n44Yf55JNP/vSali1b8tJLL3HXXXcRExPDli1bCA8PJzU1lZIlSxIdHc2qVauYN2+eB0ckIiIi4p3fDxyh84AE9qfuoniR/H3341yPODvnMoBHgClAMjDSObfCzF4zs5tzu//8ZtmyZTRq1IiLL76YN998kxdffPGPbe+//z5paWk8/fTTf3pNixYt6NChA5dffjl169bltttuY9++fbRq1YqMjAzq1avHSy+9ROPGjfP6cEREREQ8s/9wBl0GLSB690pmRz5Bnd+neR3phCynqQX5QXx8vEtM/POgdHJyMjVr1vQoUXDQeyQiIiLB4HBGJvcOWsCvG1YwsdibREYWgXsnQ4nKJ39xgJlZknPupPcZCcRUDRERERGRU5aZ5Xhi+GLWr1vD9JI9iDSg81hPiubTocJZRERERPKMc47nv17GvOVr+L5UT4qm74Mu30Dp6l5HOykVziIiIiKSZ96avIpvE9cwrXQvSh7aAp2+hgoNvI51SlQ4i4iIiEie6PPDegb9sIqJpT+m/IHVcMdQqNrU61inTIWziIiIiJx1wxN+ofukFXxdegDn70+CW/rCRTd4Heu0qHAWERERkbNq0rJtPD9mKYNKDaX+/tnQ6i2o397rWKctEHcOLFQ2btxInTp1vI4hIiIiEhTmrN3J48MX0bPkaK46MAWufgYaP+R1rDOiwjmPZGZmeh1BREREJE8t+uV3un6eyHPFJtHm4NfQqCtc85zXsc6YCudc2LBhAw0aNGD+/Pn861//4tJLL6Ve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\n",
"text/plain": [
"<Figure size 864x432 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ret_df = pd.DataFrame({'sklearn': rets1, 'keras': rets2}, index=model_dates)\n",
"ret_df.loc[advanceDateByCalendar('china.sse', model_dates[-1], freq).strftime('%Y-%m-%d')] = 0.\n",
"ret_df = ret_df.shift(1)\n",
"ret_df.iloc[0] = 0.\n",
"\n",
"ret_df[['sklearn', 'keras']].cumsum().plot(figsize=(12, 6),\n",
" title='Fixed freq rebalanced: {0}'.format(freq))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
},
"varInspector": {
"cols": {
"lenName": 16.0,
"lenType": 16.0,
"lenVar": 40.0
},
"kernels_config": {
"python": {
"delete_cmd_postfix": "",
"delete_cmd_prefix": "del ",
"library": "var_list.py",
"varRefreshCmd": "print(var_dic_list())"
},
"r": {
"delete_cmd_postfix": ") ",
"delete_cmd_prefix": "rm(",
"library": "var_list.r",
"varRefreshCmd": "cat(var_dic_list()) "
}
},
"types_to_exclude": [
"module",
"function",
"builtin_function_or_method",
"instance",
"_Feature"
],
"window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment