作者:阿布🐶
未经本人允许禁止转载
目录章节地址: 自己动手写一个印钞机 第一章 自己动手写一个印钞机 第二章 自己动手写一个印钞机 第三章 自己动手写一个印钞机 第四章 自己动手写一个印钞机 第五章 自己动手写一个印钞机 第六章 自己动手写一个印钞机 第七章
简书目录章节地址: 自己动手写一个印钞机 第一章 自己动手写一个印钞机 第二章 自己动手写一个印钞机 第三章 自己动手写一个印钞机 第四章 自己动手写一个印钞机 第五章 自己动手写一个印钞机 第六章 自己动手写一个印钞机 第七章 自己动手写一个印钞机 附录章
非均衡胜负收益带来的必然非均衡胜负比例,目标由因子的能力解决一部分,模式识别提升关键的一部分
本章开始说文章的核心了,模式识别提升关键的一部分 本章的内容主要是通过机器学习如svm,随机森林等对stock模式识别的初步探索,俗称罪恶的第一步,但还是要坚定的卖出,毕竟目标是印钞机
下面运行因子对多年数据进行回测,模式识别中基本的需求就是生成训练集数据与测试集数据,对训练集的数据抽取特质,总结规律,在测试集上指导交易,与没有指导交易的测试集进行比对,查看效果。
BuyGoldenFactor.g_enable_filter_ml = True # 回测因子的历史且结果集加入机器学习需要的数据
BuyGoldenFactor.g_enable_snap = True # 生成交易这一时刻60日图像,为深度学习准备, 详情见第四章
buy_factors = [{'XD': 42, 'class': BuyGoldenFactorClass, 'draw': True}]
# n_folds: 6年数据回测生成五年单子
# train_test_split:回测时预留一份stock代码表作为测试集,生成9份训练集,当use_last_test为True 时只用一份测试stock代码表进行因子回测
# ret_cnt_need = 0:回测所有stock
out, orders_pd_train_snap = MetricsManger.make_metrics_rsc_mul_symbol_grid(buy_factors, n_folds=6,
score_type=METRICSTYPE.SYSMBOL_R_SCORES_GOLDEN.value, ret_cnt_need=0, train_test_split=True,
use_last_test=False, force_one_process=False)
pd.options.display.max_columns = 40
orders_pd_train_snap.tail(2) # 看看添加了提供机器学习数据的pandas
由于简书不支持html的表格,完整表格请查阅git上完整版ipython notebook
这些特征都是什么比如deg_windowPd就是买入stock这一天前42天k线图的线性拟合斜率,deg_hisWindowPd是252天k线图的线性拟合斜率,它们代表了买入前stock的一种状态也就能代表一种特征,你可以理解为这些特征都是发生交易前的一些状态的量化值特征,暂时没有必要全部深入了解,知道是特征就行。
下面生成测试集数据
BuyGoldenFactor.g_enable_fiter = False
BuyGoldenFactor.g_enable_snap = True
buy_factors = [{'XD': 42, 'class': BuyGoldenFactorClass, 'draw': True}]
out, orders_pd_test = MetricsManger.make_metrics_rsc_mul_symbol_grid(buy_factors, n_folds=6,
score_type=METRICSTYPE.SYSMBOL_R_SCORES_GOLDEN.value, ret_cnt_need=0, train_test_split=False,
use_last_test=True, force_one_process=False)
orders_pd_train_snap.shape, orders_pd_test_snap.shape
# out
((44412, 32), (4956, 32))
对训练集及测试集的结果进行大体的度量:主要就是看看非均衡胜负收益带来的必然非均衡胜负比例,目标由因子的能力解决一部分效果怎么样
train_ump = UmpMainClass(orders_pd_train_snap, MlFiterGoldenPdClass)
train_ump.show_general()
# out
all fit order = (41225, 32)
win rate = 0.493559733172
profit_cg.sum() = 281.687935222
win mean = 0.0770327160087 loss_mean = -0.061738192442
test_ump = UmpMainClass(orders_pd_test_snap, MlFiterGoldenPdClass)
test_ump.show_general()
# out
all fit order = (4612, 32)
win rate = 0.5
profit_cg.sum() = 37.4002795407
win mean = 0.076550446692 loss_mean = -0.0605681543452
显示在所有有结果的单子中胜率可以接近一半,且每次赢的0.07比没次输的0.06多, 但是贪婪的我仍然认为有优化空间,这个空间就是利用这个因子产生的输出数据 作为特征识别基础,提炼特征,指导交易,
模式识别提升关键的一部分
下面我们看看如何做到的呢
首先确认ml封装库是否能正常运行
test_fiter_more = MlFiterClass.create_test_more_fiter()
学习曲线
test_fiter_more.estimator.logistic_regression()
test_fiter_more.plot_learning_curve()
特征权重
test_fiter.importances_coef_pd()
树逻辑图
test_fiter.plot_graphviz_tree()
混淆矩阵
test_fiter_more.plot_confusion_matrices()
# out
[[453 96]
[100 242]]
roc
test_fiter_more.plot_roc_estimator()
特征选择
test_fiter_more.feature_selection()
# out
RFE selection
ranking support
SibSp 1 True
Parch 1 True
Cabin_No 1 True
Cabin_Yes 6 False
Embarked_C 2 False
Embarked_Q 5 False
Embarked_S 3 False
Sex_female 8 False
Sex_male 1 True
Pclass_1 4 False
Pclass_2 7 False
Pclass_3 1 True
Age_scaled 1 True
Fare_scaled 1 True
RFECV selection
ranking support
SibSp 1 True
Parch 2 False
Cabin_No 1 True
Cabin_Yes 7 False
Embarked_C 3 False
Embarked_Q 8 False
Embarked_S 4 False
Sex_female 1 True
Sex_male 9 False
Pclass_1 5 False
Pclass_2 6 False
Pclass_3 1 True
Age_scaled 1 True
Fare_scaled 1 True
决策边界
test_fiter.plot_decision_function()
train test score
test_fiter_more.cross_val_accuracy_score()
# out
accuracy mean: 0.776812507093
array([ 0.75555556, 0.72222222, 0.73033708, 0.75280899, 0.83146067,
0.78651685, 0.80898876, 0.71910112, 0.82022472, 0.84090909])
切换使用其它学习方法
test_fiter_more.estimator.adaboost_classifier()
test_fiter_more.cross_val_accuracy_score()
# out
accuracy mean: 0.810433548973
array([ 0.78888889, 0.78888889, 0.78651685, 0.80898876, 0.84269663,
0.78651685, 0.82022472, 0.82022472, 0.79775281, 0.86363636])
可以证明封装库没有问题,可以放心使用,下一步上真正的stock数据
由252,60, 42天组成的走势数剧作为特质开始
from MlFiterDegPd import MlFiterDegPdClass
deg = MlFiterDegPdClass(orderPd=orders_pd_train_snap)
deg.df.head()
deg().estimator.svc()
deg().cross_val_accuracy_score()
# out
accuracy mean: 0.491279520472
array([ 0.48920689, 0.51758428, 0.49987873, 0.49551298, 0.48168809,
0.4887218 , 0.47610963, 0.47355653, 0.4853191 , 0.50521718])
0.49的准确率,相当于是乱猜 是不是特征选择的不好呢,换一些特征试试
from MlFiterMainPd import MlFiterMainPdClass
main = MlFiterMainPdClass(orderPd=orders_pd_train_snap)
main.df.head()
main().cross_val_accuracy_score()
# out
accuracy mean: 0.493608245706
array([ 0.5008489 , 0.49890856, 0.49793839, 0.48678147, 0.50303177,
0.47125879, 0.49648314, 0.49369238, 0.49332686, 0.49381218])
0.49的准确率,还是乱猜 是不是特征太少了,构建一个特征多的试试
from MlFiter import MlFiterClass
order_has_ret = orders_pd_train_snap[(orders_pd_train_snap.result <> 0)]
all_pd = order_has_ret.filter(['result', 'deg_hisWindowPd', 'deg_windowPd', 'deg_60WindowPd', 'atr_std', 'jump_power',
'diff_days', 'wave_score1', 'wave_score2', 'wave_score23'])
train_np = all_pd.as_matrix()
y = train_np[:, 0]
x = train_np[:, 1:]
all_filter = MlFiterClass(x, y, all_pd)
all_pd.head()
# 这回使用随机森林
all_filter.estimator.random_forest_classifier()
all_filter.cross_val_accuracy_score()
# out
accuracy mean: 0.505349477658
array([ 0.48678147, 0.50788261, 0.53019646, 0.50497211, 0.51297599,
0.46058695, 0.51564395, 0.50994663, 0.4942975 , 0.53021111])
0.50的准确率,这算是有所提升吗?😥
下面把数据离散化后,换种分类器测试
deg = MlFiterDegPdClass(orderPd=orders_pd_train_snap, dummies=True, invoke_hmm=False,
invoke_pca=False)
deg.df.head()
由于简书不支持html的表格,完整表格请查阅git上完整版ipython notebook
上边封住好了的,在离散值的选择上不是瞎来的,会通过可视化来选择离散值bins,通过数据来指导数据最终指导交易
deg().estimator.random_forest_classifier()
deg().cross_val_accuracy_score()
# out
accuracy mean: 0.487590577522
array([ 0.48217317, 0.51564395, 0.4962406 , 0.49890856, 0.49745331,
0.48338588, 0.49527043, 0.45414847, 0.44479495, 0.50788644])
结果还是乱猜
用其它等等方式仍然是胡猜,自己写的类似adaboost依然效果很差, 通过非均衡概率降低假阳,提高假阴的方式,最后统计所有测试集样本的判别概率发现其实还瞎猜
提高分类数量,设置阀值,提高准确率的方案
通过将profit cg qcut 100份分类
orders_pd_train_snap.profit_cg.fillna(0, inplace=True)
order_has_ret = orders_pd_train_snap[(orders_pd_train_snap.result <> 0)]
n_class = 100
order_has_ret['class'] = pd.qcut(order_has_ret.profit_cg, n_class, labels=range(0, n_class))
order_has_ret['class'] = order_has_ret['class'].astype(int)
ZLog.info(np.unique(order_has_ret['class']))
deg_pd = order_has_ret.filter(['class', 'result', 'deg_hisWindowPd', 'deg_windowPd', 'deg_60WindowPd'])
train_np = deg_pd.as_matrix()
y = train_np[:, 0]
x = train_np[:, 1:]
deg = MlFiterClass(x, y, deg_pd, force_clf=True)
deg_pd.head()
-
y为class train_test_split进行分类
-
使用cv数据集的 predict < class阀值 使用result==0的情况查看概率
from sklearn.cross_validation import train_test_split from sklearn.metrics import accuracy_score from sklearn.metrics import classification_report
deg.estimator.random_forest_classifier()
train_df, cv_df = train_test_split(deg.df, test_size=0.1, random_state=0)
fiter = deg.get_fiter() fiter.fit(train_df.as_matrix()[:, 2:], train_df.as_matrix()[:, 0])
predictions = fiter.predict(cv_df.as_matrix()[:, 2:])
cv_df['predict'] = predictions cv_df.head()
cv_df['predict'].value_counts().sort_index().head(10)
# out
0.0 56
1.0 50
2.0 43
3.0 47
4.0 44
5.0 45
6.0 47
7.0 30
8.0 46
9.0 39
Name: predict, dtype: int64
for threshold in np.arange(0, 10):
ppv = cv_df[cv_df['predict'] <= threshold].result.value_counts()
ZLog.info('threshold: {}, ppv: {}'.format(threshold, float(ppv[-1])/ppv.sum()))
# out
threshold: 0, ppv: 0.607142857143
threshold: 1, ppv: 0.632075471698
threshold: 2, ppv: 0.58389261745
threshold: 3, ppv: 0.586734693878
threshold: 4, ppv: 0.579166666667
threshold: 5, ppv: 0.571929824561
threshold: 6, ppv: 0.551204819277
threshold: 7, ppv: 0.541436464088
threshold: 8, ppv: 0.526960784314
threshold: 9, ppv: 0.523489932886
threshold: 0,1,达到0.6了 但是数量上只有100多个,之后会有使用gmm-hmm的方式继续扩展这种思路,提高收益
只能说最后一种的这个思想可以作为扩展使用,实际中由于 '非均衡胜负收益' 很难带来质的好转,突然想到阿西莫夫的小说基地,对心理史学的最开始的评估,‘可能但是不可行’,我们的印钞机之路是否也是这样呢,下一章开始就是真正的印钞机之路了,一个即可能又可行之路!!! 下一章开始将使用深度学习方法来训练数据,提高胜率主要是卷机神经网络的使用
下一章地址 自己动手写一个印钞机 第三章
感谢🙏您能有耐心看到这里
如果有什么问题可以加阿布的微信
微信号:aaaabbbuu
来源:oschina
链接:https://my.oschina.net/u/577691/blog/776216