中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中如何使用LSTM模型進行時間序列預測分析

發布時間:2021-07-01 11:19:25 來源:億速云 閱讀:2530 作者:小新 欄目:開發技術

這篇文章主要為大家展示了“Python中如何使用LSTM模型進行時間序列預測分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Python中如何使用LSTM模型進行時間序列預測分析”這篇文章吧。

時間序列模型

時間序列預測分析就是利用過去一段時間內某事件時間的特征來預測未來一段時間內該事件的特征。這是一類相對比較復雜的預測建模問題,和回歸分析模型的預測不同,時間序列模型是依賴于事件發生的先后順序的,同樣大小的值改變順序后輸入模型產生的結果是不同的。
舉個栗子:根據過去兩年某股票的每天的股價數據推測之后一周的股價變化;根據過去2年某店鋪每周想消費人數預測下周來店消費的人數等等

RNN 和 LSTM 模型

時間序列模型最常用最強大的的工具就是遞歸神經網絡(recurrent neural network, RNN)。相比與普通神經網絡的各計算結果之間相互獨立的特點,RNN的每一次隱含層的計算結果都與當前輸入以及上一次的隱含層結果相關。通過這種方法,RNN的計算結果便具備了記憶之前幾次結果的特點。

典型的RNN網路結構如下:

Python中如何使用LSTM模型進行時間序列預測分析

右側為計算時便于理解記憶而產開的結構。簡單說,x為輸入層,o為輸出層,s為隱含層,而t指第幾次的計算;V,W,U為權重,其中計算第t次的隱含層狀態時為St = f(U*Xt + W*St-1),實現當前輸入結果與之前的計算掛鉤的目的。對RNN想要更深入的了解可以戳這里。

RNN的局限:
由于RNN模型如果需要實現長期記憶的話需要將當前的隱含態的計算與前n次的計算掛鉤,即St = f(U*Xt + W1*St-1 + W2*St-2 + ... + Wn*St-n),那樣的話計算量會呈指數式增長,導致模型訓練的時間大幅增加,因此RNN模型一般直接用來進行長期記憶計算。

LSTM模型
LSTM(Long Short-Term Memory)模型是一種RNN的變型,最早由Juergen Schmidhuber提出的。經典的LSTM模型結構如下:

Python中如何使用LSTM模型進行時間序列預測分析

LSTM的特點就是在RNN結構以外添加了各層的閥門節點。閥門有3類:遺忘閥門(forget gate),輸入閥門(input gate)和輸出閥門(output gate)。這些閥門可以打開或關閉,用于將判斷模型網絡的記憶態(之前網絡的狀態)在該層輸出的結果是否達到閾值從而加入到當前該層的計算中。如圖中所示,閥門節點利用sigmoid函數將網絡的記憶態作為輸入計算;如果輸出結果達到閾值則將該閥門輸出與當前層的的計算結果相乘作為下一層的輸入(PS:這里的相乘是在指矩陣中的逐元素相乘);如果沒有達到閾值則將該輸出結果遺忘掉。每一層包括閥門節點的權重都會在每一次模型反向傳播訓練過程中更新。更具體的LSTM的判斷計算過程如下圖所示:

Python中如何使用LSTM模型進行時間序列預測分析

LSTM模型的記憶功能就是由這些閥門節點實現的。當閥門打開的時候,前面模型的訓練結果就會關聯到當前的模型計算,而當閥門關閉的時候之前的計算結果就不再影響當前的計算。因此,通過調節閥門的開關我們就可以實現早期序列對最終結果的影響。而當你不不希望之前結果對之后產生影響,比如自然語言處理中的開始分析新段落或新章節,那么把閥門關掉即可。(對LSTM想要更具體的了解可以戳這里)

下圖具體演示了閥門是如何工作的:通過閥門控制使序列第1的輸入的變量影響到了序列第4,6的的變量計算結果。

Python中如何使用LSTM模型進行時間序列預測分析

黑色實心圓代表對該節點的計算結果輸出到下一層或下一次計算;空心圓則表示該節點的計算結果沒有輸入到網絡或者沒有從上一次收到信號。

Python中實現LSTM模型搭建

Python中有不少包可以直接調用來構建LSTM模型,比如pybrain, kears, tensorflow, cikit-neuralnetwork等(更多戳這里)。這里我們選用keras。(PS:如果操作系統用的linux或者mac,強推Tensorflow!!!)

