- 在线时间
- 514 小时
- 最后登录
- 2023-12-1
- 注册时间
- 2018-7-17
- 听众数
- 15
- 收听数
- 0
- 能力
- 0 分
- 体力
- 40255 点
- 威望
- 0 点
- 阅读权限
- 255
- 积分
- 12788
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1419
- 主题
- 1178
- 精华
- 0
- 分享
- 0
- 好友
- 15
TA的每日心情 | 开心 2023-7-31 10:17 |
|---|
签到天数: 198 天 [LV.7]常住居民III
- 自我介绍
- 数学中国浅夏
 |
使用LSTM预测时间序列数据
/ T: | d, G) `9 H# a
, K) Z# U8 k; Q2 S; p* S+ M- ?9 k0 ~$ q, G8 s
文章目录2 N- `* T2 A7 s5 x0 X2 M
背景! y! Q8 C3 H: Q% h; [$ W. f0 \3 G
结论# I. n: m9 H9 A/ D* W
代码% a, e0 f+ b1 W5 }. ?
实验结果/ W; Z8 w7 q3 n& ?6 G
RNN和DNN的区别
$ ^# S0 T w. d) x# {7 z2 t$ d: d, KRNN和LSTM的区别
0 A2 q3 ^$ f% `& f9 {: X! J背景
4 }2 F; E4 f- d9 h复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验
, H, H$ E C+ w+ s( M! Q# ?熟悉用LSTM模型训练3 h+ D# w! t$ O6 n
验证将时序数据 转化为分类问题后,预测是否有效果
' B$ g; {. q3 @0 v6 g对比SimpleRNN与LSTM模型 哪个效果最好?) k7 c; Z) I+ ]7 D. p: A
验证LSTM相比于Dense()模型 是否有提升?# a" m' f; ]% w$ @; O1 X* b
对比使用前3天的数据 和使用前1天的数据 哪个效果最好?( y& f& ?+ B! I# y
结论7 e9 V, u# ?# q/ i
使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好$ `! a5 ^8 u5 t! O) u
使用LSTM的效果优于SimpleRNN; q5 D" X( Y, E6 T
代码
; a2 o$ f# q' [3 Nfrom pandas import read_csv
0 H- V2 @- W" q3 l( G# b$ Tfrom datetime import datetime
$ R8 [6 k/ r: V+ B2 H, Z i5 Pimport pandas as pd W* |+ x8 f+ ^8 h
from pandas import DataFrame
q- I% z/ j# B+ O) c7 Kfrom sklearn.preprocessing import LabelEncoder,MinMaxScaler
7 I! s# N' T: h8 d5 g1 {5 \, sfrom sklearn.metrics import mean_squared_error
1 f" x/ q ^6 k: Nfrom keras.models import Sequential
, O0 U( Z. L0 q: u' @) |9 l) Pfrom keras.layers import Dense, Dropout
8 `! {8 P' r0 s$ _8 nfrom keras.layers import LSTM: `" t$ c. f1 `3 D. e T
from keras.layers.recurrent import SimpleRNN) U$ j+ b4 E( N0 m; V( Z
from numpy import concatenate' _" n. @8 H* C, [
from math import sqrt8 w4 @; y( M7 F' o/ D
6 C3 J# l8 ~$ n* F) ?2 w
# j0 L6 B* `3 m [# O0 d' _, `1 R( V; {
: v- v1 [: Z8 Z
# load data' ~6 o5 U6 R3 ]0 M
def parse(x):
# E5 F! U2 l$ C/ g1 s* G8 ~ return datetime.strptime(x, '%Y %m %d %H')' ] F. L3 [7 J" L& r v8 I5 S* M, H
- n, Z v+ ?7 G) V* D& O
def read_raw():
5 L5 A7 |$ n5 M% d! ?; r dataset = pd.read_csv('raw.csv', parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse), d2 Q2 s! U3 T/ A6 l
dataset.drop('No', axis=1, inplace=True)
@" ~9 ?& P: B5 ~. v # manually specify column names4 @0 v( j- U; z2 e a% f' r' |
dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']
( {2 f( o6 ?' g3 j3 K. _ dataset.index.name = 'date'9 ^' a S" H3 h9 r
# mark all NA values with 03 W8 x; f, N/ U# ^6 U( L
dataset['pollution'].fillna(0, inplace=True)& W5 G7 n; L; K1 l
# drop the first 24 hours
# M* N* t% R$ s) y A1 U; q dataset = dataset[24:]$ H' u7 D! [' b3 ~0 t' Z, }& v1 {
# summarize first 5 rows& Y0 o. {! W' a
print(dataset.head(5))
8 v6 Q. v! i! L9 ` # save to file: O/ M/ X1 \8 M5 k6 ]) q4 I# Q
dataset.to_csv('pollution.csv')2 Y4 v6 r9 }/ K [0 p
& A6 p0 c) Q2 F# ]/ u
M( s# l( X9 x3 G2 R' i
0 n6 h f8 B& N1 U) R
( i, r$ Q* ?/ f4 F7 \/ O( t3 q# convert series to supervised learning
. w: R! Y; I' d8 X4 h' p) xdef series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
* G) u' | @, e8 {4 n( s, f7 d1 J n_vars = 1 if type(data) is list else data.shape[1]* Y7 T: t; K% o( G6 |2 h% J& n
df = DataFrame(data)
2 r" l4 ~ q4 Q( X; s cols, names = list(), list()( b, E8 \& ^6 j9 Q: e
# input sequence (t-n, ... t-1)6 D* E4 Z: t: F. r
for i in range(n_in, 0, -1):
* r5 }. _$ O& j' B3 o cols.append(df.shift(i))( X% v1 x! v% T
names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
3 }5 e, _+ P0 s% p # forecast sequence (t, t+1, ... t+n)6 C3 [3 `9 K. T: k1 R4 O/ A2 q
for i in range(0, n_out):; F" O( f8 y0 ]! N0 e
cols.append(df.shift(-i))
3 H$ q! u, f) o9 W0 O# a) b if i == 0:
- d9 c, m+ @# D: m7 u" {: [8 y names += [('var%d(t)' % (j+1)) for j in range(n_vars)]9 N, |2 O4 R8 i9 y8 I
else:
- r# D. { j, C( ]( v4 @ names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
8 j) w; x% Z2 a8 h" j2 E' }$ ` # put it all together; v; w3 g7 v/ N
agg = pd.concat(cols, axis=1)
5 U+ [4 F' u& X% W4 e3 L, ` agg.columns = names
* u: c5 |* L) V: C # drop rows with NaN values: `1 J/ e6 u+ Y& k" A
if dropnan:2 w; Q- e, b2 L8 D# f& B
agg.dropna(inplace=True)
8 z1 T7 l& {( | B return agg/ a( h6 z# e- L8 ^' z, j; g
/ s, ?7 N a N. e
# load dataset7 c" {* R: p- H9 r
dataset = read_csv('pollution.csv', header=0, index_col=0). S- H' Y# C H' f% p
values = dataset.values
" W; ~& d/ h& ^7 P% ^
3 n8 P" e3 A! O" e6 \: L, l4 J2 c5 }) y, `, m) X& X$ m
# integer encode direction
8 d/ a2 h# `- y+ x. H: d4 M+ h) Hencoder = LabelEncoder()* Z/ k6 z1 l y9 W: P& [& s
print(values[:,4])
/ i9 @9 Y, F: [/ o8 Wvalues[:,4] = encoder.fit_transform(values[:,4])
1 u+ n9 F( Y8 f: M2 j( I1 v# ensure all data is float
5 W3 D$ Q% k6 Vvalues = values.astype('float32')
8 h: t1 f1 [ g0 ]3 ?% B$ b# normalize features
; E7 W! o, ~, S4 Z2 ^scaler = MinMaxScaler(feature_range=(0, 1))
2 X' ~& ]6 {/ C0 Rscaled = scaler.fit_transform(values)9 y* q2 ^* k: G- o y4 C9 C
# frame as supervised learning2 f5 W. P l& G- {. z' i
reframed = series_to_supervised(scaled, 1, 1) * r) N* S% c* \; ]- z; h4 C+ H/ G
#reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据8 Q- W" m* b* }! B4 e6 Q6 n
print("columns:", reframed.columns)# \' J b* v2 {3 Y# o1 S9 n
# drop columns we don't want to predict! |, [6 u7 S! Y' i
reframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据
$ g/ M0 D: k0 H! U5 Z. p$ \. s#reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据
4 C9 _3 M+ d$ }8 I: V0 qprint(reframed.head())
" t7 S7 n( x3 ?9 c* d" jprint("new columns:", reframed.columns). w& r4 i* h; n- N8 b# r
# split into train and test sets) v1 b0 h+ W# |$ j) F
values = reframed.values: u' l& R, B% N: U: h) L
n_train_hours = 365 * 24- }5 z1 T6 k- j$ ~; X
train = values[:n_train_hours, :]7 U4 R1 x4 s- y0 W
test = values[n_train_hours:, :]
. o0 t) N0 c( Q7 Z/ P' P5 N1 }3 e# split into input and outputs
3 N3 u- {8 J3 a5 p% U8 dtrain_X, train_y = train[:, :-1], train[:, -1]4 p. d' O4 m9 J3 b- k+ b3 ^) I* G3 [
test_X, test_y = test[:, :-1], test[:, -1]
6 T; l% \% G; i \# reshape input to be 3D [samples, timesteps, features]
- S, s+ w: i3 I! x- i8 ?#使用Dense()模型时不用变换
: T8 x4 v- ?7 A; R, wtrain_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1])); E$ @ B4 K% M |/ a6 V' \- t% a
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
( w: l) @) m+ E/ t2 f/ Vprint(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
4 D0 P+ w. C: ~4 k1 G$ }# design network# T5 t0 b8 s8 I# Z0 V9 g
model = Sequential()/ k2 q- q+ C1 z3 I& z" y/ s0 d
#model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
' B) S x2 D0 i5 O. g* J% U#model.add(Dense(50, activation='relu', input_dim = 8)), V& ^5 p8 o: H: n2 A) q
model.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))
) d) m3 X( X5 w1 I5 C4 mmodel.add(Dense(1)), g9 t% e# k/ G/ n! M: R
model.compile(loss='mae', optimizer='adam')7 g% z3 V6 ?/ C& H( t, F
# fit network
5 h6 k1 m0 q# M6 h0 Ihistory = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
& `! X7 e( _2 o; s' P% M! |# make a prediction" z$ [; X& @" v
yhat = model.predict(test_X)/ R5 C5 I# |6 j1 l
print("yhat shape:", yhat.shape)/ B; [) R* }5 y$ S- J
'''
! b8 w0 {8 q2 ^. n计算在测试集上的均方差
! V7 x) B" ]( L7 Y6 Z2 i, mtest_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
9 f% i6 p, E, _! O! n* D$ N# T5 Xprint("test_X shape:", test_X.shape)
2 g0 ?4 f8 a o& J0 R8 R
o( [" i- X/ V. |, U+ i
1 Z) `: C* F* F" S+ I1 g, F( s# invert scaling for forecast0 \- B( w4 ~# z( U1 U
inv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)7 a7 P2 z' r0 C6 c8 |3 t
inv_yhat = scaler.inverse_transform(inv_yhat)
7 r+ B) r+ W$ A6 F: `& v0 `7 b0 zinv_yhat = inv_yhat[:,0]7 F! S# l0 m/ G' f8 L: }
# invert scaling for actual0 e- r, O+ E7 J/ z
test_y = test_y.reshape((len(test_y), 1))
. _* ]% `9 y/ e4 v7 n0 C+ b* Oinv_y = concatenate((test_y, test_X[:, 1:]), axis=1)
7 z$ u# z/ G* i% Sprint("inv_y:", inv_y[:10])
6 r1 m/ b7 }9 }. tprint("inv_y shape:", inv_y.shape)
4 ~4 g4 Y- W# M2 Z
& b) t4 U7 d/ ~' U4 y" r- ]7 h
inv_y = scaler.inverse_transform(inv_y)
6 G! Y/ T6 i# Y! cprint(inv_y, "*"*30)
2 H" d* b! ]' ?& y& J3 s! Q* g5 G5 H+ ?& S
8 P, I; S$ Y9 s: r U# ~2 {6 C1 C# Z( M
inv_y = inv_y[:,0]
2 K# C5 D$ { e9 P' v6 Q* }# calculate RMSE5 F+ v1 k; q; Q- T% E; O
rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
5 H2 Y9 S! e5 |) A) n, bprint(inv_y[:100], inv_yhat[:100])+ w: s) g( k& p5 }( r
print('Test RMSE: %.3f' % rmse)! W8 V, h% n! s
3 O/ S5 t1 b( G) F) [9 K
: o/ r' ~$ q' i) c& P
'''6 x# \; A2 w! R' t R ~9 {
实验结果
. Q9 w' ]+ G1 @- f; K实验1:用前一天的天气数据,预测某一天的空气质量
" E7 ]3 T: o$ n- E) H6 r8 B) {使用LSTM模型6 j2 W) f w& |3 o( g. Q" Q
结果:3 L6 E' Q; M' r( {
Epoch 49/50$ b! F: T5 T8 a2 e* t( u% ?% h u
0s - loss: 0.0144 - val_loss: 0.01332 C( Q4 p/ S O' G
Epoch 50/504 w, C0 y& n2 s; f8 s5 F" l
0s - loss: 0.0144 - val_loss: 0.0133& j! ~9 E6 ?$ P% a8 `2 ^
, a) I+ o) [' k! M) O" V
! `$ O) C& [/ M实验2:用前3天的天气数据,预测某一天的空气质量
4 @0 }( m2 Q9 E; R* s7 H0 O% m使用LSTM模型 T k* d* T/ i" q8 k# Y' e
5 Z: n( [. g. L0 A3 Y: k P" t
! S1 p: B; ~ H) w4 E
结果: `3 m4 `( u3 l4 I& e
Epoch 49/50
% L& R1 k, S- P m3 Q! G9 G0s - loss: 0.0147 - val_loss: 0.01499 w1 y2 ]; k- @
Epoch 50/50
3 P: y8 W4 s6 M! [5 a+ v1 a. b0s - loss: 0.0147 - val_loss: 0.0150
1 R$ e8 a# Z( u8 g
1 z. q2 C7 d3 t4 B6 M: T( ]
* e. r4 R/ ?$ Q2 E8 M1 d实验3:用前一天的天气数据,预测某一天的空气质量0 G4 G$ }: p; \; i: w
使用普通的全连接模型 Dense()
# }, |, f6 \! g结果:, S5 U- Z) E1 o" c" h0 p5 L
Epoch 49/50
/ A# \4 m3 I* j0s - loss: 0.0144 - val_loss: 0.0146
" V( P) Y. @: ^' ~% X' H+ mEpoch 50/509 ~* i$ i; E2 `* u: a' h% c
0s - loss: 0.0148 - val_loss: 0.0151- a/ k t3 x$ Q* f& g$ C
' x/ ^# p9 k3 z! d- ?0 C& p% X4 L* f4 ]5 d$ _
实验4:用前三天的天气数据,预测某一天的空气质量6 A" y$ Z( \; e; l& o
使用普通的全连接模型 Dense()& |9 Q% O. F) x, _
结果:3 B: G0 [3 Z, [- B
Epoch 49/50
4 [3 e2 W$ H9 e6 O0s - loss: 0.0150 - val_loss: 0.01658 T2 m+ A# d" w& h6 _6 a6 c( u
Epoch 50/50
6 i, `* _8 O! W+ j, B3 I8 z6 R0s - loss: 0.0148 - val_loss: 0.0141
8 |* N, Z4 ]3 `' t h8 T& b' P S+ }/ U
# O8 y! i. K0 f; e* h z* m/ S( F: U7 b z( t
实验5:用前一天的天气数据,预测某一天的空气质量5 J f- B/ S1 U: I9 l
使用SimpleRNN
H' U- n3 f6 T1 y$ A$ [6 |Epoch 49/508 c) p, A& v9 D7 k" t+ G# {: F
0s - loss: 0.0160 - val_loss: 0.01404 l0 U# c9 y* C0 s
Epoch 50/50( d+ R* u1 f% y6 m/ C& ^
0s - loss: 0.0147 - val_loss: 0.0150* r7 g: @3 U- D
& k _3 \8 W, z/ ]5 k
0 ~5 {# t+ x: D6 a4 H7 ~
实验6:用前三天的天气数据,预测某一天的空气质量
# \( U3 v8 J! e1 W6 e9 m使用SimpleRNN
3 W! W5 c3 Q: E- m# P- s6 k* rEpoch 49/50' s- t- E- s3 w" H- W
0s - loss: 0.0164 - val_loss: 0.0233
7 x! k- ?/ {. {7 K0 F3 EEpoch 50/50
) o9 B6 Y* Y! M* a0s - loss: 0.0166 - val_loss: 0.0227
+ T+ J, W9 @6 y% u/ A; g* `; s: y8 y3 YRNN和DNN的区别RNN中的循环是指一个序列当前的输出与前面的输出也有关系。也就是说,网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐层之间的节点不再是无连接的而是有连接的,并且隐层的输入不仅包括输入层的输出还包括上一时刻隐层的输出。 / s; W1 n, o) p; I; L- e
: v7 N8 D1 i5 \: l1 I
- y& r. `. F2 P; H$ C, q
RNN和LSTM的区别6 E% f- \' I& a5 U% d5 o- ~; P
LSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。" K- Y" X$ G; S6 G9 |
2 Z$ {4 _, T& u2 _8 N# I6 ^' j( V) o* x6 x! q# w
但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。
6 a9 Z0 E& j2 C( g3 f, H+ f2 w![]()
1 g ?" b+ E, X5 u( D! I* K ~8 o% P" I: l* L" [
请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员
8 A. {1 X' ^0 g/ P; ?* @" p _/ q
1 W- c0 Y8 _, v; @2 i: l
/ l, ]6 X3 ?: R3 k+ a; ? |
zan
|