Pytorch學(xué)習(xí)之LSTM預(yù)測(cè)航班

LSTM長(zhǎng)短時(shí)神經(jīng)網(wǎng)絡(luò)預(yù)測(cè)航班序列

本文通過LSTM長(zhǎng)短時(shí)記憶神經(jīng)網(wǎng)絡(luò),來預(yù)測(cè)航班信息。

航班數(shù)據(jù)集來自https://github.com/mwaskom/seaborn-data的flights.csv

本文討論最多的問題:
1、本數(shù)據(jù)集分割存在數(shù)據(jù)泄漏。代碼取data_X, data_Y = create_dataset(dataset),根據(jù)設(shè)定的lookback可以獲得數(shù)據(jù)量為len(dataset)-lookback。然后代碼中對(duì)data_X和data_Y取70%做訓(xùn)練;確實(shí)代碼偽裝的很好,在于數(shù)據(jù)集的分割問題;在測(cè)試集中,[t1,t2]=>t3中,t1和t2是被泄露的。因?yàn)楝F(xiàn)實(shí)情況的t1和t2也需要模型進(jìn)行預(yù)測(cè);所以繪圖的效果會(huì)很好;

2、關(guān)于input_size和seq_len的問題,您說的是對(duì)的;本文的特征數(shù)為1,即當(dāng)月的航班預(yù)訂人數(shù);seq_len為2,是用了2天的數(shù)據(jù)。即特征數(shù)(input_size)為1,seq_len為2。

3、模型預(yù)測(cè)效果存在一小段的偏移,這是由lookback決定的;這個(gè)問題也是時(shí)間序列問題的痛點(diǎn);

庫(kù)導(dǎo)入

導(dǎo)入pytorch庫(kù)函數(shù)和散點(diǎn)圖庫(kù)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

導(dǎo)入數(shù)據(jù)并可視化

將航班數(shù)據(jù)導(dǎo)入,注意usecols=[1],選擇第2列數(shù)據(jù)。

data_csv = pd.read_csv('./data.csv',usecols=[1])
plt.plot(data_csv)
初始數(shù)據(jù)

數(shù)據(jù)預(yù)處理

數(shù)據(jù)預(yù)處理,將數(shù)據(jù)中null或者缺項(xiàng)的列刪除。對(duì)數(shù)據(jù)集進(jìn)行歸一化處理,首先設(shè)置數(shù)據(jù)集為浮點(diǎn)類型,然后取數(shù)據(jù)集最大和最小項(xiàng)差值為放縮尺度,對(duì)每一個(gè)數(shù)據(jù)集數(shù)值進(jìn)行歸一化。

# 數(shù)據(jù)預(yù)處理
data_csv = data_csv.dropna()  # 濾除缺失數(shù)據(jù)
dataset = data_csv.values   # 獲得csv的值
dataset = dataset.astype('float32')
max_value = np.max(dataset)  # 獲得最大值
min_value = np.min(dataset)  # 獲得最小值
scalar = max_value - min_value  # 獲得間隔數(shù)量
dataset = list(map(lambda x: x / scalar, dataset)) # 歸一化

設(shè)置數(shù)據(jù)集

設(shè)置X,Y數(shù)據(jù)集。以look_back=2為準(zhǔn),取第一個(gè)和第二個(gè)為數(shù)組,形成data_X,取第三個(gè)作為預(yù)測(cè)值,形成data_Y,完成訓(xùn)練集的提取。

def create_dataset(dataset, look_back=2):
    dataX, dataY = [], []
    for i in range(len(dataset) - look_back):
        a = dataset[i:(i + look_back)]
        dataX.append(a)
        dataY.append(dataset[i + look_back])
    return np.array(dataX), np.array(dataY)

# 創(chuàng)建好輸入輸出
data_X, data_Y = create_dataset(dataset)

設(shè)置訓(xùn)練集和測(cè)試集

取數(shù)據(jù)集的前70%作為訓(xùn)練集,后30%做為測(cè)試集。

# 劃分訓(xùn)練集和測(cè)試集,70% 作為訓(xùn)練集
train_size = int(len(data_X) * 0.7)
test_size = len(data_X) - train_size
train_X = data_X[:train_size]
train_Y = data_Y[:train_size]
test_X = data_X[train_size:]
test_Y = data_Y[train_size:]

設(shè)置LSTM模型數(shù)據(jù)類型形狀

