- 在线时间
- 514 小时
- 最后登录
- 2023-12-1
- 注册时间
- 2018-7-17
- 听众数
- 15
- 收听数
- 0
- 能力
- 0 分
- 体力
- 40222 点
- 威望
- 0 点
- 阅读权限
- 255
- 积分
- 12778
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1419
- 主题
- 1178
- 精华
- 0
- 分享
- 0
- 好友
- 15
TA的每日心情 | 开心 2023-7-31 10:17 |
|---|
签到天数: 198 天 [LV.7]常住居民III
- 自我介绍
- 数学中国浅夏
 |
使用LSTM预测时间序列数据% |: n2 I2 y( z' g4 o. X
& L$ L$ M' Y* ~- E# ^' ~) z
1 H' f6 _- S/ p2 }# H1 K2 i% c1 Z文章目录" g( p+ Z, k: s" ?( S* ^' P6 m
背景
$ U7 Y* h/ a' e$ A结论% ~" }1 O0 p! c8 u7 I9 f
代码
: L3 d0 H+ I! a8 Q: c实验结果0 g& V9 w$ Z; {2 X/ a- n2 c N
RNN和DNN的区别
) u& E4 ?# R6 U% R! b- u5 J5 DRNN和LSTM的区别3 e3 `0 f# l5 O
背景6 }9 W B: p3 X
复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验4 q% b _( s4 ]' S& l
熟悉用LSTM模型训练
, D0 q7 @ T4 t3 A2 E验证将时序数据 转化为分类问题后,预测是否有效果
( l8 W" _9 m: w0 B- w对比SimpleRNN与LSTM模型 哪个效果最好?
( X( z0 r; s# T验证LSTM相比于Dense()模型 是否有提升?: n) }. s% S, x6 a
对比使用前3天的数据 和使用前1天的数据 哪个效果最好?- `, d7 M# u/ k$ F) i/ S+ j9 a
结论/ z j) e X. X2 f
使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好
3 E3 n6 g& E2 m1 u8 \; Y* X使用LSTM的效果优于SimpleRNN
$ l7 d- T1 s/ j5 S- \4 L# G, {- s代码/ q1 b9 q8 ^2 A! `, m8 A" R, ~
from pandas import read_csv
9 W* ` I- F5 w3 F- e2 A; V2 d8 b5 `from datetime import datetime
2 S' k2 I1 v; n9 }import pandas as pd
, B0 V, P0 s/ rfrom pandas import DataFrame @+ Y9 } t: U" \ o! k# A+ E
from sklearn.preprocessing import LabelEncoder,MinMaxScaler5 }/ h7 m" t1 Z* g
from sklearn.metrics import mean_squared_error' n+ ^# W2 r' T) h4 _
from keras.models import Sequential
/ k1 T! L; z$ I1 w$ p) nfrom keras.layers import Dense, Dropout/ @: w) |( C' j& N7 B% L; A7 b8 O5 P0 C
from keras.layers import LSTM
) U/ m& J4 k& y% qfrom keras.layers.recurrent import SimpleRNN
, P1 I* p: M5 v( _* i, `& G/ {from numpy import concatenate: t, v: O c9 C$ K1 ~
from math import sqrt; V; T: j) m8 J) {$ N6 w% }
: y- [; N% i4 \- [2 P! Y; o
- z( u$ [7 t8 _8 D" ~! {9 m7 K( R6 ^
" p3 s6 N! C% U: X# load data
5 K' ?( l1 H( |def parse(x):
6 x1 G( ], t. s return datetime.strptime(x, '%Y %m %d %H')6 Z" s, s6 |) c5 n2 D. R! i# v
" c3 u6 K5 |* G+ Y3 H" p
def read_raw():
; ?7 ~, i7 j; z9 a `4 r5 e7 g dataset = pd.read_csv('raw.csv', parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)
, w7 ~* f) E4 h* z dataset.drop('No', axis=1, inplace=True)& I" J6 \% z! c% p( k
# manually specify column names
1 e( _* x% C/ c7 J8 i dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']
) k: v7 |& M4 ^! ?& d dataset.index.name = 'date'
! ^/ ?6 ]% t2 A' d1 a" H # mark all NA values with 0; q; f5 R7 {6 a: Q
dataset['pollution'].fillna(0, inplace=True)
% L2 a4 U1 ~! y7 B, r8 ^* _ # drop the first 24 hours
" H# H9 k; p9 \' H0 O M1 M dataset = dataset[24:]- {7 d4 w/ t6 v
# summarize first 5 rows8 L+ y+ S! ^# O5 T2 ^
print(dataset.head(5))$ u( y8 k* _& ]( b) H; Y4 P; ?
# save to file% q7 L6 z2 ^ |
dataset.to_csv('pollution.csv')/ Z0 N: t% l* J, K/ m! O0 z
5 y" i# X E! D* e( |% T
" ]. R& I e5 P" z- `+ }4 t
2 x8 e, V1 E/ }
O% a7 O" N% |0 |" ^# convert series to supervised learning" N# i8 i- `% x
def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):" E# l) q' E5 M# Z% K+ C8 k3 F# Y$ J
n_vars = 1 if type(data) is list else data.shape[1]
$ D3 i$ V9 c5 O) K3 W; _8 Y df = DataFrame(data)( W' ?. h3 C C( y
cols, names = list(), list()
4 Y) m# T2 i* F' m& G& A # input sequence (t-n, ... t-1)# O7 {; L! F) B; t, t: w
for i in range(n_in, 0, -1):
0 v: A" @8 j2 x8 f) [- O cols.append(df.shift(i))
, Z j+ I$ E6 l& E; l9 D names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]/ t/ U: u& F8 O6 T5 \& ~5 e7 b
# forecast sequence (t, t+1, ... t+n): H$ P6 `" i' i2 z) z# E6 { {
for i in range(0, n_out):
- f* a$ u$ A* ~; g cols.append(df.shift(-i))4 S% m% L q% i. E3 S# w* S0 e
if i == 0:- e% w# R% v: q* J! X/ L
names += [('var%d(t)' % (j+1)) for j in range(n_vars)]2 H! y* U# F$ S5 E) ?4 n5 j
else:
; F' ~) g0 A- Z$ _$ ^- A names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]' H' K- \" l! }- M3 k5 h0 V8 Q
# put it all together- v0 N u; }2 ~2 o0 E8 b. B
agg = pd.concat(cols, axis=1)
0 L* R4 T4 F) C agg.columns = names( o2 ]' @! z1 W, h0 |9 h$ f. B+ t
# drop rows with NaN values r4 A N3 M# S; T) _% m$ I6 O) t5 n
if dropnan:9 S! T( |7 \) A( t
agg.dropna(inplace=True)
* Y' R9 F+ w% C8 H' n' }2 \; T return agg+ B' U, ?/ ^9 b8 T, D3 e7 ~
! ?) D% w1 T' a' `( `
# load dataset
2 H! N; v* ^! d8 W- L4 edataset = read_csv('pollution.csv', header=0, index_col=0)
! A' }; P( w, t2 K5 J/ svalues = dataset.values
5 s2 P/ i9 a5 a! r( l8 G+ h
1 y( y( V3 t- a* p# a% }+ H1 B' H5 ?4 M: V, H9 E0 I; m0 P
# integer encode direction% v: @6 S9 ]$ j
encoder = LabelEncoder()
5 J/ f, _- s& V% s/ k9 [0 B# \. |print(values[:,4])
" a& D; k" i2 N$ x6 C+ Vvalues[:,4] = encoder.fit_transform(values[:,4]) Y3 _- s9 R7 v+ d. X3 ]8 {- n1 U
# ensure all data is float
$ m, }3 U! G! e; p: v8 \. B9 \values = values.astype('float32')
* @& [8 q/ `/ [; ^* N. `# normalize features
2 F; k. V1 {& T* {& j3 g* w7 Rscaler = MinMaxScaler(feature_range=(0, 1))3 m/ G' o8 J6 ~4 P! A
scaled = scaler.fit_transform(values)" d' Z' _- ~$ J7 }& t8 g) F6 a3 M
# frame as supervised learning
% t& R: a) R4 l9 L, Y. Dreframed = series_to_supervised(scaled, 1, 1)
* m1 h: g. |9 u; f#reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据4 V6 y* U( u, e& \2 e
print("columns:", reframed.columns)
7 M- z7 E# I6 [# drop columns we don't want to predict7 H: p8 V2 L P, l- S# T7 V
reframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据
, F! a4 x4 `; o) i/ I* o#reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据
# f4 K: ]2 L4 M$ y' Nprint(reframed.head())% C/ W X4 g, i( ?4 c8 ?
print("new columns:", reframed.columns)
" ?7 J; T4 ]5 K$ W# split into train and test sets% ^( y. V7 W4 E" @) B8 ?3 h
values = reframed.values
3 r3 z4 C! D- c( k Vn_train_hours = 365 * 24
% ]' u: O/ p- b" @train = values[:n_train_hours, :]3 g. X+ D3 ~% ?
test = values[n_train_hours:, :]
8 @. D- {; D) b9 I3 J* ~# split into input and outputs
8 o: x# t% n' Ctrain_X, train_y = train[:, :-1], train[:, -1]1 ]8 L* x V) r" \' J# k
test_X, test_y = test[:, :-1], test[:, -1], N. @* J! @" o k* X! ?, a
# reshape input to be 3D [samples, timesteps, features]
' c9 M5 ]& [. j. p: \0 l#使用Dense()模型时不用变换6 [6 k8 j8 p* a s+ K/ S
train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))' p. P' R$ k- q& P4 w% e2 z
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1])), z9 ?* o* m/ w- O
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
# f* w8 R6 ?" x. @# design network5 E- U: h5 } {' A, o1 D7 [' y
model = Sequential() l/ E# [- a# c# J& q8 p
#model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
& p- m: ?. V5 D* V; V( R. P+ G' o#model.add(Dense(50, activation='relu', input_dim = 8))
" H$ y& I# y3 e' R2 ]( t) J& tmodel.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))4 w4 f5 b. t7 V% p& Q3 R2 s9 f
model.add(Dense(1))
. n! C! ]6 [1 Smodel.compile(loss='mae', optimizer='adam')3 w ?' w4 t: O" j
# fit network
& n# n6 |+ U0 w/ A. Z Lhistory = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)+ I3 y: ]8 K5 X r5 f
# make a prediction
( g: i5 Y2 J; \: Z. Pyhat = model.predict(test_X)5 e: a7 ?% Y) p! [
print("yhat shape:", yhat.shape)
" ]9 `9 A2 p! B2 y# `'''
+ E, `/ ^) l1 ` @& E) X5 q" T计算在测试集上的均方差" X' l: p. V9 Q
test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))5 M& Y/ H' G' L$ t( l
print("test_X shape:", test_X.shape)% n! E K4 f" U1 t* k
; l/ T! T: M4 R( G, e+ ^% n! B2 Z/ N0 e# s7 X
# invert scaling for forecast* |6 L+ o% c+ M
inv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)7 c! B/ G, E& Q8 [
inv_yhat = scaler.inverse_transform(inv_yhat) J. f2 D' b( @; w- o; P
inv_yhat = inv_yhat[:,0]! T" Q0 }% ]7 g/ U' A
# invert scaling for actual9 H5 i; `/ a' ^( \, L2 k* k
test_y = test_y.reshape((len(test_y), 1))
( G( G6 w2 s$ S" \7 w& \inv_y = concatenate((test_y, test_X[:, 1:]), axis=1)8 d, t0 [* W% X/ y0 ~- r
print("inv_y:", inv_y[:10])
" m A% r0 f# n; q5 J7 v3 G1 p5 Oprint("inv_y shape:", inv_y.shape), L2 w4 _! {' B! p$ i% x1 ^, p
/ t: k! j& n7 B! b& {
, H; O" j! D$ x5 r+ i
inv_y = scaler.inverse_transform(inv_y)
) F6 N) z% F+ E' Iprint(inv_y, "*"*30) W$ l5 Q2 G2 p) G; k. m
. K# C, G1 D0 W' W w% x$ Z5 Z! X( V( U$ y( B
inv_y = inv_y[:,0]
: b7 c( u1 Q+ C, \- M1 r3 i4 d+ a# calculate RMSE
" g m$ A2 R" C7 O+ G' [* trmse = sqrt(mean_squared_error(inv_y, inv_yhat))
0 }5 t, ?: a4 |! X f9 l! Qprint(inv_y[:100], inv_yhat[:100])
" b( T2 N9 |, R0 ?print('Test RMSE: %.3f' % rmse)
1 c1 r& k2 i, p1 ]8 p5 z5 G' _+ A& M" Y( r$ w* D
/ U; ]$ v/ M! C
'''8 Q; I9 Y* s6 {6 r) i. L
实验结果
) q, g* A7 D2 U9 F/ G7 j实验1:用前一天的天气数据,预测某一天的空气质量8 b' M7 t( d- }
使用LSTM模型+ `! q/ y1 d: C. s: Z$ S; k
结果:
: T* a' g( |2 z" i8 h0 a: {4 U3 kEpoch 49/50
" ?6 Z* _# F# f$ D0 L3 {0s - loss: 0.0144 - val_loss: 0.0133
! U4 C1 G3 h& Z/ p6 }Epoch 50/506 T+ h" o+ v8 _# s9 J
0s - loss: 0.0144 - val_loss: 0.0133. N7 G& h* |: r5 [& ^4 k7 R
& @7 O( ]1 {% ~* T: {0 x2 g/ k+ i5 g; O! t2 g% v
实验2:用前3天的天气数据,预测某一天的空气质量
+ F2 d* Z1 p4 |2 o+ A使用LSTM模型; F" x7 |- r3 S( }7 g
; u. C6 q2 ^2 t! G7 R) E% o& W
# \3 J+ H5 m& U结果:
7 h7 ]4 f ?4 Q2 o ^Epoch 49/50
- n0 Y0 U/ o# L/ l% T N0s - loss: 0.0147 - val_loss: 0.0149
6 Z! h4 Z' L- h. O' k, p8 s! pEpoch 50/502 R: n6 G6 F3 V8 C( M, ^
0s - loss: 0.0147 - val_loss: 0.0150
# p: ]; e. \$ r! y; Z8 \% M" f
2 v- R! ^+ c' Q4 y* j$ E4 X+ u1 \- m6 X8 [ i
实验3:用前一天的天气数据,预测某一天的空气质量- U7 \$ ?: O' e
使用普通的全连接模型 Dense()% p& q6 y& ~ B3 l. ^2 q' K
结果:
' O; f( _ k, l; k' u0 T' HEpoch 49/50
0 u4 Q2 i; a! `8 @% W3 V+ c6 x0s - loss: 0.0144 - val_loss: 0.01467 E) Z. |+ `3 A8 C! w- O' j
Epoch 50/509 g# |) ^& E6 U5 |9 G/ R" W$ k
0s - loss: 0.0148 - val_loss: 0.0151
% y `) b) b* s4 |; y% P* a4 d# ^3 x n; i7 {
) \ f3 w3 A* Z6 R% z0 h8 G实验4:用前三天的天气数据,预测某一天的空气质量
$ y! _ E2 _4 T/ Y, M使用普通的全连接模型 Dense()
+ _8 N" u5 M4 ^6 Z结果:6 ]2 n. H8 ^# V- s% U1 A, f6 _
Epoch 49/50
@: I+ e3 s* P) S0 ^0s - loss: 0.0150 - val_loss: 0.0165
' S3 u. ~5 \4 a3 ], l! rEpoch 50/50: e! O2 }/ U9 g9 R8 J
0s - loss: 0.0148 - val_loss: 0.01418 D" B' i3 v7 b6 ~1 X+ M
# _0 x6 M6 {+ C# s2 a: N$ R! o5 d! m! N) @7 I# p7 _* R
实验5:用前一天的天气数据,预测某一天的空气质量' \7 {. x, G/ Q
使用SimpleRNN P M. g7 b3 z; x3 M
Epoch 49/50
" H1 R+ _5 S s. l0 A6 C$ |0s - loss: 0.0160 - val_loss: 0.0140; ^ j; M1 D+ x, V0 E1 a5 |
Epoch 50/50# f+ F3 z$ r; ?2 o9 k0 [
0s - loss: 0.0147 - val_loss: 0.01503 l/ m0 }. s/ M5 x6 `6 D. I
! p3 ^4 D' ]+ _! R) _7 S& ]
% Z% Z2 j8 t; y0 V; Y' p1 q
实验6:用前三天的天气数据,预测某一天的空气质量% ]7 N i" H. `! m' {
使用SimpleRNN& T& O. K" q; w
Epoch 49/505 A5 ]8 G( ^6 q, Y$ i; a2 P
0s - loss: 0.0164 - val_loss: 0.0233! U9 q/ E- m6 B/ t
Epoch 50/50
, J0 w% {# F; d! [3 R0 Y1 q0s - loss: 0.0166 - val_loss: 0.0227
( V, h7 N8 ?, d- _9 _- {* JRNN和DNN的区别RNN中的循环是指一个序列当前的输出与前面的输出也有关系。也就是说,网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐层之间的节点不再是无连接的而是有连接的,并且隐层的输入不仅包括输入层的输出还包括上一时刻隐层的输出。
4 W- P }- _% v3 j. q' m" p+ } " K7 [" B$ ^! ]$ X
% N/ [) g/ {# k: B" _RNN和LSTM的区别
9 ?" _$ n% U5 ^# rLSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。
6 \( T8 v4 i5 C* |: |- P! Z% k. i" }" b. S1 o( ?
+ A* b7 I6 N/ b4 v) @但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。9 s' I# Z( z+ U. f7 v: \
: ~8 Z! p8 ?+ G& x) V# }$ \
# `3 r1 F+ z) O
请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员! C8 D8 e' B$ N2 S+ q! O
) q% Z$ l, ^% d/ c+ K
% q9 U; F; ^1 o |
zan
|