因為LSTM神經網絡模型的訓練可以通過調整很多參數來優化,例如activation函數,LSTM層數,輸入輸出的變量維度等,調節過程相當復雜。這里只舉一個最簡單的應用例子來描述LSTM的搭建過程。

應用實例

基于某家店的某顧客的歷史消費的時間推測該顧客前下次來店的時間。具體數據如下所示:

消費時間
2015-05-15 14:03:51
2015-05-15 15:32:46
2015-06-28 18:00:17
2015-07-16 21:27:18
2015-07-16 22:04:51
2015-09-08 14:59:56
..
..

具體操作:

1. 原始數據轉化

首先需要將時間點數據進行數值化。將具體時間轉化為時間段用于表示該用戶相鄰兩次消費的時間間隔,然后再導入模型進行訓練是比較常用的手段。轉化后的數據如下:

消費間隔
0
44
18
0
54
..
..

2.生成模型訓練數據集(確定訓練集的窗口長度)

這里的窗口指需要幾次消費間隔用來預測下一次的消費間隔。這里我們先采用窗口長度為3, 即用t-2, t-1,t次的消費間隔進行模型訓練,然后用t+1次間隔對結果進行驗證。數據集格式如下:X為訓練數據,Y為驗證數據。
PS: 這里說確定也不太合適,因為窗口長度需要根據模型驗證結果進行調整的。

X1  X2  X3  Y
0  44  18  0
44  18  0  54
..
..

注:直接這樣預測一般精度會比較差,可以把預測值Y根據數值bin到幾類,然后用轉換成one-hot標簽再來訓練會比較好。比如如果把Y按數值范圍分到五類(1:0-20,2:20-40,3:40-60,4:60-80,5:80-100)上式可化為:

X1  X2  X3  Y
0  44  18  0
44  18  0  4
...

Y轉化成one-hot以后則是(關于one-hot編碼可以參考這里)

1  0  0  0  0
0  0  0  0  1
...

3. 網絡模型結構的確定和調整

這里我們使用python的keras庫。(用java的同學可以參考下deeplearning4j這個庫)。網絡的訓練過程設計到許多參數的調整:比如

需要確定LSTM模塊的激活函數(activation fucntion)(keras中默認的是tanh);

確定接收LSTM輸出的完全連接人工神經網絡(fully-connected artificial neural network)的激活函數(keras中默認為linear);

確定每一層網絡節點的舍棄率(為了防止過度擬合(overfit)),這里我們默認值設定為0.2;

確定誤差的計算方式,這里我們使用均方誤差(mean squared error);

確定權重參數的迭代更新方式,這里我們采用RMSprop算法,通常用于RNN網絡。確定模型訓練的epoch和batch size(關于模型的這兩個參數具體解釋戳這里)

一般來說LSTM模塊的層數越多(一般不超過3層,再多訓練的時候就比較難收斂),對高級別的時間表示的學習能力越強;同時,最后會加一層普通的神經網路層用于輸出結果的降維。典型結構如下:

Python中如何使用LSTM模型進行時間序列預測分析

如果需要將多個序列進行同一個模型的訓練,可以將序列分別輸入到獨立的LSTM模塊然后輸出結果合并后輸入到普通層。結構如下:

Python中如何使用LSTM模型進行時間序列預測分析

4. 模型訓練和結果預測

將上述數據集按4:1的比例隨機拆分為訓練集和驗證集,這是為了防止過度擬合。訓練模型。然后將數據的X列作為參數導入模型便可得到預測值,與實際的Y值相比便可得到該模型的優劣。

實現代碼

時間間隔序列格式化成所需的訓練集格式

import pandas as pd
import numpy as np

def create_interval_dataset(dataset, look_back):
  """
  :param dataset: input array of time intervals
  :param look_back: each training set feature length
  :return: convert an array of values into a dataset matrix.
  """
  dataX, dataY = [], []
  for i in range(len(dataset) - look_back):
    dataX.append(dataset[i:i+look_back])
    dataY.append(dataset[i+look_back])
  return np.asarray(dataX), np.asarray(dataY)

df = pd.read_csv("path-to-your-time-interval-file")  
dataset_init = np.asarray(df)  # if only 1 column
dataX, dataY = create_interval_dataset(dataset, lookback=3)  # look back if the training set sequence length

這里的輸入數據來源是csv文件,如果輸入數據是來自數據庫的話可以參考這里

LSTM網絡結構搭建

import pandas as pd
import numpy as np
import random
from keras.models import Sequential, model_from_json
from keras.layers import Dense, LSTM, Dropout

