- 在线时间
- 514 小时
- 最后登录
- 2023-12-1
- 注册时间
- 2018-7-17
- 听众数
- 15
- 收听数
- 0
- 能力
- 0 分
- 体力
- 40301 点
- 威望
- 0 点
- 阅读权限
- 255
- 积分
- 12801
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1419
- 主题
- 1178
- 精华
- 0
- 分享
- 0
- 好友
- 15
TA的每日心情 | 开心 2023-7-31 10:17 |
|---|
签到天数: 198 天 [LV.7]常住居民III
- 自我介绍
- 数学中国浅夏
 |
使用LSTM预测时间序列数据$ F- y7 S' y8 x5 j+ g
1 G% Y4 e0 e0 }
4 Q4 a- q# p A, X
文章目录5 H& e# g n7 O+ O
背景5 S( {& t) m- `6 F1 G
结论
6 k1 B1 `+ r* z, G3 }; E代码
" k: F$ {* q3 w( _# `实验结果
3 |4 u9 u) Z0 hRNN和DNN的区别! H/ C1 M$ Q7 N( g$ _ s5 t: N
RNN和LSTM的区别
& h7 k2 u/ V/ b, r& C9 l背景
& ?: y, |# I. P* H复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验, U) W0 n1 G! }9 N7 r
熟悉用LSTM模型训练% n; R# A5 }/ L. E
验证将时序数据 转化为分类问题后,预测是否有效果
3 z+ r o. {0 v7 H! @, p3 x对比SimpleRNN与LSTM模型 哪个效果最好?
! H# @$ y9 V7 |: K% E验证LSTM相比于Dense()模型 是否有提升?
8 p4 x7 Z7 M3 p+ U对比使用前3天的数据 和使用前1天的数据 哪个效果最好?1 j, q" c, C8 \) F7 b! O4 i% g
结论) e$ R0 w3 E- h0 Y+ D
使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好1 m. V) }$ S$ h1 G4 A+ n, H" j4 W5 _
使用LSTM的效果优于SimpleRNN
+ U' l8 o0 d$ w( `8 }4 |1 y代码
' f2 ]1 B2 U1 E3 }8 |from pandas import read_csv
, r! s& ^$ \9 X+ R7 r; d& Mfrom datetime import datetime) ^; s8 z# W) \& E- `: o+ F
import pandas as pd. o3 q5 s" z0 {+ L$ z( p' c( Z! ?
from pandas import DataFrame
9 A( r9 l. I/ a1 b' `+ y+ Pfrom sklearn.preprocessing import LabelEncoder,MinMaxScaler2 ^, D3 a2 {. f' _
from sklearn.metrics import mean_squared_error% A0 M4 i' v# j) c6 {
from keras.models import Sequential7 |$ k: H4 X" p3 @% |$ ~+ x& q
from keras.layers import Dense, Dropout- o& P9 }4 O: @" ^) {/ s6 u
from keras.layers import LSTM
- Q4 S; ~' ?4 a% ufrom keras.layers.recurrent import SimpleRNN! B1 @& U: r0 g* J
from numpy import concatenate/ B& \9 ?: x9 K/ u
from math import sqrt" {1 A' c6 I1 l; ?4 L# P5 p& w
" A4 a, e% i) o' o( O8 J) }9 W
% h, h& |- O7 X; j2 P9 f! v
6 r0 n: n ~& I4 T
# load data
$ h- i) Z: u8 C( y/ M7 Ydef parse(x):& L8 c; w! |/ g. @; q& u
return datetime.strptime(x, '%Y %m %d %H')& V( G8 R+ j% p5 P9 i) T8 O4 Y+ m
$ J5 j6 j: `1 ], qdef read_raw():9 U2 k C+ O% |" d/ p
dataset = pd.read_csv('raw.csv', parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)
; l [* X' R4 v9 K! [3 M5 c& \* Q dataset.drop('No', axis=1, inplace=True)2 f, Z1 {& ^7 H
# manually specify column names
4 M' t, h. `7 D( d9 J$ f) Z dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']
1 G1 I: `: p1 C# z dataset.index.name = 'date'0 a! c- O0 i n: `$ }7 a4 O' ~
# mark all NA values with 0
* F+ `5 H& K/ `$ K9 o1 C+ Q% Z dataset['pollution'].fillna(0, inplace=True). F# g6 ?) V- F- A0 l
# drop the first 24 hours6 I' r& e! E# @
dataset = dataset[24:]
0 D3 ~+ v( c+ w# h # summarize first 5 rows
8 z( ^9 | y7 t4 b1 ~% {, ^ print(dataset.head(5))+ X- h* [, U: I! G& S
# save to file# W, O, \. \' G9 a6 ^/ h+ q8 L
dataset.to_csv('pollution.csv')% q/ o9 X c0 D( S
7 Z- Q6 g5 n0 G w
) ^+ ?7 D- h3 o* g
7 @4 y p. l% k$ U6 h8 z- P. L. _" s, z; N- h
# convert series to supervised learning
( `) w3 K: [) S' @1 Rdef series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
5 N; z! y: { F8 c' ~* K n_vars = 1 if type(data) is list else data.shape[1]0 P* k* t2 A% m" u* G4 \; F
df = DataFrame(data)# `, L3 Q& p) ?$ W+ y6 o: F: N
cols, names = list(), list()
$ G+ C) n+ V* _# q; ^ # input sequence (t-n, ... t-1)
: A- a; I5 d" F- n% S; N% b) c- d for i in range(n_in, 0, -1):6 P/ M. p/ m9 [( `
cols.append(df.shift(i))* M4 F0 U5 F2 T8 ]8 d$ B- p
names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
9 i9 J: o p, C. H( H# |& L # forecast sequence (t, t+1, ... t+n)( c# e* F. Y7 @) b! T# \% b
for i in range(0, n_out):
" V, v7 R8 c4 s# `$ L cols.append(df.shift(-i))
* ~" @8 g9 o3 U' l0 {* K if i == 0:/ \2 p3 _, _; g; |/ Y
names += [('var%d(t)' % (j+1)) for j in range(n_vars)]3 C" x8 x+ E3 h: q
else:, N+ q! U- c' N( f" \: l
names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]: G R1 A' d% A6 L7 k; v
# put it all together+ _9 q. a4 D: ?$ O l4 {+ e
agg = pd.concat(cols, axis=1)
4 H8 M7 Y! A6 v* t" w) a& r7 p$ G agg.columns = names- {3 C3 l6 ~) I( _, o' h4 ^
# drop rows with NaN values
# J H1 [& Y; p1 q) m if dropnan:
* h o( b8 K, N# A s2 L agg.dropna(inplace=True)
8 O& g/ u& c v: U5 s! R5 Z: a return agg
: {1 N5 O' X: B5 O, l- a' Y
' x: R) g$ @. G& A# I* U; _8 u& Q# load dataset
+ o# r( O! O* Y; ?( M9 Udataset = read_csv('pollution.csv', header=0, index_col=0)2 a% ]" i6 K& y: C' b) ~2 a
values = dataset.values9 {$ T& W$ [1 y; {$ p/ s
% u1 n4 c, p" }1 v. x- k3 d0 `% ^9 \1 ~% P9 I7 p0 f* y( a
# integer encode direction
L. F. ~$ f( X' Q- k! [7 [encoder = LabelEncoder()1 w8 `; {3 s& g0 a# }* ^
print(values[:,4])
- Y% R8 z, }9 s" V& M1 Zvalues[:,4] = encoder.fit_transform(values[:,4])
1 Y: v L* |( C& n3 _ v& j3 k# ensure all data is float6 c) M" O9 e/ c! j" P; h) w
values = values.astype('float32')
8 Z" r* Q' Q6 ]# b" o. F) y. d# normalize features0 M5 A( A* Y* g7 R: s
scaler = MinMaxScaler(feature_range=(0, 1))
* `. `4 q! O4 R) Z2 vscaled = scaler.fit_transform(values). B) J5 u; B) o, ^& i# H
# frame as supervised learning$ O$ G! P _; B* ^" ?3 c
reframed = series_to_supervised(scaled, 1, 1)
* N" `; E. g! T/ D#reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据
3 ~. R: G; |7 z5 e% Z# t1 Vprint("columns:", reframed.columns)
0 L# Y& @" p# W" Q. d% A* T# drop columns we don't want to predict
Z. O6 A! [: k& Breframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据
$ E" v3 l3 g2 f, W. ?% P5 {#reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据 d, S# [# b0 S5 M' k5 z% X
print(reframed.head())
4 q% r5 S6 X6 ^! z9 V4 aprint("new columns:", reframed.columns)
6 X3 }$ g( ^9 m& M5 N8 c/ M# split into train and test sets
$ | g8 V9 U) b+ H+ Jvalues = reframed.values
0 F* G0 q1 }. O% N" V6 c) F; g" ~ Zn_train_hours = 365 * 24( H$ G7 Q6 X/ K4 k/ X
train = values[:n_train_hours, :]
9 T2 Y, o8 l. Vtest = values[n_train_hours:, :]
! l: Q- \8 G( [% H! W! l/ W' C# split into input and outputs
6 i. E) a* Z5 Ztrain_X, train_y = train[:, :-1], train[:, -1]1 C$ u4 O# J8 P+ H" _/ G
test_X, test_y = test[:, :-1], test[:, -1]
0 X/ ?. u6 N" |" p% a+ t% _7 ]9 T# reshape input to be 3D [samples, timesteps, features]; [7 l3 \7 L: W6 B# m7 \: z/ r
#使用Dense()模型时不用变换
4 o2 z' p$ C R+ a: N( Ktrain_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
a! t8 D8 T0 C- X- o' D2 F5 Qtest_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))$ [6 X5 a8 P/ `( O
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
, J5 X5 g$ _) E# design network. F# }( H; N& K. T; V# P- a; O* g
model = Sequential()
+ ?3 {: z- U5 [& m( F, w: a7 e#model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
$ C3 m- L; h6 @0 X0 R#model.add(Dense(50, activation='relu', input_dim = 8))
% M8 ]* p A2 x! ^$ l4 Jmodel.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))
- h. M$ H4 V- @7 W3 D6 U/ S0 bmodel.add(Dense(1))
4 Y3 z; F( A) C" t/ E0 Z) w" \, i* Wmodel.compile(loss='mae', optimizer='adam'), T, h5 b# A. Y- _5 [, H+ K
# fit network6 E0 g: B4 }+ l
history = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
# Z) h, m: ?3 ^6 H# make a prediction7 A: C3 _0 M0 y
yhat = model.predict(test_X)
" ]& j. a! I) }print("yhat shape:", yhat.shape)
m. n+ R; M+ |; e- d'''
: b2 x- I5 R! C3 a {计算在测试集上的均方差: L- M3 _9 ~) ~
test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
: Q) ]2 R; D) z8 }% u. L- ^print("test_X shape:", test_X.shape)9 a7 _; J. k0 e! i# x% n$ `
! {- h3 `1 v4 g. X3 {! q" S# `. P
5 v$ {* [% V" A- X- \+ m# invert scaling for forecast
, B$ J1 C5 P1 }3 O3 H' v4 minv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)
3 K9 |4 U( n ^# ^inv_yhat = scaler.inverse_transform(inv_yhat)9 u- @! @4 O, M
inv_yhat = inv_yhat[:,0]
- g/ t7 I. L( L* r8 U1 X" [- `# invert scaling for actual
, Z4 v, h4 R( L. a+ q& C) [' btest_y = test_y.reshape((len(test_y), 1))
- u* }8 O4 j: A/ P7 q) l! U8 pinv_y = concatenate((test_y, test_X[:, 1:]), axis=1)* i1 S9 p. j' L8 E
print("inv_y:", inv_y[:10])
$ l" Y4 N u* zprint("inv_y shape:", inv_y.shape)
& x4 E& J$ h+ v4 J- ^) {; B9 D- o; ^- d% \6 }
4 ^; d' O8 n5 L, q
inv_y = scaler.inverse_transform(inv_y)
1 H" H! d# a5 X! s, Z2 b! }5 @print(inv_y, "*"*30)
' R% U7 U, T& i0 F) Z$ }0 Y! y" [% t( h8 G, b Z( T
; g) Q9 `8 B6 j1 \+ v9 @inv_y = inv_y[:,0]
2 H6 E$ a( ~# f2 o6 j2 J. w6 k# calculate RMSE0 }2 B0 z1 i6 d' s& f
rmse = sqrt(mean_squared_error(inv_y, inv_yhat)): S/ |# {3 k; D! y- C; \
print(inv_y[:100], inv_yhat[:100])7 N) m$ e* k3 J/ _! e: w4 c" P M, {
print('Test RMSE: %.3f' % rmse) L2 K# h4 Z' d& \. ~) j2 r
( }% s: c H/ F; J
7 D1 Z. \- f0 T% Y8 Y7 L
'''
; Q) d$ F& C7 k8 B. k C实验结果! ]" Q& i% m* ]3 q
实验1:用前一天的天气数据,预测某一天的空气质量
6 Y# r. I& C; b- @$ j' ^使用LSTM模型
8 K& |" g3 R5 A8 n结果:1 B' G' }- L' A
Epoch 49/50. ~. n( f% p5 e) K. P0 o
0s - loss: 0.0144 - val_loss: 0.0133) |1 ~, J) L" B1 `, q
Epoch 50/508 @5 |& V! K8 Z8 i! W1 U' o6 b
0s - loss: 0.0144 - val_loss: 0.0133
9 ^( s: k0 G4 q1 Z2 q( }1 j) a0 |9 ?9 f7 d9 F1 @
2 X; N5 N2 Z; a实验2:用前3天的天气数据,预测某一天的空气质量
8 N+ c/ C# C1 v2 D8 w* u& B使用LSTM模型& R* U1 ~. i" o% ?2 N, U1 V
9 C* f: l ]9 i0 ~& V
1 j# D) p) H0 D2 Z; h结果:
K* b6 u2 w) C: j7 \# lEpoch 49/50" ^1 l0 {: a1 m! g! x# Z
0s - loss: 0.0147 - val_loss: 0.0149
9 F" |0 v6 y& KEpoch 50/508 C) |. F! l, |6 B- B" W% R
0s - loss: 0.0147 - val_loss: 0.0150
' r% Q* U! A; R1 b& p K. M% V0 h' [' Z/ T
/ O: b% P& A8 r实验3:用前一天的天气数据,预测某一天的空气质量
& o, A) t) K+ s使用普通的全连接模型 Dense()$ k, w% M6 F0 f% m% {7 i B. T8 D
结果:
2 G5 h9 z( H1 P3 o1 b6 t, \Epoch 49/504 D: t) k6 H: g
0s - loss: 0.0144 - val_loss: 0.0146
. k T+ n9 C# E" V( i. Y! ZEpoch 50/50% X1 I! E6 ?4 ~9 f7 E: v4 e# D
0s - loss: 0.0148 - val_loss: 0.0151) T- J9 J, o* K& `5 T
9 }/ v: J$ T. q3 t
+ G1 T4 l" r+ g& e0 o3 s4 b1 d
实验4:用前三天的天气数据,预测某一天的空气质量- Q! o7 y( D1 s" ^4 k
使用普通的全连接模型 Dense()' d2 W; z8 ?! I
结果:
$ I2 y0 t) e" @. p2 s* o9 s1 qEpoch 49/500 r' j; ]0 I6 d+ r
0s - loss: 0.0150 - val_loss: 0.0165) z( p7 {$ a' S4 ?2 @- m9 @
Epoch 50/50; n/ b; X- G$ K4 Q) W/ ~
0s - loss: 0.0148 - val_loss: 0.0141
* O1 O, l5 B8 p' Y7 b0 K9 g3 _/ t, ?# R g" t
" i& s2 E3 K7 e: \3 r4 M- k9 _实验5:用前一天的天气数据,预测某一天的空气质量
+ s @1 G" j7 d+ b使用SimpleRNN
0 }- m# \: v7 a( ^$ e+ \+ A3 HEpoch 49/50
3 }5 A0 A+ x: f \! O0s - loss: 0.0160 - val_loss: 0.0140. D7 N% |& r' k. H2 Z# J# H
Epoch 50/50
" g9 _2 {, `1 [' |9 Y0s - loss: 0.0147 - val_loss: 0.0150( A% G d n4 J: c; d
( `3 l$ C) }9 _$ G1 V8 I4 d
z5 n0 [! [3 m实验6:用前三天的天气数据,预测某一天的空气质量
7 [4 a0 c+ s; V使用SimpleRNN7 ]7 M( B' h! d. z! f
Epoch 49/50
, X3 R. u7 Q/ O% u# b( F0s - loss: 0.0164 - val_loss: 0.0233. @1 ^2 [" r6 z( F8 ~" c* I$ F
Epoch 50/504 H; ]% K4 [: V7 G* Q; D! z
0s - loss: 0.0166 - val_loss: 0.0227- m, _3 f* F1 t9 u
RNN和DNN的区别RNN中的循环是指一个序列当前的输出与前面的输出也有关系。也就是说,网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐层之间的节点不再是无连接的而是有连接的,并且隐层的输入不仅包括输入层的输出还包括上一时刻隐层的输出。
3 s4 C2 M" Z5 O& K![]()
- x& U* A5 l* v- l }% t' s1 k0 t, Y3 E: P6 F3 [- r, f
RNN和LSTM的区别5 E0 e' |' O) U$ U$ A' `$ c# h3 d% N( V) s
LSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。7 o; @: y/ q( T& v- s! |5 G
6 Y7 H+ M ?1 n5 K* j
6 }9 O" b7 f5 G但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。9 w$ D; T3 P: Y! s
: H5 T3 M+ J( {+ |: Z% Q: j+ `
, f5 o% e) h7 P& o7 B& F' p- ?
请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员! A& y1 ~8 v1 B2 O/ x$ W! ^8 V
) ]/ I& D- i9 v# R+ D- F
8 G$ ~0 P/ i$ h; j3 u
|
zan
|