QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4399|回复: 1
打印 上一主题 下一主题

使用LSTM预测空气质量pm2.5

[复制链接]
字体大小: 正常 放大

1178

主题

15

听众

1万

积分

  • TA的每日心情
    开心
    2023-7-31 10:17
  • 签到天数: 198 天

    [LV.7]常住居民III

    自我介绍
    数学中国浅夏
    跳转到指定楼层
    1#
    发表于 2021-10-15 10:53 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    使用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* U
    RNN和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
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    sjlxdn        

    1

    主题

    2

    听众

    155

    积分

    升级  27.5%

  • TA的每日心情
    无聊
    2022-2-19 17:40
  • 签到天数: 30 天

    [LV.5]常住居民I

    国际赛参赛者

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-7-29 12:38 , Processed in 0.440978 second(s), 55 queries .

    回顶部