設(shè)置LSTM能識(shí)別的數(shù)據(jù)類型,形成tran_X的一維兩個(gè)參數(shù)的數(shù)組,train_Y的一維一個(gè)參數(shù)的數(shù)組。并轉(zhuǎn)化為tensor類型

import torch

train_X = train_X.reshape(-1, 1, 2)
train_Y = train_Y.reshape(-1, 1, 1)
test_X = test_X.reshape(-1, 1, 2)

train_x = torch.from_numpy(train_X)
train_y = torch.from_numpy(train_Y)
test_x = torch.from_numpy(test_X)

建立LSTM模型

建立LSTM模型,第一層為L(zhǎng)STM神經(jīng)網(wǎng)絡(luò),第二層為一個(gè)全連接層。

from torch import nn
from torch.autograd import Variable

class lstm(nn.Module):
    def __init__(self,input_size=2,hidden_size=4,output_size=1,num_layer=2):
        super(lstm,self).__init__()
        self.layer1 = nn.LSTM(input_size,hidden_size,num_layer)
        self.layer2 = nn.Linear(hidden_size,output_size)
    
    def forward(self,x):
        x,_ = self.layer1(x)
        s,b,h = x.size()
        x = x.view(s*b,h)
        x = self.layer2(x)
        x = x.view(s,b,-1)
        return x

model = lstm(2, 4,1,2)

建立損失函數(shù)和優(yōu)化器

設(shè)置交叉熵?fù)p失函數(shù)和自適應(yīng)梯度下降算法

criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-2)

模型訓(xùn)練

# 開始訓(xùn)練
for e in range(1000):
    var_x = Variable(train_x)
    var_y = Variable(train_y)
    # 前向傳播
    out = model(var_x)
    loss = criterion(out, var_y)
    # 反向傳播
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
    if (e + 1) % 100 == 0: # 每 100 次輸出結(jié)果
        print('Epoch: {}, Loss: {:.5f}'.format(e + 1, loss.data[0]))
訓(xùn)練結(jié)果
Epoch: 100, Loss: 0.00785
Epoch: 200, Loss: 0.00641
Epoch: 300, Loss: 0.00518
Epoch: 400, Loss: 0.00356
Epoch: 500, Loss: 0.00248
Epoch: 600, Loss: 0.00429
Epoch: 700, Loss: 0.00226
Epoch: 800, Loss: 0.00231
Epoch: 900, Loss: 0.00210
Epoch: 1000, Loss: 0.00213

模型預(yù)測(cè)

model = model.eval() # 轉(zhuǎn)換成測(cè)試模式

data_X = data_X.reshape(-1, 1, 2)
data_X = torch.from_numpy(data_X)
var_data = Variable(data_X)
pred_test = model(var_data) # 測(cè)試集的預(yù)測(cè)結(jié)果
# 改變輸出的格式
pred_test = pred_test.view(-1).data.numpy()

預(yù)測(cè)序列可視化

# 畫出實(shí)際結(jié)果和預(yù)測(cè)的結(jié)果
plt.plot(pred_test, 'r', label='prediction')
plt.plot(dataset, 'b', label='real')
plt.legend(loc='best')
結(jié)果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、實(shí)驗(yàn)?zāi)康?學(xué)習(xí)使用 weka 中的常用分類器,完成數(shù)據(jù)分類任務(wù)。 二、實(shí)驗(yàn)內(nèi)容 了解 weka 中 explo...
    yigoh閱讀 8,834評(píng)論 5 4
  • 語(yǔ)言的正則化LSTM用于情感分類 Linguistically Regularized LSTM for Sent...
    __子不語(yǔ)__閱讀 2,096評(píng)論 0 2
  • 今天偶然聽到“鬼”這個(gè)字眼,突發(fā)奇想便想寫下這么篇東西,沒什么目的,說純粹的,不過是想說點(diǎn)什么,為消遣而已。 一寫...
    小老鼠嘎閱讀 613評(píng)論 8 6
  • 夜半,醒來 聽到的只是寂靜 會(huì)忘卻寒暑 也忘卻一切喧囂 輕輕地吟唱 ...
    海月先生閱讀 443評(píng)論 9 4
  • 今年夏天,我在長(zhǎng)春學(xué)習(xí)有一幕讓我難忘!一個(gè)年輕的媽媽帶著4歲小女兒在公園游玩,媽媽坐在樹底下看書,小女孩...
    善水100閱讀 554評(píng)論 0 1

友情鏈接更多精彩內(nèi)容