基于时间序列的回归问题(4)——时间序列预测的基本思路

前言:

大家好,这个系列之前以及写了几篇博客,都是对于时间序列回归预测的一些前期准备知识,相信很多人(包括笔者在内)第一次接触这种项目,可能大体的思路方案都不是很清楚,那么,这么博客将为大家梳理一下做基于时间序列数据回归预测问题的大体思路。


1、数据预处理

对于大多数基于数据挖掘的预测项目来说,得到的数据一般情况都会有噪声的,这时,就需要对数据进行预处理。
数据预处理包括对数据的清洗、数据规约等步骤。
数据清洗主要是对数据中的缺失值和异常值进行处理,对于时间序列的数据,可以看做是信号,相信大家都了解之前学习的信号与系统和数字信号处理,那时候我们经常用的就是傅里叶变换呀什么的,通过一定的滤波器从而实现信号的去噪,得到有用的信号,其实我们这里做的工作和那些类似,只不过对于实际生活中的一些数据,并不是完全满足周期性,如果我们再用傅里叶什么这时候就不能符合实际生活中的客观性,这时候便引入了前面讲的奇异普分析(SSA)经验模态分解,这两种方法的具体内容可参照前面的博客,这里就不多说了,经过这两种方法去噪后,可使我们得到更有利于未来预测的数据。
对于数据规约,这里一般需要对数据进行归一化处理,这里最常用的包括(0,1)标准化和Z-score标准化(这种方法给予原始数据的均值(mean)和标准差(standard deviation)进行数据的标准化)。

2、特征提取思路

对于之前了解分类问题的人们,大家都知道要对数据提取所需的特征,有时候也会对数据集直接进行预测,这时候不再构造新的特征,而是直接使用原有数据集中的特征,其实我们这里基于时间序列的预测与之前的思路还是一直的,比如可以采用要预测时间点的前一个月所有数据作为特征,或通过特种工程,统计出要预测时间点前所有数据的部分特征,比如前1,2,3,4,5,6…天的平均值,最大最小值等统计量等,可以看出基于时间序列的预测与之前的分类问题只是具体操作的手段不一致,下面针对不同情况将具体介绍几种基本思路:

2.1、单维单步

对于采用前n个点的数据预测下一个数据点的数据,这里为了方便大家理解,我们以前2的点预测下一个点的例子举例。
如我们基于时间序列为:1234567
那么我们的特征集为train_x和label(train_y)为:

train_x=[ [1,2][2,3][3,4][4,5][5,6]]
train_y=[3,4,5,6,7]

可以看出,用前两个数据预测下一个数据,比如用第一、第二个数据1和2作为特征,label为第三数据3。

2.2单维多部

由于我们在很多预测项目中,需要对未来一段时间进行预测,而不单单仅是预测未来一天的数值,所以这里就引入了单维多部的方法,这里以通过过去2个点的数据预测未来2个点的数据举例:
如我们基于时间序列为:1234567
那么我们的特征集为train_x和label(train_y)为:

train_x=[ [1,2][2,3][3,4][4,5]]
train_y=[[3,4],[4,5], [5,6],[6,7]]

2.3多维单步法

这种方法适用于同时对多组数据进行预测,且这两组数据彼此之间有一定联系,这里我们用两维数据,通过前三个点预测后一个点:
如我们基于时间序列为:
123456
11,12,13,14,15,16
那么我们的特征集为train_x和label(train_y)为:

train_x=[ [[1,11],[2,12],[3,13]],
          [[2,12],[3,13],[4,14]],
          [[3,13],[4,14],[5,15]]]
          
train_y=[[4,14],[5,15], [6,16]]

这里我们可看出,此时的特征集为3维(3, 3, 2)的数组,即3个sample,每个sample有3组feature,每组feature为2维数据。

2.4统计特征

之前的3种方法只是单纯建立在了对时间序列的预测,只是通过之前时间的数据来预测未来的数据,这种方法具有一定的局限性,这里可以引入其他的统计特征,比如引入会影响未来该数据值的其他特征,比如前n天的平均值、最大最小值等,这里也可以加入一些会影响未来数据但未在之前数据中体现出来的特征,比如应用在对股票价格的预测,不仅仅要对之前价格作为影响因素,同样要考虑当下的政策与具体情况,当然,这里只是举个例子,就不具体说了。

