经过和坛子里的朋友友好讨论以后,我决定还是把样本按照时间序列切除一下,把最后100~228行数据拿出来不放在训练和测试集里分割,做一个样本外测试集来score一下比较比较模型效果,看看这样做了以后,我们3个模型的表现。
前3个帖子回顾:
测试模型稳健性的结果发现,只剩下决策树这个最简单的模型表现得还稳健一些了(果然简简单单才是真吗?),然而对样本外测试的准确率也从对样本内测试的0.9跌到了0.8左右。而adaboost和SVM的预测准确率就在那里上下波动,上下波动……一点都不听话。
为啥adaboost和SVM在那里光波动不听话呢?它光不听话也就算了。它不光不听话,预测准确率还很有规律地要么高,要么低,也不是单纯地上下摆动。而且预测准确率极低的时候吧,和决策树对比,准确率相加恰好为1,为毛相加以后准确率恰好为1呢?这到底是为什么呢?我怎么想都想不明白。
根据论坛里朋友的建议,我按照时间周期重新生成了3个数据集,训练集,测试集,周期后测试集,来共同判断准确率。
import numpy as np
import pandas as pd
from CAL.PyCAL import Date
from CAL.PyCAL import Calendar
from CAL.PyCAL import BizDayConvention
from sklearn.ensemble import AdaBoostClassifier
start = '2014-01-01' # 回测起始时间
end = '2016-12-01' # 回测结束时间
benchmark = 'HS300' # 策略参考标准
universe = set_universe('HS300') # 证券池,支持股票和基金
capital_base = 100000 # 起始资金
freq = 'd' # 策略类型,'d'表示日间策略使用日dw线回测,'m'表示日内策略使用分钟线回测
refresh_rate = 1 # 调仓频率,表示执行handle_data的时间间隔,若freq = 'd'时间间隔的单位为交易日,若freq = 'm'时间间隔为分钟
import talib
2
def max_arr(arr):
3
try:
4
se=talib.MAX(np.array(arr),30)
5
except:
6
se=np.array([np.nan]*len(arr))
7
return se
8
def min_arr(arr):
9
try:
10
se=talib.MIN(np.array(arr),30)
11
except:
12
se=np.array([np.nan]*len(arr))
13
return se
14
fields = ['tradeDate','closeIndex', 'highestIndex','lowestIndex', 'turnoverVol','CHG','CHGPct']
15
stock = '000300'
16
#tradeDate是交易日、closeIndex是收盘指数、highestIndex是当日最大指数,lowestIndex是当日最小指数,CHG是涨跌
17
index_raw = DataAPI.MktIdxdGet(ticker=stock,beginDate=u"2006-03-01",endDate=u"2015-03-01",field=fields,pandas="1")
18
index_date = index_raw.set_index('tradeDate')
19
index_date = index_date.dropna()
20
index_date['max_difference'] = index_date['highestIndex'] - index_date['lowestIndex']
21
index_date['max_of_30day']=index_date.apply(max_arr)['highestIndex']
22
index_date['min_of_30day']=index_date.apply(min_arr)['lowestIndex']
23
index_date['max_difference_of_30day']=index_date.apply(max_arr)['max_difference']
24
index_date['closeIndex_after30days']=np.nan
25
index_date['closeIndex_after30days'][0:-30]=np.array(index_date['closeIndex'][30:])
26
index_date = index_date.dropna() #去掉前30个和后30个无效的数据。
27
lables_raw = index_date['closeIndex_after30days'] #提取出需要预测的数据
28
lables = index_date['closeIndex_after30days'] > index_date['closeIndex'] #为分类处理数据,判断30天后的收盘价是否大于今日收盘价
29
lables_ud = lables.replace({True:'up',False:'down'}) #方便他人阅读,将True和False改为up和down,意味着30天后收盘价涨了还是跌了
30
features = index_date.drop(['closeIndex_after30days'],axis = 1) #在特征值中去掉我们要预测的数据。
这里我选用前1900个数据分割训练集和测试集,1900个数据的时间点以后的328来个数据预留出来,用来做时间周期后测试。
from sklearn import cross_validation
from sklearn import preprocessing
features_1 = features[:1900]
features_2 = features[1900:]
lables_1 = lables[:1900]
lables_2 = lables[1900:]
scaler1 = preprocessing.StandardScaler().fit(features_1)
features_scaler_1 = scaler1.transform(features_1)
scaler2 = preprocessing.StandardScaler().fit(features_2)
features_scaler_2 = scaler2.transform(features_2)
#上面4行代码用来标准化数据
X_train,X_test, y_train, y_test = cross_validation.train_test_split(features_scaler_1, lables_1, test_size = 0.2, random_state = 0)
接下来先来比较adaboost的:
clf_AdaBoost = AdaBoostClassifier(n_estimators = 340 , learning_rate = 1.53 )
clf_AdaBoost.fit(X_train, y_train)
print "样本内预测准确率为:%0.2f" % (clf_AdaBoost.score(X_test,