- 在线时间
- 514 小时
- 最后登录
- 2023-12-1
- 注册时间
- 2018-7-17
- 听众数
- 15
- 收听数
- 0
- 能力
- 0 分
- 体力
- 40344 点
- 威望
- 0 点
- 阅读权限
- 255
- 积分
- 12814
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1419
- 主题
- 1178
- 精华
- 0
- 分享
- 0
- 好友
- 15
TA的每日心情 | 开心 2023-7-31 10:17 |
|---|
签到天数: 198 天 [LV.7]常住居民III
- 自我介绍
- 数学中国浅夏
 |
使用LSTM预测时间序列数据/ Q" t% E4 Z/ p
& f* b \ _$ E% H& D
" y& l' f u( |: f6 w' H$ I文章目录
" |# r. n# r! f, l% D+ x背景
. @' g, B f$ c结论4 i K, c5 C- ^- N$ z) Z( c( s$ X1 O: ]
代码
N* r, o( I0 @1 W- ~0 Y实验结果) v' a! O( Z" Z2 S; o1 T
RNN和DNN的区别
! V6 M+ E) Z* r( f& `RNN和LSTM的区别
# G: P: I" Z1 Y5 [7 E: k" w背景
7 [8 p% K2 j8 l4 R复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验: G" G7 T! ]. z6 g% b
熟悉用LSTM模型训练* j% F0 c8 T% _( D e; g
验证将时序数据 转化为分类问题后,预测是否有效果 e7 I: V" D" r
对比SimpleRNN与LSTM模型 哪个效果最好?
+ q# q7 }: ~! _: l, E, i1 a验证LSTM相比于Dense()模型 是否有提升?9 G( t7 ]4 ?+ C
对比使用前3天的数据 和使用前1天的数据 哪个效果最好?- c {% r0 q' f' d" p5 O
结论
' t5 K5 M+ A, R ] X2 P4 I( @使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好
9 D( E& y/ F2 k. {使用LSTM的效果优于SimpleRNN
" }' M% ~1 {7 p" {# R) M+ c J代码
: F: _# s4 d6 H/ ffrom pandas import read_csv+ t2 Z# c1 L# V( F- o* D! `; O
from datetime import datetime$ d8 v/ ` P! ^3 T/ o/ a. N! i
import pandas as pd
( ~: W% O- C* m, y e- hfrom pandas import DataFrame: S2 a' [$ R% L' t
from sklearn.preprocessing import LabelEncoder,MinMaxScaler
" k7 j9 i F9 A7 ^6 dfrom sklearn.metrics import mean_squared_error4 `% S; ?0 r3 b. d; E5 U" N1 {8 `
from keras.models import Sequential
' k, x0 A) N' I2 f! g u/ q! cfrom keras.layers import Dense, Dropout& L0 `* d5 T9 |* S" Q
from keras.layers import LSTM
3 \1 b$ e% @! `; E& H) I: s; ]from keras.layers.recurrent import SimpleRNN
1 T9 {- m, G( ]( |, ^1 E7 Mfrom numpy import concatenate
' P# s! c3 y- E$ cfrom math import sqrt
; _2 n$ J# ~6 s. \6 i+ F
' L5 I+ ~# [' L( ~: ^1 P, I" q) l4 _- Q( x
& D/ P U8 U7 A& Z! G4 M
4 K3 T3 {3 N6 @. \& O
# load data0 g! I; }( u" q& p* I1 [
def parse(x):
1 j, Z, R' Z: Y1 q9 R8 f return datetime.strptime(x, '%Y %m %d %H')
1 G H" E9 H+ _; W0 b3 q
- M' ?! n4 l; ddef read_raw():
9 q9 J9 i, m3 [0 ^ dataset = pd.read_csv('raw.csv', parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)* X% t( ^/ ?; {' R. K) }8 Z
dataset.drop('No', axis=1, inplace=True)% ^# V a; a' ?2 `
# manually specify column names1 M. I$ W5 g* |" B- c- I
dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']1 j# W `+ r, I! `+ o0 d
dataset.index.name = 'date'$ z2 P4 _" m& n4 |" T, F
# mark all NA values with 0
: N) | M" K+ |5 P7 b dataset['pollution'].fillna(0, inplace=True)4 J. B! G' I0 Y4 n
# drop the first 24 hours
$ k# R+ b6 v" D" x9 ?8 k dataset = dataset[24:]( _. e( ~ g2 \) d
# summarize first 5 rows+ O2 }. s7 `2 l! ~
print(dataset.head(5)). _* z8 @! f6 z; G% z
# save to file
% Z X/ A$ f+ E( T dataset.to_csv('pollution.csv')
8 r# a' ?% K9 M' Z
6 R ~) o- ?7 c) x, X7 y8 ~9 ~: ^1 i5 B% k4 h+ a W+ V/ n- p
- M4 j3 ~* X8 ]: F
# _* _8 @4 b k0 F+ V" u% s/ g; ~# convert series to supervised learning
( A5 P( ?3 O) Tdef series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
( c% l/ _: x: } n_vars = 1 if type(data) is list else data.shape[1]0 ^9 A6 ]$ v4 Y: a6 \$ G" d" R
df = DataFrame(data)
8 ~5 y- e2 \6 F7 |, j. W cols, names = list(), list()
0 Y# n) a- h) ] # input sequence (t-n, ... t-1)
. t3 u% l/ {, j) \$ W9 P for i in range(n_in, 0, -1):* X0 y& d% S, I+ n
cols.append(df.shift(i))
7 s2 {( |, R! I& y$ ` names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]6 `3 F$ ^7 v+ x2 h% ?; f% b7 ]+ |" c* w
# forecast sequence (t, t+1, ... t+n)
% l1 x3 ~1 E j% M for i in range(0, n_out):
- H5 a* a) i) {- O& T cols.append(df.shift(-i))
6 k0 {- W2 ]$ }, S! s5 I* H/ {( U if i == 0:
- A) z# ~7 L: Y4 C, r+ d) N6 z names += [('var%d(t)' % (j+1)) for j in range(n_vars)]8 F/ Y; M5 \1 q9 v. c! W3 u
else:/ p$ g$ P8 b" W, [9 ]
names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]# g( j* \, L/ u: {4 \3 @9 _
# put it all together
8 Y2 k. p8 J( K- d; B0 m2 U& f agg = pd.concat(cols, axis=1)
$ l2 E* c6 ~: z% h9 b# P) N+ A agg.columns = names8 [# v6 e! W! S+ q1 w' W9 @
# drop rows with NaN values
5 S* \5 E! @& i. h, F ]$ g( E if dropnan:) D) D' v$ M6 ?; A
agg.dropna(inplace=True)7 k% |( i8 m0 A) F8 ?5 x
return agg' u% \9 A, R$ {% j
3 W: T" C" g* [9 g/ Y5 e# load dataset
F8 E1 f% u7 y/ G, R' ] Y$ P% e. ddataset = read_csv('pollution.csv', header=0, index_col=0)$ D! U; t7 ?! f4 O& t
values = dataset.values
% O6 O; z5 x9 J- b+ l" v# h( Y5 ~
' h' N' H3 M B. e! O$ K* u! Y4 l9 _+ ^+ J, f0 a7 x" b
# integer encode direction
# D8 y Q W3 L/ Rencoder = LabelEncoder()
7 S1 I* I3 R3 Q ~9 M& Z& \6 _5 |+ z! Qprint(values[:,4])
4 S# c* r/ _+ ? svalues[:,4] = encoder.fit_transform(values[:,4])
8 X1 y& H3 L$ j# ensure all data is float7 E4 u: a; D% Z1 A. S+ a$ \" n% D
values = values.astype('float32')2 U! T" g$ S6 f, L
# normalize features& z6 }( Y8 N+ K0 j
scaler = MinMaxScaler(feature_range=(0, 1))) I7 Q$ X& A( G5 p
scaled = scaler.fit_transform(values)
- b& L7 S' W; n+ R# frame as supervised learning
) U$ l& L$ q2 Oreframed = series_to_supervised(scaled, 1, 1)
, f: c+ _& h3 b7 s9 _#reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据% K3 ~( u3 m% {
print("columns:", reframed.columns)" n$ J2 I) L/ o0 w! c$ N6 D
# drop columns we don't want to predict. k7 r& _0 l! q1 h4 o
reframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据& E* r: t* E) g
#reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据: f- C2 `+ [- x
print(reframed.head())# t4 c5 K% P q$ W: t# j# U8 d# ]
print("new columns:", reframed.columns)/ h3 @; Q7 E3 g1 z
# split into train and test sets3 T2 ~4 l& E- c
values = reframed.values4 s Z2 x1 ^( R6 d0 G2 P$ Q
n_train_hours = 365 * 24
; e' s" P. _5 qtrain = values[:n_train_hours, :]- i; G+ ~( x w0 {* ]
test = values[n_train_hours:, :]3 z5 V0 v7 e7 D0 }
# split into input and outputs
6 O3 b0 [2 m4 B- q" @2 t% `train_X, train_y = train[:, :-1], train[:, -1]% l7 W, \. \ q+ o" {( A
test_X, test_y = test[:, :-1], test[:, -1]" m* }: b: \% d5 @8 R0 ~% s
# reshape input to be 3D [samples, timesteps, features]0 S# [ I$ r/ E" G0 u
#使用Dense()模型时不用变换
% \; L' I3 ^$ l+ ctrain_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))& C/ E; T6 R% B& E+ a% u3 W
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))$ H, K# K: u6 w6 e; f" ^ k3 F0 Q
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)* t! j- i" W8 U3 w; ? n1 A
# design network
6 M+ a6 {% g; _model = Sequential()# i! k% w0 D6 C. J7 b. w6 p
#model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))6 Y: C+ H( ?) d! j$ d
#model.add(Dense(50, activation='relu', input_dim = 8))' k* M7 k4 w5 j0 d( m e; L
model.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))/ X' d, {9 o1 k# _: Z0 ^5 K
model.add(Dense(1))
( ]7 b9 X( k& ~! a+ g0 H4 wmodel.compile(loss='mae', optimizer='adam')( H8 A2 P; c9 z( U# J3 [- g
# fit network
5 D" P7 d9 S/ `' u# V1 y% O( S$ Rhistory = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
5 s% N1 @- e- r# make a prediction
2 O1 N- f; Q& C7 Y' {+ fyhat = model.predict(test_X)5 ]; ~. |; l( }' U: d
print("yhat shape:", yhat.shape)0 H' o7 ]& w0 {' e- J' i
'''6 ~/ z+ \4 q, h+ \: K
计算在测试集上的均方差
( ?- c( O0 u X% e* B$ ~0 W! [test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
9 H! q9 e6 d, b% Nprint("test_X shape:", test_X.shape)
( T" ]5 Y7 R. r: m' t' }; I& p
6 Z, g+ X& J$ c o6 Q3 d) q* i* I& ]
# invert scaling for forecast
0 g! O! M9 F5 Cinv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)5 w! U# [2 d* ~, ^* {7 N
inv_yhat = scaler.inverse_transform(inv_yhat)+ F9 m7 {2 R& `. f3 D; P% `3 y) ^% l
inv_yhat = inv_yhat[:,0]0 \/ X) B' D" [$ i* k' q
# invert scaling for actual
; O1 J- i$ W0 ~" H6 Z- b; e% ytest_y = test_y.reshape((len(test_y), 1))" R. w* Z; k3 J0 U8 n+ j1 `
inv_y = concatenate((test_y, test_X[:, 1:]), axis=1): g# }' k. ]5 a, {4 I/ I4 v$ K
print("inv_y:", inv_y[:10])
& D- m6 N7 ]8 e) W) q& ?- q8 @print("inv_y shape:", inv_y.shape)+ Z4 O; D% f/ E- R
( N+ l* W; ~6 e) G6 |
7 B' _; p0 z7 C8 z a8 q; @. jinv_y = scaler.inverse_transform(inv_y)
3 [& X& K- G3 H* H5 g$ P! K; Sprint(inv_y, "*"*30)5 T5 [. G: t/ g; P+ E/ R% ^. _6 N
0 u# ^, W2 X( \) g& H( {( ]9 b) L6 o! e' z7 C, R% H
inv_y = inv_y[:,0]. T$ @) F3 N& b' N- S
# calculate RMSE( Z$ [( w4 X- N2 G
rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
: h0 ~$ Z: t* I6 b' tprint(inv_y[:100], inv_yhat[:100])- Y+ T6 k. b! y: \0 n3 S- y
print('Test RMSE: %.3f' % rmse), L' T9 e! s2 P1 a" `
& L; w3 |% ^( a- U4 \5 a
8 I4 Q$ t V5 D
'''2 v6 _- q( C* Y0 ?& b6 ]& D! r
实验结果9 z& L# b2 `* S5 R6 j
实验1:用前一天的天气数据,预测某一天的空气质量
& G' J& C. y7 r使用LSTM模型
) x0 W+ M0 q" U6 D结果:
b0 r C0 K9 z3 e6 k# _5 xEpoch 49/50
9 l1 Z: f4 t! Q0s - loss: 0.0144 - val_loss: 0.0133; h9 b7 V7 W- v0 Q7 O0 T% i
Epoch 50/50' H7 R# Y ]6 o# i9 m
0s - loss: 0.0144 - val_loss: 0.0133
$ V |8 ? a) M+ A. I. X! F
* c8 g; h- C. y4 {9 A
$ A8 V) q6 K; l' x3 P实验2:用前3天的天气数据,预测某一天的空气质量
# o0 H @5 ~* i4 q使用LSTM模型$ a) b D& K6 i2 A
" _. q' d" X% [) G4 b5 A) u2 \( {# R. ~+ k
结果:5 y3 n- r: u" S) z& G* f" k* e3 S
Epoch 49/50
# w& P' y( v: ?& {0 I/ M" q/ `0s - loss: 0.0147 - val_loss: 0.0149 x& {( g* \4 B/ @% b7 G
Epoch 50/50
+ v5 O: V+ p" K5 \; w5 n0s - loss: 0.0147 - val_loss: 0.0150
- C$ ]* v3 a0 \9 F @! H2 `3 D
$ b# l1 U2 m7 y4 S9 ^7 O$ ^ \6 U4 P0 C% N: y
实验3:用前一天的天气数据,预测某一天的空气质量
3 E3 M4 O* x A8 O0 F使用普通的全连接模型 Dense()& ]0 R. {$ ^( I5 x9 g2 {7 f ~8 k
结果: _- \5 q, x6 b& s I* _ L, N
Epoch 49/50* b( ^! B$ S: I* ]+ a
0s - loss: 0.0144 - val_loss: 0.0146, {* {0 Y! f8 }% w
Epoch 50/50
( o, c* O5 D9 ?$ q' R3 q0s - loss: 0.0148 - val_loss: 0.0151; H$ K8 z2 g2 p" |# E4 L
+ y# t% F# s& L9 A0 X9 V
+ K1 W, `# g9 l p
实验4:用前三天的天气数据,预测某一天的空气质量+ I B! Z/ V1 S5 }. g |7 v8 n
使用普通的全连接模型 Dense()
* Y* t: \1 Y# S( l结果:, l& F% o$ r. k& ~. Y( P. Q
Epoch 49/50: U: }! W8 ?" J" |7 F( [+ {% |! S4 T" [
0s - loss: 0.0150 - val_loss: 0.0165% ~" F: a+ k3 _4 r, x( L+ V
Epoch 50/50
+ w$ I z- @9 B0s - loss: 0.0148 - val_loss: 0.0141
( n k' ?' ?7 t# u) j r* y5 |. \1 T% @0 p2 C6 @% N
7 `* a/ L- j: I z
实验5:用前一天的天气数据,预测某一天的空气质量* ?4 i& o2 e/ q" n6 V1 ~! f
使用SimpleRNN8 d5 i1 c/ y/ G8 x# J# B/ a
Epoch 49/50
& y9 ?; o7 B, J; g$ P0s - loss: 0.0160 - val_loss: 0.0140
( H& J z" B' h& ?. ~Epoch 50/50+ S$ ? f# z9 f9 `
0s - loss: 0.0147 - val_loss: 0.0150
6 j7 \; g/ F- a6 @
0 i5 X" F5 C/ V8 r2 a! i
) L7 z: o- n/ [% S实验6:用前三天的天气数据,预测某一天的空气质量
; W; H/ J" f/ d6 A/ {0 w Y使用SimpleRNN
6 B Z! F; H" ~. B& j* z' yEpoch 49/50
, c& ]$ r& w0 z# G0s - loss: 0.0164 - val_loss: 0.0233
# {6 r2 p$ G% Z/ d: G! W0 UEpoch 50/50
, z. ^: A% j4 n7 _* o; Y' `0s - loss: 0.0166 - val_loss: 0.02276 S5 [7 d2 c- c3 L2 d
RNN和DNN的区别RNN中的循环是指一个序列当前的输出与前面的输出也有关系。也就是说,网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐层之间的节点不再是无连接的而是有连接的,并且隐层的输入不仅包括输入层的输出还包括上一时刻隐层的输出。
4 W" `0 c E4 G( N * X& N; i( g, R6 t% p$ {6 F
( I+ T! v% X( N& k3 bRNN和LSTM的区别
! a# S- g! _! w3 e4 PLSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。
; [6 G2 U& a, {: m% U2 U; _( b9 a0 T h% _7 b
4 y+ d4 z; T! ~" |; F8 K9 L但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。
$ r9 c, ]3 T1 W6 Y6 K1 N& W 4 A0 M4 N* s( s! J7 }; g1 `, O( E3 n
6 B8 i P0 I, p7 M' }+ d请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员
& {, l: q# U7 T7 N! a$ ^9 [6 d- L8 k
- l1 e1 K* x. \) V+ E# n6 X# s7 Q: | c, c0 X7 m: m5 O& c# m
|
zan
|