3程序实例

这里通过一个正弦和余弦函数的实例来简单说明一下:
首先拟定一个二维的数据对其进行实验 这个数据长度是1000条,一维是sin函数 另一维是cos函数使用前200步去预测后50步

data = np.zeros(2000)
data.dtype = 'float64'
data = data.reshape(1000,2)
sinx=np.arange(0,40*np.pi,2*np.pi/50,dtype='float64')
siny=np.sin(sinx)
cosx=np.arange(0,40*np.pi,2*np.pi/50,dtype='float64')
cosy=np.cos(sinx)

data[:,0] = siny
data[:,1] = cosy

print(data)
plt.plot(data[:,0])
plt.show()
plt.plot(data[:,1])
plt.show()

然后我们利用转换函数,将数据按照第二部分讲的方法转换为相应的特征和label集:

def create_dataset(data,n_predictions,n_next):
    '''
    对数据进行处理
    '''
    dim = data.shape[1]
    train_X, train_Y = [], []
    for i in range(data.shape[0]-n_predictions-n_next-1):
        a = data[i:(i+n_predictions),:]
        train_X.append(a)
        tempb = data[(i+n_predictions):(i+n_predictions+n_next),:]
        b = []
        for j in range(len(tempb)):
            for k in range(dim):
                b.append(tempb[j,k])
        train_Y.append(b)
    train_X = np.array(train_X,dtype='float64')
    train_Y = np.array(train_Y,dtype='float64')

    return train_X, train_Y
    
train_X,train_Y = create_dataset(data,200,50)

之后就是训练模型,由于本博客偏向于应用,就不再具体介绍回归模型了,这里就直接用神经网路Keras库中LSTM,如果想具体了解这个训练模型,可以关注本人博客,后续将持续更新,或自行百度。

def trainModel(train_X, train_Y):
    '''
    trainX,trainY: 训练LSTM模型所需要的数据
    '''
    model = Sequential()
    model.add(LSTM(
        140,
        input_shape=(train_X.shape[1], train_X.shape[2]),
        return_sequences=True))
    model.add(Dropout(0.3))

    model.add(LSTM(
        140,
        return_sequences=False))
    model.add(Dropout(0.3))

    model.add(Dense(
        train_Y.shape[1]))
    model.add(Activation("relu"))

    model.compile(loss='mse', optimizer='adam')
    model.fit(train_X, train_Y, epochs=100, batch_size=64, verbose=1)

    return model
model = trainModel(train_X,train_Y)

这个时候,模型已经训练好了,下面将对数据进行预测,我们预测时,同样构造一组正弦函数和一组余弦函数:

def reshape_y_hat(y_hat,dim):
    re_y = []
    i = 0
    while i < len(y_hat):
        tmp = []
        for j in range(dim):
            tmp.append(y_hat[i+j])
        i = i + dim
        re_y.append(tmp)
    re_y = np.array(re_y,dtype='float64')
    return  re_y


data = np.zeros(400)
data.dtype = 'float64'
data = data.reshape(200,2)
sinx=np.arange(0,8*np.pi,2*np.pi/50,dtype='float64')
siny=np.sin(sinx)
cosx=np.arange(0,8*np.pi,2*np.pi/50,dtype='float64')
cosy=np.cos(sinx)
data[:,0] = siny
data[:,1] = cosy

model = load_model("./MultiSteup2.h5")
test_X = data.reshape(1,data.shape[0],data.shape[1])
y_hat  =  model.predict(test_X)
#重组
y_hat = y_hat.reshape(y_hat.shape[1])
y_hat = reshape_y_hat(y_hat,2)

print(y_hat.shape)
plt.plot(y_hat[:,0])
plt.show()
plt.plot(y_hat[:,1])
plt.show()

这是就会画出预测后的效果了,当然,本篇博客只是想简单介绍一下大体思路,程序只是一个简单举例而已,如果想做具体项目,还要后续考虑更多的问题。

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

努力改掉拖延症的小白

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

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

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

打赏作者

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

抵扣说明:

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

余额充值