class NeuralNetwork():
  def __init__(self, **kwargs):
    """
    :param **kwargs: output_dim=4: output dimension of LSTM layer; activation_lstm='tanh': activation function for LSTM layers; activation_dense='relu': activation function for Dense layer; activation_last='sigmoid': activation function for last layer; drop_out=0.2: fraction of input units to drop; np_epoch=10, the number of epoches to train the model. epoch is one forward pass and one backward pass of all the training examples; batch_size=32: number of samples per gradient update. The higher the batch size, the more memory space you'll need; loss='mean_square_error': loss function; optimizer='rmsprop'
    """
    self.output_dim = kwargs.get('output_dim', 8)
    self.activation_lstm = kwargs.get('activation_lstm', 'relu')
    self.activation_dense = kwargs.get('activation_dense', 'relu')
    self.activation_last = kwargs.get('activation_last', 'softmax')  # softmax for multiple output
    self.dense_layer = kwargs.get('dense_layer', 2)   # at least 2 layers
    self.lstm_layer = kwargs.get('lstm_layer', 2)
    self.drop_out = kwargs.get('drop_out', 0.2)
    self.nb_epoch = kwargs.get('nb_epoch', 10)
    self.batch_size = kwargs.get('batch_size', 100)
    self.loss = kwargs.get('loss', 'categorical_crossentropy')
    self.optimizer = kwargs.get('optimizer', 'rmsprop')

    def NN_model(self, trainX, trainY, testX, testY):
    """
    :param trainX: training data set
    :param trainY: expect value of training data
    :param testX: test data set
    :param testY: epect value of test data
    :return: model after training
    """
    print "Training model is LSTM network!"
    input_dim = trainX[1].shape[1]
    output_dim = trainY.shape[1] # one-hot label
    # print predefined parameters of current model:
    model = Sequential()
    # applying a LSTM layer with x dim output and y dim input. Use dropout parameter to avoid overfitting
    model.add(LSTM(output_dim=self.output_dim,
            input_dim=input_dim,
            activation=self.activation_lstm,
            dropout_U=self.drop_out,
            return_sequences=True))
    for i in range(self.lstm_layer-2):
      model.add(LSTM(output_dim=self.output_dim,
            input_dim=self.output_dim,
            activation=self.activation_lstm,
            dropout_U=self.drop_out,
            return_sequences=True))
    # argument return_sequences should be false in last lstm layer to avoid input dimension incompatibility with dense layer
    model.add(LSTM(output_dim=self.output_dim,
            input_dim=self.output_dim,
            activation=self.activation_lstm,
            dropout_U=self.drop_out))
    for i in range(self.dense_layer-1):
      model.add(Dense(output_dim=self.output_dim,
            activation=self.activation_last))
    model.add(Dense(output_dim=output_dim,
            input_dim=self.output_dim,
            activation=self.activation_last))
    # configure the learning process
    model.compile(loss=self.loss, optimizer=self.optimizer, metrics=['accuracy'])
    # train the model with fixed number of epoches
    model.fit(x=trainX, y=trainY, nb_epoch=self.nb_epoch, batch_size=self.batch_size, validation_data=(testX, testY))
    # store model to json file
    model_json = model.to_json()
    with open(model_path, "w") as json_file:
      json_file.write(model_json)
    # store model weights to hdf5 file
    if model_weight_path:
      if os.path.exists(model_weight_path):
        os.remove(model_weight_path)
      model.save_weights(model_weight_path) # eg: model_weight.h6
    return model

這里寫的只涉及LSTM網絡的結構搭建,至于如何把數據處理規范化成網絡所需的結構以及把模型預測結果與實際值比較統計的可視化,就需要根據實際情況做調整了。

以上是“Python中如何使用LSTM模型進行時間序列預測分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

甘洛县| 澄城县| 武胜县| 蛟河市| 赣榆县| 兰西县| 同仁县| 罗甸县| 永城市| 邯郸市| 蒙山县| 桐庐县| 澄迈县| 松潘县| 浑源县| 贺州市| 吴旗县| 鄂伦春自治旗| 南投县| 揭西县| 和政县| 大丰市| 休宁县| 岳西县| 乐亭县| 临安市| 定州市| 博乐市| 澳门| 景东| 平遥县| 图木舒克市| 怀来县| 洛隆县| 长垣县| 福建省| 达日县| 淳安县| 门头沟区| 尖扎县| 柘城县|