LASSO是非常经典的机器学习回归模型,XGBoost是具有代表性的集成学习方法。本文以LASSO、XGBoost为例,数据集为沪深300指数的收盘价与7项技术指标(包括MA5,MA20,MA60,MACD,MOM,OBV,RSI,ROC,已通过TA-Lib库完成)观察输入原始数据、差分数据、min-max标准化后的数据、Z-Score标准化后的数据(已通过Excel完成)对于模型误差的影响。
首先,导入任务相关的库。
import tushare as ts
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import Lasso
导入数据集,包括原始的沪深300指数2010年4月14日至2022年4月14日的收盘价与技术指标以及数据预处理后的结果。
CS_300 = pd.read_csv(r'C:\Users\syk\Desktop\CS_300.csv',index_col='trade_date')
所得结果如下表所示。
将原始数据划分为训练集和测试集(此处可以考虑定义函数替代重复的过程)。
_raw代表原始数据
_diff代表差分后的数据
_mm代表min-max标准化后的数据,公式为:
_zs代表Z-Score标准化后的数据,公式为:
data_train=CS_300.iloc[:2334].copy()
data_test=CS_300.iloc[2334:].copy()
feature=['MA5','MA20','MA60','MACD','MOM','OBV','RSI','ROC']
x_train_raw=data_train[feature].values
y_train_raw=data_train['close'].values
x_test_raw=data_test[feature].values
y_test_raw=data_test['close'].values
data_train=CS_300.iloc[:2334].copy()
data_test=CS_300.iloc[2334:].copy()
feature=['MA5_diff','MA20_diff','MA60_diff','MACD_diff','MOM_diff','OBV_diff','RSI_diff','ROC_diff']
x_train_diff=data_train[feature].values
y_train_diff=data_train['close_diff'].values
x_test_diff=data_test[feature].values
y_test_diff=data_test['close_diff'].values
data_train=CS_300.iloc[:2334].copy()
data_test=CS_300.iloc[2334:].copy()
feature=['MA5_mm','MA20_mm','MA60_mm','MACD_mm','MOM_mm','OBV_mm','RSI_mm','ROC_mm']
x_train_mm=data_train[feature].values
y_train_mm=data_train['close_mm'].values
x_test_mm=data_test[feature].values
y_test_mm=data_test['close_mm'].values
data_train=CS_300.iloc[:2334].copy()
data_test=CS_300.iloc[2334:].copy()
feature=['MA5_zs','MA20_zs','MA60_zs','MACD_zs','MOM_zs','OBV_zs','RSI_zs','ROC_zs']
x_train_zs=data_train[feature].values
y_train_zs=data_train['close_zs'].values
x_test_zs=data_test[feature].values
y_test_zs=data_test['close_zs'].values
定义LASSO函数,alpha设置为0.00001。
#定义LASSO回归函数
def LASSO_REG(x_train,y_train,x_test):
las_model=Lasso(alpha=0.00001)
las_model.fit(x_train,y_train)
testPredict_las=las_model.predict(x_test)
return pd.DataFrame(testPredict_las)
定义一个画图函数,用于比较测试数据与真实数据的走势。
def PLOT(label,y_test,testPredict):
font={'family':'Times New Roman'}
fig,ax=plt.subplots()
plt.plot(y_test,color='firebrick',label='real_test',linewidth=0.5)
plt.plot(testPredict,label=label,linewidth=0.5)
plt.yticks(fontproperties='Times New Roman', size=12)
plt.xticks(fontproperties='Times New Roman', size=12)
plt.legend(loc='upper right',prop=font,frameon=False)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.show()
定义一个误差函数,用于比较预测性能。使用的误差函数为MAPE,公式如下:
def ERROR(y_test_raw,y_test_diff,y_test_mm,y_test_zs,testPredict_raw,testPredict_diff,testPredict_mm,testPredict_zs):
df_error=pd.DataFrame()
df_error['y_test_raw']=pd.DataFrame(y_test_raw).iloc[:,0]
df_error['y_test_diff']=pd.DataFrame(y_test_diff).iloc[:,0]
df_error['y_test_mm']=pd.DataFrame(y_test_mm).iloc[:,0]
df_error['y_test_zs']=pd.DataFrame(y_test_zs).iloc[:,0]
df_error['testPredict_raw']=pd.DataFrame(testPredict_raw).iloc[:,0]
df_error['testPredict_diff']=pd.DataFrame(testPredict_diff).iloc[:,0]
df_error['testPredict_mm']=pd.DataFrame(testPredict_mm).iloc[:,0]
df_error['testPredict_zs']=pd.DataFrame(testPredict_zs).iloc[:,0]
error_raw=abs(df_error['testPredict_raw']-df_error['y_test_raw'])/df_error['y_test_raw']
error_diff=abs(df_error['testPredict_diff']-df_error['y_test_diff'])/df_error['y_test_diff']
error_mm=abs(df_error['testPredict_mm']-df_error['y_test_mm'])/df_error['y_test_mm']
error_zs=abs(df_error['testPredict_zs']-df_error['y_test_zs'])/df_error['y_test_zs']
print('基于原始数据,测试集的MAPE为{:.2f}%'.format(error_raw.mean()*100))
print('基于差分数据,测试集的MAPE为{:.2f}%'.format(error_diff.mean()*100))
print('基于min-max标准化数据,测试集的MAPE为{:.2f}%'.format(error_mm.mean()*100))
print('基于Z-score标准化数据,测试集的MAPE为{:.2f}%'.format(error_zs.mean()*100))
分别对原始数据、差分后的数据、min-max标准化后的数据、Z-Score标准化后的数据进行LASSO回归,并求解误差。
testPredict_las_raw=LASSO_REG(x_train_raw,y_train_raw,x_test_raw)
PLOT('lasso_raw',y_test_raw,testPredict_las_raw)
testPredict_las_diff=LASSO_REG(x_train_diff,y_train_diff,x_test_diff)
PLOT('lasso_diff',y_test_diff,testPredict_las_diff)
testPredict_las_mm=LASSO_REG(x_train_mm,y_train_mm,x_test_mm)
PLOT('lasso_mm',y_test_mm,testPredict_las_mm)
testPredict_las_zs=LASSO_REG(x_train_zs,y_train_zs,x_test_zs)
PLOT('lasso_zs',y_test_zs,testPredict_las_zs)
ERROR(y_test_raw,y_test_diff,y_test_mm,y_test_zs,testPredict_las_raw,testPredict_las_diff,testPredict_las_mm,testPredict_las_zs)
最后得到误差结果为:
基于原始数据,测试集的MAPE为0.72% 基于差分数据,测试集的MAPE为82.24% 基于min-max标准化数据,测试集的MAPE为1.30% 基于Z-score标准化数据,测试集的MAPE为3.48%
走势对比图为:
定义XGBoost函数,参数设置有进一步优化的空间。
#定义XGBoost回归函数
def XGB_REG(x_train,y_train,x_test):
xgb_model=xgb.XGBRegressor(learning_rate=0.01, max_depth=10, n_estimators=1000)
xgb_model.fit(x_train,y_train)
testPredict_xgb=xgb_model.predict(x_test)
return pd.DataFrame(testPredict_xgb)
重复上文类似LASSO的步骤。
testPredict_xgb_raw=XGB_REG(x_train_raw,y_train_raw,x_test_raw)
PLOT('xgb_raw',y_test_raw,testPredict_xgb_raw)
testPredict_xgb_diff=XGB_REG(x_train_diff,y_train_diff,x_test_diff)
PLOT('xgb_diff',y_test_diff,testPredict_xgb_diff)
testPredict_xgb_mm=XGB_REG(x_train_mm,y_train_mm,x_test_mm)
PLOT('xgb_mm',y_test_mm,testPredict_xgb_mm)
testPredict_xgb_zs=XGB_REG(x_train_zs,y_train_zs,x_test_zs)
PLOT('xgb_zs',y_test_zs,testPredict_xgb_zs)
ERROR(y_test_raw,y_test_diff,y_test_mm,y_test_zs,testPredict_xgb_raw,testPredict_xgb_diff,testPredict_xgb_mm,testPredict_xgb_zs)
最后得到的误差结果为:
基于原始数据,测试集的MAPE为1.48% 基于差分数据,测试集的MAPE为3.18% 基于min-max标准化数据,测试集的MAPE为3.18% 基于Z-score标准化数据,测试集的MAPE为6.41%
走势对比图为: