9 `) r2 k$ Y: \- Q6 i, t/ ^. t1 Z/ \; g) Z8 ?6 Z# v
文章目录/ x% t) g. X9 E/ G4 {! [, h
背景 # m: |! Z% U/ r" E: `+ c. u! K结论 ) T7 R; j' Q/ X5 `( M代码 ( b+ w6 g' q6 l& {实验结果 + R( X: d A! ?' I/ v; kRNN和DNN的区别 K0 Z" a; e5 Z+ Y9 i) y) `9 N8 h
RNN和LSTM的区别 ; @3 D1 W1 @" V5 L背景! V. M& G! b8 Z# H9 {
复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验 / d+ M( n _' L7 n熟悉用LSTM模型训练 8 ^) e3 k5 @7 ~5 X; V0 Z验证将时序数据 转化为分类问题后,预测是否有效果0 `- h+ \3 N$ Y$ Y( X9 T
对比SimpleRNN与LSTM模型 哪个效果最好? ( F2 O# _ N% R! J/ V% k$ _9 s验证LSTM相比于Dense()模型 是否有提升?$ {$ D l. N, w! c. R0 n, _
对比使用前3天的数据 和使用前1天的数据 哪个效果最好? ; j# @ l+ _; R6 x" Q$ a9 O r h1 S结论 5 `3 Y9 _2 i3 ]% a* N0 n5 G使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好( \ R/ |1 w8 T; ~; ~
使用LSTM的效果优于SimpleRNN e# x/ i6 e7 j- O' J& d6 e
代码 $ w7 _3 J9 v8 ~" @from pandas import read_csv 7 g5 z" X. ]6 |( \from datetime import datetime1 B% v% Z( k0 K$ h. i; j
import pandas as pd4 D: \$ ^$ J4 E0 Z6 x o6 ^
from pandas import DataFrame + K/ H$ I* a+ ~: |% l8 Y5 hfrom sklearn.preprocessing import LabelEncoder,MinMaxScaler * [# h- O' a' a! ]( sfrom sklearn.metrics import mean_squared_error ' _2 d2 I h4 k0 Hfrom keras.models import Sequential / x3 \" R$ I9 a' F& _8 i/ c# ffrom keras.layers import Dense, Dropout 0 ~, G/ g0 \3 c5 ]3 f1 J% Kfrom keras.layers import LSTM 8 G+ y2 a' M- o2 ~ ^5 K, cfrom keras.layers.recurrent import SimpleRNN9 x2 O% c' \- G4 G. N% \ c' i( O
from numpy import concatenate 9 \3 ]4 Q( m; s9 q8 ufrom math import sqrt: {1 E5 n: i/ O. q @4 i1 U! |
! |6 P$ [7 S' s2 K2 ^* b k( H. y" y, h1 u
$ J% D ?4 u. N; p. Z0 u
L! {) Q0 z& }- a& F+ n# load data ) O1 s# a3 t9 \/ ~" q- Y5 Bdef parse(x): * s- a6 @' E: u return datetime.strptime(x, '%Y %m %d %H') 2 `% s j1 U( f S$ ~ # G" ~$ i, |( `
def read_raw():0 h& _' }& O* _8 H4 _
dataset = pd.read_csv('raw.csv', parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)8 W$ O5 c: v! a0 A% D3 o9 A* v8 W
dataset.drop('No', axis=1, inplace=True) / m* c, l1 Z x0 s, Z1 w l # manually specify column names & V% s9 B/ F: s: ?/ K' u; Q dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain'] 7 O8 K, z5 ^5 M dataset.index.name = 'date' 0 X1 a9 z" i. D1 I # mark all NA values with 0! f, j/ |( T2 {* e0 X" o9 T
dataset['pollution'].fillna(0, inplace=True) * b8 U& S4 t0 h Z # drop the first 24 hours3 _: P, i; f1 f% m: R( P
dataset = dataset[24:] - z% X1 I: f! w9 I( z4 X' I& D/ s # summarize first 5 rows5 G2 d3 m0 U/ M' A8 [6 i' T! \
print(dataset.head(5))* T) ~ [0 K, d3 }5 m+ E
# save to file 4 _2 V# w* T) f" A- z dataset.to_csv('pollution.csv')2 u! b7 w3 w2 ]+ u/ [0 L# Q; P
& M1 `6 E7 s: w
% ?5 M0 E# U% \6 A6 l; Z& F( F : e* \& o2 U! d8 y( b/ c# R% Y1 X0 n2 f7 {0 L# Q* b8 s
# convert series to supervised learning X) J( G' Y& S0 @! P" jdef series_to_supervised(data, n_in=1, n_out=1, dropnan=True): 1 l. p1 ~) g6 b0 V$ d) x0 E, T+ @ n_vars = 1 if type(data) is list else data.shape[1]+ y5 `5 u4 ^, W
df = DataFrame(data)5 R/ l" c% G! F A, {
cols, names = list(), list() ) u8 q0 f1 E. i9 B- d! K7 z # input sequence (t-n, ... t-1) 0 C; I! V. d. c5 S; j! |1 I6 ?$ y for i in range(n_in, 0, -1):1 s6 v t# q( h& R1 w
cols.append(df.shift(i)), Z0 d6 b K/ f) f& m
names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)] " a! G6 I! s+ u: s$ P' h # forecast sequence (t, t+1, ... t+n). L, g0 ]* i Z4 x: i. W# @& P R
for i in range(0, n_out):6 N. D' N4 d. o/ `% w0 N
cols.append(df.shift(-i))6 q! V( y( x9 t I# ~ f
if i == 0:5 l; i# M# M1 T0 P! v+ N9 Q3 s- E
names += [('var%d(t)' % (j+1)) for j in range(n_vars)]! j2 r5 a0 I3 @, m
else:; ~. y; }) g1 e% I# _7 [
names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)] " T. [2 G- R/ a* O, C- c # put it all together 5 y1 l# ~* [9 j9 I" C agg = pd.concat(cols, axis=1)- {8 }) \! v' r+ b. Q
agg.columns = names , w' g0 C' N/ r& _ # drop rows with NaN values ' }5 b V9 }2 B/ g, ?* R g if dropnan:1 V) h U0 u9 T# G% J. W% @: f
agg.dropna(inplace=True) " M+ u4 `" E9 r3 X, z3 C2 f return agg # p" ]( T* _9 Q s. J7 _ , R. u' T7 l' D0 o# load dataset; b/ I4 g: u; z
dataset = read_csv('pollution.csv', header=0, index_col=0) 4 q7 h3 g1 M/ c8 ?8 tvalues = dataset.values% K: A: g: ?; m+ T( S
9 Y, k5 l$ a8 c3 {1 }* S ( _; u% F5 l) c# F9 u# integer encode direction( S# `1 q8 E7 D1 B! s
encoder = LabelEncoder()& U3 e+ o4 b3 B
print(values[:,4]) 4 r( F2 E3 C( s* K+ b% S( gvalues[:,4] = encoder.fit_transform(values[:,4]) 8 t& K! T3 W8 I/ F# ensure all data is float$ `3 R( p7 [# X
values = values.astype('float32') ' J. ~4 X% m# k& \7 }5 F- V K4 d. y# normalize features' q, N. z# n7 F# g
scaler = MinMaxScaler(feature_range=(0, 1)) % A4 J. ~1 @' G" n& K3 Fscaled = scaler.fit_transform(values) 9 G' @( }9 X) H2 e# frame as supervised learning * r/ T) q: {# _ A* [) treframed = series_to_supervised(scaled, 1, 1) ) n K" z) ]' N2 V+ q#reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据' m( K% ?2 T5 I. I) r! a
print("columns:", reframed.columns) B$ m, I% V1 C r! {) j X
# drop columns we don't want to predict / [7 r- v* S* i3 p3 h$ kreframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据/ P3 T' u9 E8 E9 T7 R1 f
#reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据 . Q, s5 x0 h4 \/ U9 i, g! r: mprint(reframed.head()) - }3 t1 ?( A$ T# k+ \) ~print("new columns:", reframed.columns)* O8 G# |+ C0 C6 M9 O% }/ Y' ~
# split into train and test sets # ?0 z$ ]" b6 f5 P; _values = reframed.values 4 n v T; I2 t8 L6 H9 }n_train_hours = 365 * 24 4 u: \: W9 r# B# ftrain = values[:n_train_hours, :] - H: J$ e: K8 S+ Qtest = values[n_train_hours:, :] 5 s& O* M6 q" a: U" J# split into input and outputs 1 x% R6 c. m* R% S/ z3 e! [: [train_X, train_y = train[:, :-1], train[:, -1]- ]9 F" k: _% }0 [
test_X, test_y = test[:, :-1], test[:, -1] 4 P/ w0 y6 f e' v7 f+ w# reshape input to be 3D [samples, timesteps, features]/ I$ o# V4 z! E; q+ K( c3 u
#使用Dense()模型时不用变换9 M# S- K6 ~7 ]
train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))3 s7 Q3 [& s4 ~8 o+ f
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1])) 6 k/ K/ m. e- e; [print(train_X.shape, train_y.shape, test_X.shape, test_y.shape) 5 W& R! W+ w, {7 n" K% I/ e# design network( y. V, Z9 _( J1 f
model = Sequential()- g7 ]' C% A7 A( i/ k0 u
#model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))3 _( l/ J/ t9 p/ I2 M8 U6 Y
#model.add(Dense(50, activation='relu', input_dim = 8)) . v3 U% B2 `& v6 L5 wmodel.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2]))) 8 \' j* K* [2 Nmodel.add(Dense(1)) : ~% ~( K h/ M8 Y) omodel.compile(loss='mae', optimizer='adam') / @9 A9 H' J9 h' h$ U4 U# fit network 5 B& g+ y! h7 s `, hhistory = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False) + L/ ?: V V Q: d) O9 e7 D# make a prediction% p7 b! F1 L a0 y5 H, W6 m
yhat = model.predict(test_X) & Y1 X' i/ m1 }7 A$ J Vprint("yhat shape:", yhat.shape)4 {# J" s6 c% Z' p3 k9 A# z+ Z! x
''' 8 Q5 `0 E6 Z! O" U" j计算在测试集上的均方差- t% g- f, S. X V' ^+ y
test_X = test_X.reshape((test_X.shape[0], test_X.shape[2])): E1 ^7 m+ }0 f; V+ `
print("test_X shape:", test_X.shape) * c$ r6 i% i2 d / O3 g* z0 j$ n2 f ; `$ Q- {& g8 l) f8 _, l# invert scaling for forecast # l, S. Z# k* k4 A; j* h. yinv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1) ; u: ~# O- A) s* W# x9 Iinv_yhat = scaler.inverse_transform(inv_yhat) + U/ @( @6 |6 b# W8 Qinv_yhat = inv_yhat[:,0]- X. H3 d3 T `
# invert scaling for actual & @+ y1 Z8 k( ]' [5 Otest_y = test_y.reshape((len(test_y), 1)). Z/ @" M2 {% {: q* Q2 |5 A" J
inv_y = concatenate((test_y, test_X[:, 1:]), axis=1) ( g5 n" v9 [2 r/ W; q# X" eprint("inv_y:", inv_y[:10]) 2 P7 \8 K2 }. N/ e- Oprint("inv_y shape:", inv_y.shape) 0 R/ v0 {$ C7 W: q " ^$ s4 }* G$ p) @# \( y8 R7 u( j0 \% N4 Z
inv_y = scaler.inverse_transform(inv_y)4 g0 D/ n' n1 R# ?4 ]. s
print(inv_y, "*"*30) ( y. u' x6 x, C9 k, g' L ' l6 {! p4 o: U0 h- y4 ` / ?( q4 {( D! w7 t3 |: Einv_y = inv_y[:,0] ' \0 p) n' K) T3 v/ \5 x8 n% c# calculate RMSE & y. Q5 V: Y6 e. V) Grmse = sqrt(mean_squared_error(inv_y, inv_yhat)) ( R0 O/ Q# A& zprint(inv_y[:100], inv_yhat[:100]) * v" h* G' r2 g* ?+ Dprint('Test RMSE: %.3f' % rmse)- h) L# f8 T1 g
" M: r) H; e1 W: j! i
6 r! @+ L1 @2 ]0 e, ?% p2 P4 k
'''/ g5 e8 R( K! h. M: j" I 实验结果. u" C, [( P+ n
实验1:用前一天的天气数据,预测某一天的空气质量 ! o$ L4 I$ N# y9 P9 Q- U5 H3 `6 Z使用LSTM模型 ' y4 T8 Q E8 n( g3 Z4 I2 B3 J+ c结果: 2 o j! L2 K* v. u/ `. A: J9 SEpoch 49/50; P s# f' t7 k( x. s
0s - loss: 0.0144 - val_loss: 0.0133 0 W9 @9 M3 d5 L* H6 m5 aEpoch 50/50 ' M) g" b( a2 Y% o0s - loss: 0.0144 - val_loss: 0.0133) k3 {: H0 H" W" B+ C' P3 p
# a' `( h. H6 @
* h, I; c1 R9 T, ?8 A
实验2:用前3天的天气数据,预测某一天的空气质量 ' q8 X, c1 a9 X% |% I( e使用LSTM模型( t3 j x' w, S6 h
# H( k1 u+ h& T+ x& Q0 ^, D; v
# m5 N% [2 P) [( i6 z( U0 E结果: / w+ Y8 h& w8 K* ~Epoch 49/50 ' Z E' Z" ?4 o) Z" F' g) m0s - loss: 0.0147 - val_loss: 0.0149 ! n0 T; }1 b1 j+ S7 G+ p9 b. M, YEpoch 50/50& M$ H- q; H$ w+ J
0s - loss: 0.0147 - val_loss: 0.0150 $ K P0 g d) R" T7 h( } 5 n" ?. o4 o6 h) Q2 z& o3 q( Q; X0 g/ {+ K( P: v' _1 P
实验3:用前一天的天气数据,预测某一天的空气质量 " q. n% Y0 V8 k! B8 W! X使用普通的全连接模型 Dense()/ w% v* r, g% N( B" F. ~1 x
结果:) E R9 O1 U7 t. ~2 Y
Epoch 49/50 5 |3 V- j$ |# H B. G0s - loss: 0.0144 - val_loss: 0.0146' N$ E' S! Q f: b4 n
Epoch 50/50 6 Y# p- U. |3 \/ Z) W0s - loss: 0.0148 - val_loss: 0.0151 # ~7 X6 q% Z* u) Z- ` v! Q) X8 [% Q+ `0 H0 L' c0 Y! X T R$ K
0 r, n9 s" I* N; z
实验4:用前三天的天气数据,预测某一天的空气质量8 W. @" B, r" q3 u" ?
使用普通的全连接模型 Dense() 7 K1 l, n: I. B" P" D% B% ?6 _结果: L8 ~; @$ g" I. F4 S% j0 ^8 ?" AEpoch 49/50, O: N$ ]9 z5 c4 ?+ I9 B L' d. j
0s - loss: 0.0150 - val_loss: 0.0165 % U; u$ i% e8 ~, g% fEpoch 50/50$ e0 b& V/ Z% c% o0 W/ d0 Z g% I
0s - loss: 0.0148 - val_loss: 0.0141 3 Y5 ~$ N% E8 @# l- r, u- s& E3 g! C/ C5 h
% J( T1 E/ ], {. d- {, x$ r
实验5:用前一天的天气数据,预测某一天的空气质量( w) Y& m/ t, Z. q% R$ z5 t" r
使用SimpleRNN : V: n: |$ p5 WEpoch 49/50 2 @; Z; p4 u! P0s - loss: 0.0160 - val_loss: 0.0140 ! W/ |9 J9 ^; C& O5 T: }6 EEpoch 50/50 , [& J, y. Y1 @! Z7 g. M4 T0s - loss: 0.0147 - val_loss: 0.0150 ' V! I; P. o6 x. m . G1 S1 \- X3 B( R3 ~: }* f! d9 G% o2 ^; A+ \
实验6:用前三天的天气数据,预测某一天的空气质量! A2 J8 o6 ~0 p, Q- g
使用SimpleRNN8 M% Y: M. m, ` ^. s- |* S( a
Epoch 49/50$ m, v1 i6 i" j1 R: A' l9 d
0s - loss: 0.0164 - val_loss: 0.0233" l4 a- r4 k! Z g. n5 N, Y# }
Epoch 50/50" O) F7 N$ S3 f/ L3 v$ f% h% |
0s - loss: 0.0166 - val_loss: 0.0227 + O6 s8 e; {/ ^" eRNN和DNN的区别