- 在线时间
- 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预测时间序列数据* |4 @6 F1 V! o6 ^& l$ c z+ T
! a8 ~1 o2 c" `8 ]3 I
9 X$ O4 U/ w4 G文章目录. b, e2 Z* s$ s$ x
背景
7 J6 [1 N& H* W1 m/ p+ T9 V结论( w# e% l1 ~' b5 e, r
代码
8 C' {) `1 l4 a/ }0 ?7 [% W# g ^实验结果& G; h3 O! m6 @% Z& b
RNN和DNN的区别2 [6 e4 _ r* S. w
RNN和LSTM的区别; {7 Y* R9 }9 @) ~5 z
背景
4 R: ]8 R5 F! [, a复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验
; g. U) D) T3 j' T; R熟悉用LSTM模型训练
) v# L o0 }: A验证将时序数据 转化为分类问题后,预测是否有效果9 n% a1 e4 d8 H
对比SimpleRNN与LSTM模型 哪个效果最好?
6 C- g! B5 \ [% `6 i& k验证LSTM相比于Dense()模型 是否有提升?
4 ^- ^2 q$ @( Z$ i; W对比使用前3天的数据 和使用前1天的数据 哪个效果最好?
+ o8 Z/ z: @( Z- q6 s结论$ f5 p) [! l8 K" P" b
使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好0 u' F/ y8 M/ v( w/ l: j- x
使用LSTM的效果优于SimpleRNN
- G1 v0 [ o: P( _" F! Q代码
) b/ K( F, {$ C2 [from pandas import read_csv
. f% b5 H! K. M5 }. U7 Z7 S6 Ofrom datetime import datetime* J Y- w# @& ~
import pandas as pd/ B% b8 q/ \2 r3 { t- u2 Z
from pandas import DataFrame
N9 p3 e% n, Lfrom sklearn.preprocessing import LabelEncoder,MinMaxScaler( g- t5 f, I& C+ x! F6 V
from sklearn.metrics import mean_squared_error
9 B2 H3 n, b% z- o3 O1 T% Afrom keras.models import Sequential
- C$ F6 X$ K" r" qfrom keras.layers import Dense, Dropout y m F+ {! J" _
from keras.layers import LSTM
$ U" O$ K' Y& B" H3 N1 A3 dfrom keras.layers.recurrent import SimpleRNN
# j+ \4 @6 R5 _: \# {$ }+ Ifrom numpy import concatenate
% E% b" q2 Z" F0 a+ _! Lfrom math import sqrt. D2 k# u) o( ]9 R$ l: |( Q* @
) C0 {& T0 g4 k$ L, L
# M2 X, b c: l. \. g5 X! s
5 G- }. _8 s! _( L9 m, U/ {7 k
4 d* `. \% E n7 {1 l5 x6 \# load data8 Z- _( M ^; q9 d
def parse(x):. p, M) K B# e+ ~6 n
return datetime.strptime(x, '%Y %m %d %H')* |4 J5 O- a* u3 o- ?0 D
9 _+ Z# _, p" ]. d! F5 \
def read_raw():0 B$ a+ D7 v; Z" D B! _9 I
dataset = pd.read_csv('raw.csv', parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)
8 Z; n" W- E) F" }( _1 q8 O# s& |. a dataset.drop('No', axis=1, inplace=True): h( s9 p' t4 b7 o9 q U3 B
# manually specify column names9 _+ [' U+ p% D0 k9 a6 m- n2 _% H
dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']0 w" q- g* W+ x! m: k+ q9 x
dataset.index.name = 'date'9 Y; S i3 M$ A5 \* X J; |# p: H/ ^
# mark all NA values with 02 k8 M$ t8 q/ `3 H% e+ M r
dataset['pollution'].fillna(0, inplace=True)0 D" {- j$ c- V
# drop the first 24 hours
- P6 t- m2 M" J7 P dataset = dataset[24:]
. t4 W; Q! V9 a: K/ A3 z1 ?& @ # summarize first 5 rows
1 p8 b0 H3 h( e4 \ print(dataset.head(5))) }+ V0 I: x/ t% G
# save to file' }) n1 Z4 ~9 T2 i% ~
dataset.to_csv('pollution.csv')! L& c: o% e7 l+ f2 ]8 o( g+ x S; e
6 i% a; `' s( U7 Y7 @
2 g. j, M- B/ X, R! W2 w0 y- f/ o+ ~5 f" O. d f( E3 }
6 P$ F+ T% O0 }4 f5 x$ K
# convert series to supervised learning$ M p6 c( _3 V+ _1 ?! P
def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):# v( ]7 j' U# X1 U" G2 N( |
n_vars = 1 if type(data) is list else data.shape[1]
) B8 x- T1 A' {9 R" o/ ~0 B df = DataFrame(data) D( X. y7 B- Y3 i3 C( [
cols, names = list(), list()
3 H* |4 v9 U' A9 V) s( Q # input sequence (t-n, ... t-1)9 s# q& A! m) q; d
for i in range(n_in, 0, -1):
+ n9 Y; n/ v, p: |* z/ a cols.append(df.shift(i)). `' m) |4 V/ s3 Z/ T! I% @' L
names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
% _2 U# Y1 F! `9 I/ M5 i7 J # forecast sequence (t, t+1, ... t+n)+ T4 I+ L8 S0 Q( P0 I
for i in range(0, n_out):6 y9 o2 i1 f/ M, t/ `
cols.append(df.shift(-i)): w% S6 Z `$ X j1 E7 A# w# n9 ?* v$ O
if i == 0:
/ |$ S* k3 N. p% p; L7 ` names += [('var%d(t)' % (j+1)) for j in range(n_vars)]! B$ v& X; a) \, ]
else:
3 N1 S3 d3 Y# d: \5 g names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
8 F& F4 W2 j; J5 f1 n( k # put it all together
- K: {, s$ p1 j. ]) k" `0 D' q agg = pd.concat(cols, axis=1)
& Y" E, G; n9 f2 e# }, s* ? agg.columns = names
9 m, {' ?+ V% t+ ?5 p$ b# l # drop rows with NaN values
a8 x0 f5 w7 S* F. J; Y% z/ v2 w if dropnan:
& |9 R6 a$ t* K* a3 U7 m! Q agg.dropna(inplace=True)" w6 D3 v5 o7 R- T; ?1 y
return agg0 O! H% w/ Y$ W
4 m1 @- n) v) }* N# load dataset+ q8 R8 c7 a) e% E
dataset = read_csv('pollution.csv', header=0, index_col=0)
5 Y/ o0 P( \) B' T- Hvalues = dataset.values4 L7 q- a3 v6 d8 U# x
8 Z/ d: I1 ~+ |& U: M9 f8 X$ P( D9 g; F7 V; J
# integer encode direction
- U0 m& ~5 H7 U- T6 vencoder = LabelEncoder()( Q! q: p* A4 \5 L
print(values[:,4])
' {: h: K* _+ u4 |values[:,4] = encoder.fit_transform(values[:,4])5 i$ j8 b5 j* Z5 \% S" r( e F
# ensure all data is float
7 B: M3 o# X1 W; Q+ }values = values.astype('float32')
' ]3 i1 {6 f8 {$ z: p* E' e. p# normalize features
0 h7 a) {% a3 u* z9 Vscaler = MinMaxScaler(feature_range=(0, 1))
0 U8 J. o+ I' K+ l9 |# L3 H0 K5 Nscaled = scaler.fit_transform(values). C m h; g1 t8 o
# frame as supervised learning
! w3 M4 i. P4 xreframed = series_to_supervised(scaled, 1, 1)
. u# z. P# r0 b; Y4 ?& K# h2 v+ [#reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据# X$ G( }2 M' h# u% Q4 D6 x
print("columns:", reframed.columns), f, x' `& T6 z* x" p$ H
# drop columns we don't want to predict
9 E7 U* ^; ~6 p8 q+ G, \$ [* U/ [reframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据2 T. I3 B- ?; D2 L3 b- c
#reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据, L( {+ d$ h3 T7 ^/ f5 G
print(reframed.head())
+ y! {$ I* P e1 y# f$ b$ qprint("new columns:", reframed.columns)
1 o! r7 A; g" g# split into train and test sets
1 G9 q# T4 v( Jvalues = reframed.values
7 ^, }3 S* T6 P# Jn_train_hours = 365 * 24
" D2 B9 _- R; p5 D atrain = values[:n_train_hours, :]& B8 E- b/ n' H+ Y
test = values[n_train_hours:, :]1 \3 z- g: @9 q' L
# split into input and outputs. B5 F" B) u) F
train_X, train_y = train[:, :-1], train[:, -1]
E% p& d" H( Q# vtest_X, test_y = test[:, :-1], test[:, -1]
; t6 a# D1 J3 m& B# reshape input to be 3D [samples, timesteps, features]; G9 B- R8 z. l
#使用Dense()模型时不用变换
" a7 B# j x8 O) j3 M9 Q1 x. J8 |train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
# f! u0 o" p6 C1 ~. s( d* p+ W' ytest_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
& w+ e% C3 D ]. cprint(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
3 @ [* V! b l2 d5 ^( J# design network
6 D5 K$ |/ l! F2 z+ k, a, bmodel = Sequential()
% G3 Q1 n. e2 J$ z) y5 O1 C) S#model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2]))), B5 V- G3 l6 j2 S0 p& G c- B% b/ |
#model.add(Dense(50, activation='relu', input_dim = 8))& n! ~1 |2 ?1 f* f' x$ d
model.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))) t8 X' U& o4 W, R, C( s
model.add(Dense(1))
! ^" d+ [, @( w2 J5 N, Hmodel.compile(loss='mae', optimizer='adam'): ^5 x- y! {+ d* c" i4 N$ c8 D
# fit network
8 A( D9 C% H9 o: Y8 ?: Shistory = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
4 h' L' j+ H. Y2 O& b9 G8 ]5 a# make a prediction. P& x( m Y( G0 J: U( j0 p
yhat = model.predict(test_X)8 q1 h$ e: [: L4 l; } B- S
print("yhat shape:", yhat.shape): i) g( E8 J+ j. m2 o- F5 y
'''3 s% P0 ^# r2 j& D; o
计算在测试集上的均方差2 {3 t0 r- S2 @, r0 Y+ Z8 `3 R. D
test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))8 _) _' M8 U: G% j. `# |3 n
print("test_X shape:", test_X.shape). r/ b4 k9 D. m$ H3 P
& P1 l* O9 w& s3 `; P) i/ }) r/ c% ~5 b) C. h. k# ?8 o
# invert scaling for forecast
" X4 w$ ]3 Q6 E6 p" yinv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1). [9 i) Z$ m% ~" H* f+ |( S
inv_yhat = scaler.inverse_transform(inv_yhat)
, |# }8 R7 R& h! g6 ?# L+ L hinv_yhat = inv_yhat[:,0]
# z) T4 n& k r/ I0 }# invert scaling for actual
# I3 [% Y+ b: I9 c- r# Q- ^, n. ttest_y = test_y.reshape((len(test_y), 1))6 C! f* b: t- [. v# H& B) {5 `
inv_y = concatenate((test_y, test_X[:, 1:]), axis=1)- t+ B& L4 x2 a: w8 p$ a7 Z/ L2 B; P
print("inv_y:", inv_y[:10])
( H6 ^% Y. ^' I2 Iprint("inv_y shape:", inv_y.shape)
! _& ^5 d$ |# F( N- @! y; G( ]! O% q: `4 d5 [7 c* b1 S
! V& `* {7 Z1 A8 _
inv_y = scaler.inverse_transform(inv_y)9 |$ P' y0 x+ l3 ]9 p
print(inv_y, "*"*30)
% u6 Z5 g, h1 _+ }3 A$ @2 ] I
0 g7 d" n) _1 y6 [1 B
$ f+ h4 V* q$ U* v+ Zinv_y = inv_y[:,0]/ c% n U X! \
# calculate RMSE( D$ ^" b( n i3 r+ V( `" |; T& G
rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
) Y5 z' o7 _1 B0 ^print(inv_y[:100], inv_yhat[:100])! H, b! M$ P6 h6 @
print('Test RMSE: %.3f' % rmse)
/ F$ Z6 b& `. a# ?2 }8 F
) _4 d4 |, [: G) i4 n' M5 f) [) k8 R0 m' E& B0 P" z" v: d
'''
$ ^. c8 b7 q8 s, J实验结果
$ R1 H! d4 v$ M实验1:用前一天的天气数据,预测某一天的空气质量
; O; g$ j( g& g* U3 s# M使用LSTM模型
% Y* t" m, Z) P. s: V X+ a+ k结果:
0 y/ D) Y! f4 F2 i8 Q$ q7 P, E7 wEpoch 49/50+ C/ J: G' ]2 {% X; k2 ?( b" t
0s - loss: 0.0144 - val_loss: 0.01339 a& P1 i' X& C. P9 W# A z
Epoch 50/50
7 \* t! G ~( w9 M9 G0s - loss: 0.0144 - val_loss: 0.0133
: s1 M' p6 _: [' X" O3 E
3 l# t& y7 h# o7 m( s! A1 Y, q. V8 h s+ Q5 Y% [
实验2:用前3天的天气数据,预测某一天的空气质量
( G2 K" z/ J: B( t: m7 j使用LSTM模型1 c+ m# H `) |+ }" V3 {, O: G; N
B' P r* Q4 M9 c# e% i6 |% y
结果:
" ]2 i8 B$ }* M+ j* BEpoch 49/50
& ~9 L) k) ^9 U2 l- a t0s - loss: 0.0147 - val_loss: 0.0149
' t5 Z; `, Y M8 nEpoch 50/50
5 k, \2 G- q) T( {1 Z, W1 w0s - loss: 0.0147 - val_loss: 0.0150$ q6 ^" v4 ]' c, |% I" g
9 w; g( M- T& N; d. U( b
8 A. e* @; s' { M6 h- T1 H实验3:用前一天的天气数据,预测某一天的空气质量
! {3 ~" f2 S: [1 q0 b& q4 s使用普通的全连接模型 Dense(): R. E# }8 N2 `+ A/ r
结果:& q8 f5 |" r# z9 W4 i- o: P
Epoch 49/50" m- c+ M; m* j P
0s - loss: 0.0144 - val_loss: 0.0146
- q; _! M X# ]Epoch 50/50
* N6 [6 S! N: X2 @0s - loss: 0.0148 - val_loss: 0.01511 X$ a: l2 [# v( |5 M0 c
# a: T/ q4 f7 p. f
3 q! ~6 }, ]) V# |# D& m" @/ N! y实验4:用前三天的天气数据,预测某一天的空气质量% n" J+ Y1 t- Q# [' j" O9 O* h
使用普通的全连接模型 Dense(), P# g/ v$ O h# [$ O
结果:
$ c! x8 T4 A* R* X: k2 LEpoch 49/50 p4 ~( |" ^# y) Q0 i( b7 x' y
0s - loss: 0.0150 - val_loss: 0.01653 p V3 }% n. h s
Epoch 50/507 d, j1 B8 ?8 c& ~$ p2 |1 N4 g
0s - loss: 0.0148 - val_loss: 0.0141( }9 w* k. M2 f7 K( r$ T! A
6 `2 r" \5 T4 \0 M& v/ P9 E
4 E" r. a' G$ r5 X9 [$ ~! C实验5:用前一天的天气数据,预测某一天的空气质量
! w/ }7 u# @) R% Z' e4 o# S使用SimpleRNN$ _: N i% H- i# X
Epoch 49/50
# i, u; o; J% u' S0s - loss: 0.0160 - val_loss: 0.0140
1 J) \ z( Y/ U% y) I) _Epoch 50/508 u+ C: ^) k$ \1 ~$ h% o9 N5 L
0s - loss: 0.0147 - val_loss: 0.0150
) |( i L9 c! y& I6 d9 F1 b7 Y. N1 N; W4 c& Y# l5 W
* U' n; i4 I* r3 ?3 t实验6:用前三天的天气数据,预测某一天的空气质量
( C3 f/ m( R! ]使用SimpleRNN4 l8 U( O6 _. U5 \; i; |1 O
Epoch 49/50
. ? c L& f3 W2 K- b/ A$ b: k0s - loss: 0.0164 - val_loss: 0.0233* f& C+ I7 V! `+ J9 I3 R4 @
Epoch 50/50
1 G4 u0 g% g7 W! a0s - loss: 0.0166 - val_loss: 0.0227
; N$ x! S/ {+ y3 Z5 D3 ^RNN和DNN的区别RNN中的循环是指一个序列当前的输出与前面的输出也有关系。也就是说,网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐层之间的节点不再是无连接的而是有连接的,并且隐层的输入不仅包括输入层的输出还包括上一时刻隐层的输出。 8 E( P3 E* o) v5 j, N; T
# Q, @3 ?7 e! T2 n; j( B
+ w; G: J7 g C6 X u- a+ ]
RNN和LSTM的区别
9 }2 T1 x) R0 i S# B! R% XLSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。
- X& r9 N5 `3 ^7 Y/ `8 M' x
4 H9 n" n$ W! G# v& p1 E
( p C2 t( O( i2 g$ h: s6 ~但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。
* Q$ I7 o, f w% p- Q ( ~! v+ O6 ~- v, `
; S& n ~# B1 n请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员
# n# e6 u# N' J2 W% w- ?) b! v; [1 R! f$ m W5 l+ T* ?
+ H6 o' T) v8 \0 g, i |
zan
|