- 在线时间
- 514 小时
- 最后登录
- 2023-12-1
- 注册时间
- 2018-7-17
- 听众数
- 15
- 收听数
- 0
- 能力
- 0 分
- 体力
- 39393 点
- 威望
- 0 点
- 阅读权限
- 255
- 积分
- 12513
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1388
- 主题
- 1158
- 精华
- 0
- 分享
- 0
- 好友
- 15
TA的每日心情 | 开心 2023-7-31 10:17 |
---|
签到天数: 198 天 [LV.7]常住居民III
- 自我介绍
- 数学中国浅夏
|
使用LSTM预测时间序列数据
8 g, l" }8 G( Q+ Z4 g I8 b* M& T, k. F1 H
@; i* y9 [$ n% k- h% O; P& h文章目录
8 d% J4 d9 X3 M/ K l8 s背景
- x% e1 y5 U3 i* c结论4 h) z( ]" I. |. H3 Y: \8 i; b& b
代码 n( O. q4 @ F$ a. g/ |( L/ }
实验结果
5 w! h9 U+ t j6 V) ]RNN和DNN的区别) _1 I0 t" t; j# X$ c7 M v
RNN和LSTM的区别
! \" A1 M! l [. n背景
; J, x& V; C6 }复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验6 a6 Y* _8 n- |) l# [+ {2 i) x
熟悉用LSTM模型训练# O D: i5 P1 M: d# C0 \
验证将时序数据 转化为分类问题后,预测是否有效果# j' j% P3 ]. s) q) Q
对比SimpleRNN与LSTM模型 哪个效果最好?
$ A8 K/ q ?& k; v3 p! y验证LSTM相比于Dense()模型 是否有提升?
: I) O1 L8 _8 F' Y7 s( H/ t对比使用前3天的数据 和使用前1天的数据 哪个效果最好?# s/ B' \( n i6 V& ?; x7 c
结论
$ ~# v& @5 N2 v, |6 v& B* x$ z使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好
$ C4 w* p e4 d0 Y& I, K3 [使用LSTM的效果优于SimpleRNN# W a8 m* `3 f4 ]
代码/ ?# q) A' w, a# B. y
from pandas import read_csv; T! M8 D% i: [: n" R8 M. E
from datetime import datetime; _) f: p" ]- ~; r
import pandas as pd
0 i0 \. l- e8 g8 p! S/ N& zfrom pandas import DataFrame
% b5 b4 F8 z* \; o" O9 Cfrom sklearn.preprocessing import LabelEncoder,MinMaxScaler4 x+ @; m3 I; A+ b: A/ T: V
from sklearn.metrics import mean_squared_error0 a! p% P2 ?: l( L. |+ C
from keras.models import Sequential8 k6 p8 L- S0 H$ [0 S
from keras.layers import Dense, Dropout6 K( `4 A: Z) c
from keras.layers import LSTM% O7 U/ V9 v8 k# L! l
from keras.layers.recurrent import SimpleRNN
, F! Q' C; y$ r! C# {from numpy import concatenate
2 p8 R! o1 E: x! f% _; Bfrom math import sqrt" ~- H5 a$ [ [( R1 X- r& I! V& }
; m7 A& U4 m$ e
* i- v& v) K p- q, t( a/ K; V( E" O! ~8 L, Q; `( m& i! m
8 A% P! u; ]8 Q/ P* p6 O! O. D# load data
& j% y- F* e' |5 U; W/ W7 ]def parse(x):# O4 v0 X' T' `
return datetime.strptime(x, '%Y %m %d %H')
% D3 V7 ~; f* ?& P
% Y5 L0 s* W3 Z: Q9 }) j0 K: \def read_raw():5 L4 t2 n7 O0 G: x, e6 A! R
dataset = pd.read_csv('raw.csv', parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)
* N8 W- X# N1 ^" _9 ^$ M dataset.drop('No', axis=1, inplace=True)
. h8 G6 x' o; K; b8 n) Q # manually specify column names+ n9 ~+ Y, X; B7 G* L) W
dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']
3 |# v. U& P; G: A dataset.index.name = 'date'
6 g9 P* g" m% j # mark all NA values with 0( p) B. `8 Y3 \( o
dataset['pollution'].fillna(0, inplace=True)" W: }% ]* l+ \5 V! w6 `4 u
# drop the first 24 hours' B" \$ k( g0 G7 n: J
dataset = dataset[24:]
# S5 e% M; f' s8 Y" q # summarize first 5 rows
; t. d6 V* v6 y1 w6 k% G# u1 Q print(dataset.head(5))
! m" d' @6 Y! c" b8 C # save to file2 l6 u( \# D: q- A9 D7 p4 O
dataset.to_csv('pollution.csv')
+ `& W) |% C9 i( E( K& w9 }6 x) t/ {# ?7 f) ^5 l+ d* ?
! M: x' l0 V% z& Z* K1 ^3 S" j6 b5 n; f5 B$ c
o' X6 W$ j7 U' |6 ?2 e
# convert series to supervised learning
B+ l) V) E; c7 n0 ^' @* a: u2 Fdef series_to_supervised(data, n_in=1, n_out=1, dropnan=True):0 B! w+ L& s/ p: Q1 |1 M
n_vars = 1 if type(data) is list else data.shape[1]+ o) n, G. E* P) e, d$ E
df = DataFrame(data)" m6 o7 l6 {/ I; z
cols, names = list(), list()$ Q% G: V: X% ]/ L4 V
# input sequence (t-n, ... t-1)
8 j, O7 Z; T: z' Z+ m/ w2 k4 E for i in range(n_in, 0, -1): B( j- h% s+ S) z
cols.append(df.shift(i))# f9 W+ `; o' q- y1 d% d
names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
5 Q7 }' n0 u5 {: `# f # forecast sequence (t, t+1, ... t+n)
9 c7 l D6 E- p9 G7 x" c for i in range(0, n_out):
$ q3 y2 n7 g2 s5 F# j" l1 ?4 r cols.append(df.shift(-i))# Y! }. s4 R' O# B) u! A
if i == 0:6 m( P2 u4 o% }7 ?$ H# l
names += [('var%d(t)' % (j+1)) for j in range(n_vars)]6 s8 k( C* r( J# A. ^1 p6 z* \. O
else:
" r4 [$ ?: v" O. O- M% w/ a names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]$ F2 C! @0 T6 t0 [' w$ K
# put it all together9 B9 ]* t% W T% E- o
agg = pd.concat(cols, axis=1)
% U/ `6 R' r; @+ t7 q4 \ agg.columns = names7 G. }( U1 j3 j! j9 U9 o- o
# drop rows with NaN values6 t9 C( f3 R, G6 s& N6 Q
if dropnan:
. v% u6 y, n% N4 B# Y, L' n* y% r agg.dropna(inplace=True)
" N3 A4 E2 X3 f- M return agg
& O9 y7 d+ g$ k& R1 _7 K4 @
5 u) j3 e) Z1 g# c8 K# load dataset
. r" ^3 m. u$ K# Adataset = read_csv('pollution.csv', header=0, index_col=0)- w/ w3 s. k+ _5 z4 o0 p
values = dataset.values/ T7 L+ G V, Z) Q/ h, f9 p3 Y
& F) Z# J; `$ d: V+ N6 b6 R8 N- B% Q9 R( t) l) N4 U- Y
# integer encode direction+ b3 b2 T% e' o R- f) w# m
encoder = LabelEncoder()1 d) P# I$ w+ h- W. t8 G4 ^3 P
print(values[:,4])
" l q, S, A; C' f: W1 M! @values[:,4] = encoder.fit_transform(values[:,4])% e5 g9 F" {4 z. P* i) w
# ensure all data is float( M& N6 d$ q9 z3 `! i4 d/ ?6 v5 w3 o0 d
values = values.astype('float32')
3 D2 N7 H `# P! b3 z: Z0 A# normalize features9 {% L! u. y+ ]8 ?. c6 ^
scaler = MinMaxScaler(feature_range=(0, 1))
+ j( e& h2 k, [4 A! Lscaled = scaler.fit_transform(values)
9 Y" Y1 ~, g. M# frame as supervised learning
' k4 \ X) q/ O* creframed = series_to_supervised(scaled, 1, 1) ; t6 T. \' V% z. p" `
#reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据
6 T; h& ?$ y: v7 bprint("columns:", reframed.columns)
- J1 R7 n2 P( [" T$ N5 t# drop columns we don't want to predict
3 y& e" R$ d7 V# w! G% Wreframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据
7 W9 ]/ ?, |2 U$ X+ v: k$ m" y#reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据2 T( |0 X& u4 Z+ H0 K+ X$ D$ q; [1 T- A
print(reframed.head())
. T8 l) H$ H" d: Kprint("new columns:", reframed.columns)8 | m% n5 I' H) J# H
# split into train and test sets
/ `2 K4 R+ `0 Q9 \) N' T6 c" s. E/ gvalues = reframed.values* z2 t7 _ x2 ?
n_train_hours = 365 * 245 c: @& b; M" a$ x! o& l, Z
train = values[:n_train_hours, :]
+ ^! ]/ `* k& d2 a# ]test = values[n_train_hours:, :]
0 s' F+ [3 q7 ^# split into input and outputs6 T K: d3 ]2 C! P( O, |3 U2 {
train_X, train_y = train[:, :-1], train[:, -1]5 {4 x) e( L' h3 r9 e
test_X, test_y = test[:, :-1], test[:, -1]
0 K% N S' u1 P9 i! {# reshape input to be 3D [samples, timesteps, features]
/ o! \ @: \, @0 G: e#使用Dense()模型时不用变换; I1 F3 k' ~# k
train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))" t2 Y8 p9 s! c# h) c( V
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))8 H2 D% `2 s+ Z- a
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
; `5 w! K# l8 H- E# design network9 q$ N2 f" |0 J" }/ L
model = Sequential()' a. {2 N; q9 C. ?7 j. {
#model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))5 D+ P" ]: T* Q. g& l* C* \
#model.add(Dense(50, activation='relu', input_dim = 8))+ l0 b9 o" g7 n% C
model.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))6 T8 ^6 ?6 U1 G
model.add(Dense(1))- e! \, E! l: \( \8 ]
model.compile(loss='mae', optimizer='adam')0 R7 [ a- `1 r; r- f; m* h0 ]8 f% I
# fit network
% Y3 Q8 K! Z1 `; [: ihistory = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
5 ^ a8 [5 g3 o! e, T) d# make a prediction
* [. i" I6 R' B+ o. f0 ]yhat = model.predict(test_X): c. Z' q( V; N% u3 C3 M, }
print("yhat shape:", yhat.shape)
3 W$ \8 U* ?6 y0 X'''
% d9 r/ Q( Q* L7 N8 \, ?# P计算在测试集上的均方差) E. ?1 j, E! n( n- f9 Q8 S
test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
2 B; e7 @/ A7 `3 l1 C |! e$ iprint("test_X shape:", test_X.shape)
Y! n7 ]5 @- e5 ]5 p1 c \4 ]8 U% c
" |( ^7 g) C+ B3 q6 f# invert scaling for forecast+ I4 C B5 ]$ F. l( \
inv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)& J5 M: M% |$ C9 }% k$ b& A0 g
inv_yhat = scaler.inverse_transform(inv_yhat)+ I, c( c& ^. g* Y& E" W$ R
inv_yhat = inv_yhat[:,0]/ H2 z- d8 U) M7 h+ J; ?
# invert scaling for actual
9 r" A' N7 }! dtest_y = test_y.reshape((len(test_y), 1))
) ]4 D& C0 C% ainv_y = concatenate((test_y, test_X[:, 1:]), axis=1)
7 r: w: r1 N* g6 p" Oprint("inv_y:", inv_y[:10])9 n/ C' t$ p; ^7 A$ t4 R
print("inv_y shape:", inv_y.shape), d# z" |" T! z
- n, W& s- W6 Z- m
7 q6 H; V4 s) M
inv_y = scaler.inverse_transform(inv_y)3 \' g( V3 F6 Q6 Z* j, ]0 A$ y
print(inv_y, "*"*30)% w2 _4 l8 E: J. F" n$ j
6 h0 W5 Y) U4 e9 b' A1 ?
1 l+ o) ~4 m, U) y# r2 F. ~inv_y = inv_y[:,0]9 f' w6 Z/ r6 X5 r; Y
# calculate RMSE5 ~; h* Y1 T; |# n) n
rmse = sqrt(mean_squared_error(inv_y, inv_yhat)), ~' ]0 |- u7 ?& D3 Y% ~
print(inv_y[:100], inv_yhat[:100]), F0 ]) n8 `% E: G* h9 t3 h# z
print('Test RMSE: %.3f' % rmse): g- ]( c0 p; {4 I$ C3 G0 P# g
! @9 w0 o* s4 [4 I. K$ o i' Y( ?
- T: a/ E x/ E5 d( C% ]8 T# H5 n'''
5 ]6 o( s; N3 f2 t v% W实验结果3 e5 m( _" W; h! f. Z/ O
实验1:用前一天的天气数据,预测某一天的空气质量
' m+ z F/ C% w5 J使用LSTM模型
* i3 h7 B) Q7 v' ~% Y6 T# a1 L结果:$ Z! h; }- I- ?& V2 s9 F" g. n; r& V
Epoch 49/50
8 n/ N) W7 B/ d# ]0s - loss: 0.0144 - val_loss: 0.0133
4 \6 k) n) M R+ P* q- W+ VEpoch 50/50" |" n1 n1 J9 O
0s - loss: 0.0144 - val_loss: 0.0133
1 L( }' `* S7 \6 P2 n5 T, z! x$ [$ D. \
0 w1 ~/ [ z6 z) {) k
实验2:用前3天的天气数据,预测某一天的空气质量: q, j f2 T. j
使用LSTM模型! J z6 E. B, u/ x/ v# b
4 k9 H9 M) P. f! v4 @ w
* p0 H0 ~2 }4 t8 L! ?结果:3 p2 }/ E# c8 j! X/ t* v
Epoch 49/50
1 v! P3 y+ d( u% U8 T0s - loss: 0.0147 - val_loss: 0.0149
0 |2 P3 P l2 b" T( AEpoch 50/50* K; m' K' u2 w+ g3 J$ o
0s - loss: 0.0147 - val_loss: 0.0150
. f- K: I$ P. a% I5 }: ~, S' X7 F2 t. Q
# `" r7 F& f1 x3 T9 K实验3:用前一天的天气数据,预测某一天的空气质量
7 }6 ] J6 @; f+ S使用普通的全连接模型 Dense()4 B. Z2 ?& y9 r0 B
结果:1 p3 [3 j, D0 a& O2 S; h$ b- v
Epoch 49/50/ h/ G) p" v8 y! m1 v0 M
0s - loss: 0.0144 - val_loss: 0.0146
2 i' l. @8 f- z gEpoch 50/50( v4 V# Z3 z7 J; g2 W
0s - loss: 0.0148 - val_loss: 0.0151
5 [' D, H% L2 @" h! n" k5 o3 O7 q. B% w, U6 Q5 C
/ @' B0 {3 C& y
实验4:用前三天的天气数据,预测某一天的空气质量
- f. O# Z! c3 P3 M% s* |使用普通的全连接模型 Dense()
: Y. r9 |3 N& A. |* R% H结果:
5 Z( T. b! N3 oEpoch 49/50
6 O ]0 Q( c" V- E0s - loss: 0.0150 - val_loss: 0.0165' f( P( u7 L8 z7 ?
Epoch 50/50
1 v. g" h4 C6 X t0s - loss: 0.0148 - val_loss: 0.0141
; {. i) A/ C) F9 D" W) o! ^! d7 U+ L4 W' S" ]+ ^8 @. e6 P' ]% a" @
5 e+ ~" X* t: H$ f% y0 l+ Y
实验5:用前一天的天气数据,预测某一天的空气质量# _" |: q: X; X; ~, E j
使用SimpleRNN8 H/ N8 g+ U5 E6 K/ }
Epoch 49/50
! ^# C0 E! T( E2 h0s - loss: 0.0160 - val_loss: 0.0140) h, v! ^$ F# E6 j' o" X1 w
Epoch 50/503 |! o* m8 @0 Z
0s - loss: 0.0147 - val_loss: 0.0150
; b! u. I( G5 Z: r8 x. B* b9 p6 u- O8 g' I D
1 ?8 R" n, q4 G6 V3 f' c实验6:用前三天的天气数据,预测某一天的空气质量; J! R9 B# G/ R3 L
使用SimpleRNN6 a2 f! y! M& E, S4 t4 b6 O
Epoch 49/50
: {7 @: ^5 s& Z# @0s - loss: 0.0164 - val_loss: 0.0233
2 [, z. O, q- O0 |Epoch 50/50
) y" g$ @0 k; _4 b) g0s - loss: 0.0166 - val_loss: 0.02276 r% W& ^! o6 c+ K1 `6 h/ U
RNN和DNN的区别RNN中的循环是指一个序列当前的输出与前面的输出也有关系。也就是说,网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐层之间的节点不再是无连接的而是有连接的,并且隐层的输入不仅包括输入层的输出还包括上一时刻隐层的输出。 7 X* e8 z7 Q& D6 w2 W2 P9 d9 H
0 Z0 P: C) h% w
8 E5 p7 u. E9 z7 a8 IRNN和LSTM的区别
; C8 V- v3 k( D5 XLSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。+ p+ ~8 Q& i& o; Q- k
* _8 k! a- u: i$ g$ ] s' k; t* L9 a/ B# M
但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。
5 ^# F. H1 {$ }5 O4 a9 Y$ E9 H7 s2 O9 \, B' u, `- r3 Q5 Q
5 w( {$ n$ r- w, E: z9 V
请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员
# r+ P& Q& t0 c! N. Y5 i" W! F6 c+ Y
. b1 H0 e& y4 {" {1 F5 W! A
|
zan
|