不同数据处理方式对机器学习模型误差的作用——以LASSO、XGBoost为例

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标准化后的数据,公式为:

x^{*}=\frac{x-min(X)}{max(X)-min(X)}

_zs代表Z-Score标准化后的数据,公式为:

x^*=\frac{x-\bar{X}}{\sigma }

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,公式如下:

MAPE=\frac{100%}{n}\sum_{i=1}^{n}\left | \frac{y_i-\hat{y_i}}{y_i} \right |

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%

走势对比图为:

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

etetbt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值