- 在线时间
- 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预测时间序列数据4 o$ H2 i, }, L( Q4 T2 U
; n$ @' W3 \: @) j* |4 j
0 v! w& n* Q& }! ?. u文章目录$ w& k+ w$ n+ R
背景
L. C* l8 u4 [5 v结论9 d0 h' s# {# G) u/ n* q
代码8 t0 d$ e- y1 K8 i
实验结果/ o7 m+ q. X8 B
RNN和DNN的区别
7 t$ Q) k* b# L: iRNN和LSTM的区别& f0 ^ K, x% V; r& o% r
背景) A! l' e+ y# Y k7 G* K* h
复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验' C E. ]! h) ]0 r4 I# Y ~
熟悉用LSTM模型训练8 h; z' ?6 g: z! t: e
验证将时序数据 转化为分类问题后,预测是否有效果( s9 J7 F5 |( b9 r) A$ C2 W# Y
对比SimpleRNN与LSTM模型 哪个效果最好?$ W G5 k. \! R+ C& ?0 x. C
验证LSTM相比于Dense()模型 是否有提升?
1 h& b" Y' w. f' i% j1 Y$ c% F对比使用前3天的数据 和使用前1天的数据 哪个效果最好?
# Q" D' s! R. c4 Z结论) v$ ^$ Q X0 {$ J% @6 O
使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好
3 j4 ]# f; n0 D* K; O使用LSTM的效果优于SimpleRNN
& l8 _! ]; m3 q9 V8 H: [ p8 X代码+ [; z4 a" q" W, M" H* H6 Y
from pandas import read_csv/ B# f; R, d" N0 M4 [4 f& {) n& |. \
from datetime import datetime7 ^3 j9 ~4 x1 w& ^* @( u
import pandas as pd% }8 E1 m ~6 @( [0 L+ N
from pandas import DataFrame6 j$ }* ]$ h; y6 a( G0 a7 G5 Q* K
from sklearn.preprocessing import LabelEncoder,MinMaxScaler
# w$ W5 l7 Z! k* }* G9 S. lfrom sklearn.metrics import mean_squared_error
2 `& ]6 W4 t, |, nfrom keras.models import Sequential
2 k2 X8 ]7 `; Q, h% Nfrom keras.layers import Dense, Dropout
; H6 d( P8 C6 ]# ~! P) u1 Q( Y: ?from keras.layers import LSTM
0 o/ p7 D% n5 T: ~# r( |# Lfrom keras.layers.recurrent import SimpleRNN
8 C) N7 |& p |, o4 C! Ffrom numpy import concatenate
5 e. x! }4 G/ w% {9 G2 I1 zfrom math import sqrt
& T# m5 q0 e+ T+ V; V2 b$ {
7 V2 T$ \: j) N$ E" \* a' w9 h/ ^" x0 P. U3 P7 u7 y6 R
. Y, a* X& f; w* k' \
! x1 V+ _0 H$ }: z% V# load data
( U- z. q2 b- u, t! ~def parse(x):
" Z; S0 P$ @& c0 x return datetime.strptime(x, '%Y %m %d %H')! ^, w' h7 }: x5 M8 L
+ s" _% ^. ]! {% q. ~8 x) v
def read_raw():
* w9 y7 b% H0 Z5 ]/ W- { dataset = pd.read_csv('raw.csv', parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse). m) W* _4 ]. h" A5 b% u- F
dataset.drop('No', axis=1, inplace=True)
" j. t1 a% X+ N4 F2 W # manually specify column names
. [9 f, V$ `5 s& O c& n dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain'], ~7 o! [ V: Y* p0 B- N
dataset.index.name = 'date'
6 s, I, v$ i! M, C # mark all NA values with 0
0 q# U- O0 {3 D* y4 i; `! M: r& t dataset['pollution'].fillna(0, inplace=True)
. @, p# B8 u# Q7 w/ n: O8 h # drop the first 24 hours& R0 U; U; I# T0 o o- x. P) E5 E' F
dataset = dataset[24:]
, z1 G5 q w- v # summarize first 5 rows
5 J* \2 |% c4 K& o) P print(dataset.head(5))
2 m3 h" W' S, A # save to file' f+ u- x& t. L
dataset.to_csv('pollution.csv')- n* \4 |0 a% c' {% l
2 O. O9 X1 M w; | \
) f+ M6 k2 w& R, U7 Y4 O3 i4 E/ I9 @* {
# j1 k) Z3 a A
# convert series to supervised learning
3 d# l$ I* D8 y' n$ k1 odef series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
: U) t, V0 d( i- w0 b* g- i n_vars = 1 if type(data) is list else data.shape[1]
1 }1 K! S1 Z; R1 I- K$ U df = DataFrame(data)" v- G2 [6 ]3 L
cols, names = list(), list()" T9 ?) ?' ^8 a7 Q- T
# input sequence (t-n, ... t-1)
5 `" E0 R0 L; ^/ H) T for i in range(n_in, 0, -1):
" |2 X& H; C% a1 V cols.append(df.shift(i))
1 k! s! Y3 K7 }/ F) V+ a names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
B6 r" U, o* s8 C I5 F2 X # forecast sequence (t, t+1, ... t+n)
! o' i. Q0 x, {8 w, j# O, S7 I0 |+ I for i in range(0, n_out):) q. a% [' U% \! Z3 y: N; D" m
cols.append(df.shift(-i))! H+ g4 }# ?1 i
if i == 0:
. I; V8 O# }- p1 q names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
2 A' H; {8 |8 P2 K4 E else:
7 y2 t1 X# u1 ~0 X" k, a names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]$ d4 V3 ]; l$ y" a1 Q/ l
# put it all together
/ |+ b" L" p8 e" U agg = pd.concat(cols, axis=1): F9 f' `0 g' j1 @
agg.columns = names% {" p( A% T& u \
# drop rows with NaN values: ], e3 q( V) V( @! l
if dropnan:2 a' j9 S: M% s) `0 N9 ?" y \
agg.dropna(inplace=True)% S) B# w8 w8 A7 V9 j6 A
return agg
2 y! i! Q8 R! m& F & e" p0 Y. y- Z. d- v% Y. ~
# load dataset+ z( b7 j9 ~9 z
dataset = read_csv('pollution.csv', header=0, index_col=0)1 |! z& }9 {/ I9 v! j) |/ d. W1 @' L
values = dataset.values' M6 e+ ?* O3 b1 c' @
+ W' I$ \2 [) e2 _: v. G- O
; Z6 U$ h$ C8 r) Q# integer encode direction
7 S, \' o) F) J# q1 x, k# Sencoder = LabelEncoder()% B; {9 L; X( u4 t- P7 c
print(values[:,4])
/ Y2 \4 G9 r7 J( ]8 I; S b3 h$ \1 _+ }values[:,4] = encoder.fit_transform(values[:,4])
$ F9 p" }& o! a4 ]( u9 y+ _# ensure all data is float
7 k- q1 b9 Y8 P5 `; evalues = values.astype('float32')' Y/ p4 B- p2 ?# F4 z0 L2 P
# normalize features; W6 X% r* G* v
scaler = MinMaxScaler(feature_range=(0, 1))/ p# z7 }+ ], q1 t5 L+ ]4 c2 X2 X
scaled = scaler.fit_transform(values)
' B8 X1 w B5 u$ }+ ^- f# frame as supervised learning
_) K- K5 Q. b Y4 y2 R8 yreframed = series_to_supervised(scaled, 1, 1) . s+ a: O" I! S4 \
#reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据- z; X! O& h# i4 h& w
print("columns:", reframed.columns)& [ |( ~" p% H% Z) `3 x) M
# drop columns we don't want to predict2 Q9 l s# o4 p2 x4 W% g
reframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据
3 p# x2 F, O9 b+ s#reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据2 S4 R. k) i: i# T
print(reframed.head())" a1 e, D: \; n) G& F- y8 V7 q& d
print("new columns:", reframed.columns)
; P8 F0 i' l. A) M+ u' r# split into train and test sets' T+ [* Q* e$ b) @2 {
values = reframed.values7 m T$ ^/ ^! `0 n6 `
n_train_hours = 365 * 24 h0 p$ I7 L, Z& @3 D/ v: C
train = values[:n_train_hours, :]3 x; t0 V# e+ `1 }) d2 o2 I
test = values[n_train_hours:, :]
4 n- ^, z/ G/ {6 Y5 s, g' ~$ l# O# split into input and outputs
: B3 K# }( `9 G! C- [- Ztrain_X, train_y = train[:, :-1], train[:, -1]- h e+ `; s2 E! A* d ?$ }
test_X, test_y = test[:, :-1], test[:, -1]$ ~5 y: y. K) Q7 _
# reshape input to be 3D [samples, timesteps, features]
+ S6 ` T( P$ x* B" y. ^# S#使用Dense()模型时不用变换
+ |- a6 u2 o4 @; w/ Z4 i* s: v$ r& h3 `train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))6 b3 |5 T* m T9 K7 _
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))- @- r+ }9 y: G8 y5 m7 k% d
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
A" m5 u1 ~ i d1 k' p# design network
+ X3 M! x! q3 e' s: bmodel = Sequential()* v; F1 a& Z# u, S# A0 A* J
#model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
* L2 y( }5 T0 s0 G! @#model.add(Dense(50, activation='relu', input_dim = 8))
. H2 s. e! E# G1 `! X5 c3 x- ]model.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))
, I0 f! Y1 [% Qmodel.add(Dense(1))
^+ u! i' e/ v! {model.compile(loss='mae', optimizer='adam')
9 r! Y6 ]8 x$ ?2 \" T7 N- q( x$ A1 B: t# fit network
3 ~8 \- c5 r0 M7 Q: ^5 M n" Ahistory = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)6 Z# |. _6 P/ C. k/ u1 A! h
# make a prediction$ G* [( D1 c& @ G# s: a
yhat = model.predict(test_X)! W; I1 l8 X: C% ~/ ^" z
print("yhat shape:", yhat.shape): }' q5 d9 k; X3 c# i
'''6 ?1 m2 \4 q; ^( n' W/ C- P
计算在测试集上的均方差
! J: T' D- j8 m/ _test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
1 b+ V9 X0 R1 G- t3 g, V& P; bprint("test_X shape:", test_X.shape)
/ Z8 c0 u7 O' b* N
! T4 s; G G9 s4 m! Z% {0 D& f2 b* C0 @
# invert scaling for forecast0 H0 c# D; U9 j% L2 j
inv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)
1 f r/ N1 Q0 k' g3 vinv_yhat = scaler.inverse_transform(inv_yhat)
& R/ N) l* a6 g4 ^" t* s9 d% T; oinv_yhat = inv_yhat[:,0]
/ }; V- _ c6 q, i5 [. f# invert scaling for actual
* g9 j) c) U, mtest_y = test_y.reshape((len(test_y), 1))& v( s+ A& L; _
inv_y = concatenate((test_y, test_X[:, 1:]), axis=1), F. z- T" D5 R9 Y( O7 i1 k7 ~
print("inv_y:", inv_y[:10])
+ t# G8 C1 |2 r; P( ?% B6 ~print("inv_y shape:", inv_y.shape)
2 ?* R7 n. B8 `3 P. q3 a$ ^# j: X5 \
, b) a5 h# u$ S# C; Einv_y = scaler.inverse_transform(inv_y)& U" `' ~7 f9 z% n
print(inv_y, "*"*30)- t; m) ~2 W( S c
$ ~' K/ o# U& l
6 {7 f$ R7 h+ U! |# N9 Uinv_y = inv_y[:,0]9 ^) D2 P0 f$ t1 `/ r, C( q% y1 s
# calculate RMSE
) T" v. t+ w) ]1 O6 G. qrmse = sqrt(mean_squared_error(inv_y, inv_yhat))
; n' A3 a3 @; ^8 G X; i( @6 Nprint(inv_y[:100], inv_yhat[:100])! L: D. i" j3 w J) W. l
print('Test RMSE: %.3f' % rmse)
$ l0 S% W) T% n$ P5 Z1 ?9 M5 `* A
+ y1 D! w3 x* X8 M
& Y/ H; W# u) i9 t1 w+ M9 ?* i# V'''
+ W( F9 f) Y) l9 m: [: P6 m# {实验结果$ l4 c1 Q- r/ i- }* Q
实验1:用前一天的天气数据,预测某一天的空气质量8 D; A" @* L) B' m2 e
使用LSTM模型" j- |3 V0 P. f: E* f4 t
结果:+ O/ P8 ~# [9 U( o$ A
Epoch 49/50/ p8 n- o/ W" ?& A" d9 Q4 c2 H7 |
0s - loss: 0.0144 - val_loss: 0.0133/ k3 ?$ P/ x& r; D: ?8 ~+ B
Epoch 50/502 v+ K9 F1 ~0 l. r6 a
0s - loss: 0.0144 - val_loss: 0.0133
X# R4 V K1 I$ S! \9 u5 Q7 g4 V* W* y
# f1 b5 T1 G. m, @
实验2:用前3天的天气数据,预测某一天的空气质量
% v- D, ~8 E; u c使用LSTM模型8 Y6 B, t7 h' a& t% a$ L) f5 t; L
% B8 N7 O5 p3 @6 e) G% q2 [* D1 k* Y) `' W! \
结果:+ ^' `# m' y8 u" P
Epoch 49/50
* o. n/ k6 C3 q9 W' G/ p9 r$ k. b0s - loss: 0.0147 - val_loss: 0.0149
6 W7 I9 ^) C$ @# ZEpoch 50/50
+ R2 X* \) m8 v9 \! h- @9 A; Y0s - loss: 0.0147 - val_loss: 0.0150! d7 j( \) o, q- q0 z. a8 ~. _+ O8 }$ V. j
7 l! c$ ]6 E9 ]) t* y1 r! G6 p' g
/ I9 g4 n5 ?) N8 B
实验3:用前一天的天气数据,预测某一天的空气质量& {! y1 R9 f! w0 {1 z4 R( p
使用普通的全连接模型 Dense(). s) S/ Z. w0 \7 D8 ?7 N4 r
结果:
1 N$ F8 h; O0 u/ k! q6 i VEpoch 49/500 ~& f/ o+ {+ R4 M
0s - loss: 0.0144 - val_loss: 0.0146
: g* o3 h6 {8 r [: U/ W3 MEpoch 50/50
2 ]0 g1 B( `. y0 {2 ~5 k0s - loss: 0.0148 - val_loss: 0.0151& R' R2 J0 x2 c0 p0 R- }4 `
# J3 J+ g- t2 N) P/ j6 P
$ O( ` m5 n/ p4 c实验4:用前三天的天气数据,预测某一天的空气质量; p" N: F( K7 J/ y5 S
使用普通的全连接模型 Dense()0 B: D0 h" |5 y+ D$ f& S- I: C
结果:
" M( x3 x$ C! E* e E# c1 cEpoch 49/50
. C( h5 _" t) k0s - loss: 0.0150 - val_loss: 0.0165# K2 x8 ]% f. m% k: D5 @! r8 q
Epoch 50/50! C1 P' T; f7 [
0s - loss: 0.0148 - val_loss: 0.01410 j6 u0 t1 y5 g0 w) U
3 k, B$ E( R6 v5 v, {# |
) ^+ x& y: R, ]2 l实验5:用前一天的天气数据,预测某一天的空气质量: A: D* U; H8 L) w3 Q0 J( [9 E- R! r
使用SimpleRNN g5 Z6 G# N0 Y5 n& k3 D
Epoch 49/50( E, Y0 r" V7 A# h
0s - loss: 0.0160 - val_loss: 0.0140
/ i' B3 H k) k, s1 R/ J% q8 Y0 x/ V, gEpoch 50/50% A0 C- M% O7 l" x
0s - loss: 0.0147 - val_loss: 0.0150+ [& T" C; |2 e2 [
& ~+ D* U1 N# F4 t
* q7 L7 }, ?* Q' [/ T0 U* t c实验6:用前三天的天气数据,预测某一天的空气质量
: g. {- O# G6 o使用SimpleRNN
$ H& Z; [9 |9 _) I; _Epoch 49/50
% v3 `- `& [, _2 q4 h& N0s - loss: 0.0164 - val_loss: 0.0233
0 E0 g5 v3 j" ^& E2 g, iEpoch 50/50" u7 F. ^9 c* n9 J
0s - loss: 0.0166 - val_loss: 0.0227, }2 g y, q- P- U( y: s8 v
RNN和DNN的区别RNN中的循环是指一个序列当前的输出与前面的输出也有关系。也就是说,网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐层之间的节点不再是无连接的而是有连接的,并且隐层的输入不仅包括输入层的输出还包括上一时刻隐层的输出。 # c, e' n; L& c0 x7 P' I6 r
, f0 ^. M+ d: A/ ^9 o4 h* ^# u/ D
2 s9 u+ g X5 g6 U* URNN和LSTM的区别
, l+ N% h( H7 P' h M/ gLSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。: G: b$ d) o$ \
N0 b3 \% b! L1 ]6 ^* O! q# w
) x" j) j5 I. w5 ]; \但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。$ L+ I' `# D# z* `& A/ E$ p/ K
![]()
# R9 L- e5 ?" S- l6 A( E+ a: R1 G" W( s0 o* _$ }
请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员
" G% R% |2 K0 t+ ^0 A
) ~% U. q& x4 l/ Z* R2 Q) s4 Z+ g- I9 W; l
|
zan
|