2023年6月29日发(作者:)
python⽀持向量机股票_⼩蛇学python(4)利⽤SVM预测股票涨跌最近接了⼀个私活,指导学妹完成毕业设计。核⼼思想就是利⽤SVM模型来预测股票涨跌,并完成策略构建,⾃动化选择最优秀的股票进⾏资产配置。在做这个项⽬的过程中,我体会到想成为⼀个合格的数据分析或者数据挖掘⼯程师不仅技术要过关,还需要了解所要挖掘数据涉及到的领域的相关知识。举个例⼦,在做数据预处理的时候,不知道超额收益率是怎么个意思,查阅资料才了解,超额收益率是股票⾏业⾥的⼀个专有名词,指⼤于⽆风险投资的收益率,在我国⽆风险投资收益率即是银⾏定期存款。也稍微打个⼩⼴告,简书上如果有需要做毕业设计的同学可以找我私聊哦。⽽且如果只是简单咨询⼀些技术问题,学长会很热⼼得解答。废话少说,⾔归正传。这⾥有关SVM、PCA等等这些与项⽬相关的数学知识不会提及,我以后会在算法专题⾥详细描述。本项⽬⽤pycharm + anaconda3.6开发,涉及到的第三⽅库有pandas,numpy,matplotlib,skllearn。流程图Quotation 参数设置class Para:method = 'SVM' #模型选择为SVMmonth_in_sample = range(1, 7 + 1) #训练集数据对应⽉份month_test = range(8, 12 + 1) #测试集数据对应⽉份percent_select = [0.3, 0.3] #正反例股票选取⽐例percent_cv = 0.1 #交互验证机占样本内数据⽐例path_data = 'C:/my python/python code/stock predict/Datas/Tests/Tests/' #输⼊数据⽂件路径path_result = 'C:/my python/python code/stock predict/Datas/Results/' #输出数据⽂件路径seed = 42 #random seed设置随机种⼦,制造伪随机数svm_kernel = 'linear' #⽀持向量机的核函数类型svm_c = 0.01 #线性⽀持向量机的惩罚系数para = Para()这个就是参数的初始化,没有什么要说的。数据读取以及标记#function: label data#3数据标记def label_data(data):data['return_bin'] = #在data表格最后添加⼀列,并命名为return_bin,这⼀列将记录每个样本的标签data = _values(by = '超额收益', ascending = False) #将整个表格按照return列的值降序排列n_stock_select = ly(t_select, [0]) #选取的股票个数n_stock_select = (n_stock_select).astype(int) #将上⾏所选取的股票个数取整,注意n_stock_select是个含有两个整数的列表[0:n_stock_select[0],-1] = [-n_stock_select[1]:, -1] = 0 #这两⾏将表现好的股票标签置1,差的置0data = (axis = 0) #将没有1,0标签的,即不是最好的前百分之三⼗也不是最差的前百分之三⼗股票从表格⾥剔除return data#4数据读取for i_month in _in_sample:file_name = _data + str(i_month) + '.csv'data_curr_month = _csv(file_name, header = 0) #header=0意思是将表格第⼀⾏作为列名para.n_stcok = data_curr_[0]data_curr_month = data_curr_(axis = 0) #去除缺省值data_curr_month = label_data(data_curr_month) #将读⼊的数据进⾏标记if i_month == _in_sample[0]:data_in_sample = data_curr_monthelse:data_in_sample = data_in_(data_curr_month)print('数据读取完成')#5数据预处理X_in_sample = data_in_[:,'货币资⾦(万元)':'应收分保账款(万元)']y_in_sample = data_in_[:,'return_bin'] #从样本内数据中分别提取特征与标签因⼦X_train,X_cv,y_train,y_cv = train_test_split(X_in_sample,y_in_sample,test_size=t_cv, random_state=)#按照固定⽐例随机分配训练集与交叉验证集pca = (n_components=0.95)(X_train)X_train = orm(X_train)X_cv = orm(X_cv) #以上是关于主成分分析模型的代码print('数据预处理完成')代码的基本功能注释⾥也写了⼀些,不过不够全⾯,我再详细说⼀下。这三部分代码所实现的功能是读取数据,并对数据进⾏预处理。我已经把最原始的数据整理好放在了excel表格⾥,并且将第⼀个⽉的全部股票的参数放在⼀个excel⾥,并将其命名为,以此类推,我爬取了157个⽉的数据,总共有157个excel。因此代码⾥循环的便是excel的⽂件名,也就是依次读取excel⽂件。因为数据量太⼤,所以我⼀般调试的时候只跑12个⽉。所以我在参数初始化阶段,训练集(1,8),测试集(8,12)。数据截⾯.png将数据读取到DataFrame表格⾥后,并不是全部使⽤,⽽是取超额收益值最好的前百分之三⼗,以及最差的后百分之三⼗,并在表格后追加⼀列,列名叫return_bin,将最好最差的百分之三⼗的股票的return_bin列各赋值1,0。然后将每个读取并加⼯的excel表格拼接在⼀起形成⼀个⼤表格,从总抽取70个因⼦作为X_in_sample,抽取return_bin作为y_in_sample作为训练集。训练模型#6print('选择模型')if == 'SVM':model = (kernel=_kernel, C=_c)print('模型选择为SVM')#7⽤训练好的模型分别放到训练集和验证集上去预测,⽤来调参print('模型开始训练')if == 'SVM':(X_train, y_train)y_pred_train = t(X_train)y_score_train = on_function(X_train)y_pred_cv = t(X_cv)y_score_cv = on_function(X_cv)print('模型训练结束')这个也⽐较好理解,就是选择sklearn库⾥的svm模块对数据进⾏训练。svm模型是集成封装好的,拿来⽤就可以。模型预测与评价#8使⽤训练完成的模型再测试集上做预测print('模型预测开始')y_true_test = ame([] * ((para.n_stcok, _test[-1])))y_pred_test = ame([] * ((para.n_stcok, _test[-1])))y_score_test = ame([] * ((para.n_stcok, _test[-1]))) #先对各种参数做⼀个初始化print(y_true_test)for i_month in _test: #遍历测试集的每⼀个⽉份,每个⽉份都有上市的所有股票file_name = _data + str(i_month) + '.csv' #读取预测集上的数据data_curr_month = _csv(file_name, header=0)data_curr_month = data_curr_(axis=0)X_curr_month = data_curr_[:,'货币资⾦(万元)':'应收分保账款(万元)']X_curr_month = orm(X_curr_month)if == 'SVM':y_pred_curr_month = t(X_curr_month)y_score_curr_month = on_function(X_curr_month)y_true_[data_curr_, i_month - 1] = data_curr_month['超额收益'][data_curr_]y_pred_[data_curr_, i_month - 1] = y_pred_curr_monthy_score_[data_curr_, i_month - 1] = y_score_curr_monthprint(y_true_test)print('模型预测结束')#9模型评价print('模型开始评价')print('training set, accuracy = %.2f'%cy_score(y_train, y_pred_train))print('training set, ACU = %.2f'%_auc_score(y_train, y_score_train))print('cv set, accuracy = %.2f'%cy_score(y_cv, y_pred_cv))print('cv set, ACU = %.2f'%_auc_score(y_cv, y_score_cv))for i_month in _test:y_true_curr_month = ame({'超额收益':y_true_[:, i_month - 1]})y_pred_curr_month = y_pred_[:,i_month - 1]y_score_curr_month = y_score_[:,i_month - 1]y_true_curr_month = y_true_curr_(axis=0)y_curr_month = label_data(y_true_curr_month)['return_bin']y_pred_curr_month = y_pred_curr_month[y_curr_]y_score_curr_month = y_score_curr_month[y_curr_]print('test set, month %d, accuracy = %.2f'%(i_month, cy_score(y_curr_month, y_pred_curr_month)))print('test set, month %d, AUC = %.2f'%(i_month, _auc_score(y_curr_month, y_score_curr_month)))print('模型评价结束')现在模型就训练好了,然后就那训练好的模型在测试集上来跑,看看情况到底如何。模型评价.png可以看到参数并不是多好,这是训练集上数据太少的原因。那我们来改动⼀下,把训练集改成(1,10),测试集改成(10,12)看看有没有改变。模型评价训练集从只有6个⽉变成9个⽉(1-10在代码上体现为1-9),参数情况⼤有改观。可见数据对机器学习模型训练的重要性。策略构建以及策略评价#10策略构建print('策略构建开始')para.n_stcok_select = 3strategy = ame({'return' : [0]*_test[-1], 'value' : [1]*_test[-1]}) #这并不是字典格式,⽽是表格格式,分别表⽰每⽉收益和每⽉净值,初始值为0和1print(strategy)for i_month in _test:y_true_curr_month = y_true_[:,i_month - 1]print(y_true_curr_month)y_score_curr_month = y_score_[:,i_month - 1]y_score_curr_month = y_score_curr__values(ascending=False)print(y_score_curr_month)index_select = y_score_curr_month[0:para.n_stcok_select].indexprint(index_select)[i_month-1, 'return'] = (y_true_curr_month[index_select])print(strategy)strategy['value'] = (strategy['return'] + 1).cumprod()print('策略构建结束')#11策略评价print('策略评价开始')month_test = (_test)month_test = month_test - 1print([month_test, 'value'])(month_test, [month_test, 'value'],'r-')()ann_excess_return = ([month_test,'return']) * 12 #策略年化超额收益print(ann_excess_return)ann_excess_vol = ([month_test,'return']) * (12) #策略年化超额收益波动info_ratio = ann_excess_return/ann_excess_vol #数值越⼤策略越好print('annual excess return = %.2f'%ann_excess_return)print('annual excess volatility = %.2f'%ann_excess_vol)print('information ratio = %.2f'%info_ratio)print('以上为策略评价参数')print('策略评价结束')所谓策略构建就是选择什么样的股票,代码⾥将股票按照超额收益率进⾏排序,然后我设置para.n_stcok_select = 3意思就是选择超额收益率前三名进⾏购买。所谓策略评价这⾥采⽤的评价体系就是将选择的三⽀股票的每⽉超额收益率取平均值乘12,来作为这三只股票在该⽉的年化收益率。Figure_ure_以上两张图是选择不同⽉份做训练集后,模型策略的表现。在这⾥还要提及的是这⾏代码,month_test = (_test)month_test = month_test - 1。这个涉及到了np数组的⾼阶⽤法。⼀般数组是⽆法和数字做运算的,可是将普通数组⽤()加⼯过后,变成了np数组,他拥有⼀个⼴播属性,可以直接与数字运算。该⾏代码就是将数组⾥每个元素都减1。想要数据集跑程序⼜不会爬⾍的可以私聊我,可以分享
发布者:admin,转转请注明出处:http://www.yc00.com/web/1687977677a62895.html
评论列表(0条)