QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4325|回复: 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预测时间序列数据/ m% n3 t* U1 m% C' t
    + ^+ s. m& @. S+ O, y, u
    % n- u7 N! c% W. N/ Z- t: a' d
    文章目录2 b7 g1 ~3 ]5 p  E" P
    背景' B; u% e+ ~  c* [
    结论
    $ L; `9 E$ w/ J7 L& O# W6 R代码7 o; t, E9 C# `: c
    实验结果
    ) e4 [- k7 C$ i1 H$ xRNN和DNN的区别$ q5 b2 j' G/ r2 F% T
    RNN和LSTM的区别% [6 {! B" i6 D
    背景
    & K" H0 S2 t$ e9 x复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验) K& x4 U, Q- D$ ?- B
    熟悉用LSTM模型训练
    + _- W( \8 ]5 Z) @  a. R2 |验证将时序数据 转化为分类问题后,预测是否有效果
      z" q0 B5 A& c* o/ Y" b* t: ?对比SimpleRNN与LSTM模型 哪个效果最好?: S: I) N; S$ {+ U$ K, E- e
    验证LSTM相比于Dense()模型 是否有提升?
    , ?" b$ B  c' W& Z7 o' C对比使用前3天的数据 和使用前1天的数据 哪个效果最好?+ C$ T' m, d1 \& _4 C/ _0 p
    结论
    0 a$ A- [7 i& M8 L" O- x使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好! U6 Z/ n% u& Z* A1 V7 s
    使用LSTM的效果优于SimpleRNN  e, O$ E3 \! [1 L* M" o5 k- }
    代码
    9 {9 J$ O2 i  O6 @from pandas import read_csv
    # L& f8 R% z! ]% `9 r1 P" ?+ E  Ufrom datetime import datetime) w# Z' L. ~* Y6 g
    import pandas as pd" n/ S" l8 x% j# e8 o" a# n
    from pandas import DataFrame& e6 J2 n. ~% M5 ]6 i) ^; `1 h  E
    from sklearn.preprocessing import LabelEncoder,MinMaxScaler7 U+ Q% X7 T0 b* _- F
    from sklearn.metrics import mean_squared_error
    2 v' f, L' B( dfrom keras.models import Sequential
    & S  d- a1 [1 a* |5 o7 Nfrom keras.layers import Dense, Dropout. j( I, Z, Z; X. J5 o6 a
    from keras.layers import LSTM( `+ H2 L% y  e1 m
    from keras.layers.recurrent import SimpleRNN
    6 _4 I+ c; z& p$ ^4 }% Jfrom numpy import concatenate# p9 Z2 A; t' |0 k8 s7 f
    from math import sqrt$ X& }8 U6 ^* K3 M% r$ D& S
    + @' @, L5 ?* l# A2 ]
    " o; n6 R8 U" T) L& I, q0 P
    5 @, n# T1 e9 ]# e7 }9 R

    9 e  m/ H( b# o, H9 U8 e1 \# load data
    4 m6 G* V% F. s, W# A9 y0 ^def parse(x):* e, ]$ H  j7 W  U8 M* b0 S
            return datetime.strptime(x, '%Y %m %d %H')8 G3 X1 f4 X7 H7 ~3 y" P
      R7 J7 `  ?& f, u9 y
    def read_raw():
    1 j$ S4 s1 R& r6 F  W8 I9 \    dataset = pd.read_csv('raw.csv',  parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)% f% O5 G- p! K, m/ _; L1 y2 V
        dataset.drop('No', axis=1, inplace=True)
      p$ g6 _& E% @6 q    # manually specify column names
    # T: s# a8 I6 |5 e# P/ @    dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']% G, s& g& s& R/ z( u1 E& i5 \! O
        dataset.index.name = 'date'
    5 _$ V( o& L# `    # mark all NA values with 0
    . R% b7 M* F7 {2 y/ b    dataset['pollution'].fillna(0, inplace=True)) m7 q1 @6 J/ B
        # drop the first 24 hours
    ; T6 j5 Y+ m1 D# D* x    dataset = dataset[24:]
    : X  x/ i* t  S5 d9 `% }    # summarize first 5 rows9 e; s* Y" P8 B: E( m% T4 p
        print(dataset.head(5))
    8 E9 [/ g- n. B5 a( N% c9 v    # save to file0 k/ k5 `/ d) {  ]
        dataset.to_csv('pollution.csv')
    # t5 L0 h+ D& }* @0 i- H( ~2 C
    $ r4 ^2 d7 c+ q  O) ^2 T, C

    % y7 `, B; y# b6 B5 L2 r
    1 R- W" `" W1 L: m3 g

    " {& T, [; A; R8 Z, p( m$ \' C8 T# convert series to supervised learning
    4 P; d! e/ G+ ^: h* Fdef series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    2 K( @" I3 }5 Z) c  k9 ^    n_vars = 1 if type(data) is list else data.shape[1]/ {8 O. G- B, Y$ w8 G- _/ {8 n8 t
        df = DataFrame(data)
    + j3 i5 y( m1 Q% J    cols, names = list(), list()
    8 H. e% T9 W# n% A9 ~2 p    # input sequence (t-n, ... t-1)2 v" E$ N4 B3 x# C8 c% |
        for i in range(n_in, 0, -1):8 J, \3 D( X) ^* G+ B  f, o
            cols.append(df.shift(i))
    + S  |- ?0 ?8 H0 J9 i% a4 L        names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
    ' u, g2 V/ H4 i+ K/ Y. Y    # forecast sequence (t, t+1, ... t+n)4 g" k) S# z9 Q0 k$ S
        for i in range(0, n_out):  R% e! t3 h' o
            cols.append(df.shift(-i))! s4 B8 \8 F+ O+ _1 Z$ }
            if i == 0:
    - d% I6 }. z9 x7 j  u9 k! H            names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
    6 V3 m( C+ ^9 |* h+ l        else:- V5 X8 s; N6 E: k( J. v
                names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
    1 [2 `' ^3 l- o4 p, s8 k    # put it all together& ~- e: w, H2 E2 K" ?) ?$ ]4 @# f/ w
        agg = pd.concat(cols, axis=1)9 p# E4 ^, h6 x' W( E4 S
        agg.columns = names
    6 ]* O4 Y1 z: V3 l4 W5 |' h1 ?: Y    # drop rows with NaN values
    ( M. B/ P+ R) A" @  ^    if dropnan:# Q; j- e/ k8 y9 v
            agg.dropna(inplace=True)' |5 d1 O) z1 I' [; f" C
        return agg
    2 a$ Q& U0 d, M/ _4 [" a . X5 f( v8 V4 v/ J) ^0 l# S
    # load dataset. Y$ P3 ]8 O( s+ [2 o) w0 {6 B
    dataset = read_csv('pollution.csv', header=0, index_col=0). o) h% F" L% n( s. X/ ]7 l) y
    values = dataset.values
    + [2 C" q  a1 K- Z  _; G9 q7 x1 Y. s) Z% W* v' |4 e

    : I  e! ?  I. V5 x1 Q# integer encode direction2 D) w0 K( {& @; {. A+ b, c
    encoder = LabelEncoder(): m$ ~% `! y/ K) _+ ~& @
    print(values[:,4])
    9 _: p: }1 E1 o% rvalues[:,4] = encoder.fit_transform(values[:,4])4 P3 G, [' n/ o# d1 l6 V7 `
    # ensure all data is float
    3 s6 K& M1 L/ z: e! Jvalues = values.astype('float32')" P1 f/ m: b( b: A! F
    # normalize features
    6 ?5 I+ a( c, Y( b. l! v7 hscaler = MinMaxScaler(feature_range=(0, 1))) T+ w# `7 K# j; Z/ S9 b7 M
    scaled = scaler.fit_transform(values)& E- X1 F/ ~7 O2 d* x! O
    # frame as supervised learning+ e& a3 g7 P* W& b/ m! C/ g! \: O
    reframed = series_to_supervised(scaled, 1, 1) 1 ^( h* E5 z9 c. t
    #reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据
    ' Q) @( {4 D/ g$ bprint("columns:", reframed.columns)
    1 r5 ^0 p6 Y$ [+ O& j+ A( I# drop columns we don't want to predict$ Z6 _" f6 S$ W6 G
    reframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据" J2 ]- D6 }. {5 f1 n* A6 y; x
    #reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据5 e3 ]+ P0 o- S3 q8 n
    print(reframed.head())  N7 P& g9 h# d: {8 B5 q$ P: t; Q
    print("new columns:", reframed.columns)
    & a" _: _* L+ B( f) f# split into train and test sets
    ; H; K" ]/ h( l8 Y# a5 ?values = reframed.values6 e- a9 i5 o# C5 m! f
    n_train_hours = 365 * 243 T6 c5 S; [+ Y" b, p% u
    train = values[:n_train_hours, :]
    0 @) Z: I  B" t1 G: wtest = values[n_train_hours:, :]+ F; Y6 @& e$ o. h" ^; _
    # split into input and outputs+ ]9 e; w* S; D  }6 T1 L
    train_X, train_y = train[:, :-1], train[:, -1]
    ! I8 C$ u( J, G( |1 Y9 ?test_X, test_y = test[:, :-1], test[:, -1]
    2 Z% \  M# E1 O8 _# reshape input to be 3D [samples, timesteps, features]) W4 C4 K" {$ H7 q. @  T
    #使用Dense()模型时不用变换
    ' H! m2 T8 y6 ytrain_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))9 e5 r( g" J3 }3 \' c7 G/ f
    test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
    , D0 D& E  ~1 s8 r! B( }* eprint(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
    ( H3 Y* q2 Q8 b6 n9 E* _# design network
    4 o; |" I$ T" v& J7 y- ymodel = Sequential()
    7 _2 M) \: b1 P/ V' [#model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))4 `( _+ T9 x' }. p) U7 H
    #model.add(Dense(50, activation='relu', input_dim = 8))
    & r: {* M- V* Y0 }: o  Y. V3 _  pmodel.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))
    9 z9 G0 }1 K' @5 l, j. k+ [model.add(Dense(1))2 c; T1 w' F1 j; m8 @6 d# M- B
    model.compile(loss='mae', optimizer='adam'); D+ V$ Z! A+ _5 R/ @
    # fit network
    ; t5 ?7 |- X  a2 n- V$ ?! p) xhistory = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)% ^0 n( d/ @  A! X) `- c# {4 `
    # make a prediction7 Q7 X, W0 ~+ [+ l
    yhat = model.predict(test_X)
    " I9 L  Z8 C- f+ Tprint("yhat shape:", yhat.shape)
    % i* h, X% {: k% R'''! Q. l& y  |9 {, z( t8 h
    计算在测试集上的均方差
    1 R% x+ j( ]. m2 S2 i1 jtest_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
    & s9 K) l. Q: _! }& R) }print("test_X shape:", test_X.shape)+ M8 Q  u; Z$ M

    # c& t8 W5 O& \; E% F
    ; H5 W' ]0 v0 E  C9 C3 o: x
    # invert scaling for forecast' _% V& `2 F/ p! k4 A4 `( `
    inv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)4 {2 A. b) S) e- d- d4 @1 q
    inv_yhat = scaler.inverse_transform(inv_yhat)$ G! a' ~, l( x* ~/ B/ p
    inv_yhat = inv_yhat[:,0]7 t5 R, ^' c! W1 p6 W+ m% }1 _
    # invert scaling for actual
    6 C) b1 e1 l; m9 o0 ?, ktest_y = test_y.reshape((len(test_y), 1))
    * m0 x4 n" C4 ?inv_y = concatenate((test_y, test_X[:, 1:]), axis=1)
    ' |4 x! i# `6 _3 l- d2 m, Qprint("inv_y:", inv_y[:10])" ?& e4 a7 y1 V) T% W5 O% F7 x+ q3 ?
    print("inv_y shape:", inv_y.shape)) d! |6 O9 V8 g8 B% W+ u- Z5 M
    1 c' M1 f* B- ?9 r" N' R- Z
    9 ^- t8 l8 i* v! a( ]% ~! s& d$ p
    inv_y = scaler.inverse_transform(inv_y)0 {4 i3 i$ g" D+ h
    print(inv_y, "*"*30)
    / j. }( }6 Y) k8 T- o) t' k" ^3 u0 x" ^3 |# E( T

    $ n7 P+ I7 q$ finv_y = inv_y[:,0]
    1 }$ t* N( c3 K# calculate RMSE# R, ~7 p4 R# n) d
    rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
    3 L7 m/ I2 e% L  Q# O" C) E4 T6 rprint(inv_y[:100], inv_yhat[:100])$ l; s- o  J" u: n4 n
    print('Test RMSE: %.3f' % rmse)$ S! X( G8 x( G9 @* v

      D6 }1 a. y% K' p/ t" n+ s& W
    4 H& M  {+ M6 z' A+ F/ l: K$ z
    '''
    9 Z1 E8 o3 ?; \" P, }+ j/ h实验结果
    * j2 @/ `& a: r# U+ L0 W( X
    实验1:用前一天的天气数据,预测某一天的空气质量
    9 c8 B+ b* G7 S: C6 |. g' _使用LSTM模型
    # D5 U5 T; `: [结果:1 r- `' L4 g& |0 ~) H, R$ ?
    Epoch 49/50$ |5 f1 N1 X5 y
    0s - loss: 0.0144 - val_loss: 0.0133
    6 a0 O" ?; E8 o' x4 LEpoch 50/50
    1 V3 H: Q" c. d; G$ a" k0s - loss: 0.0144 - val_loss: 0.01331 \+ D( H1 \1 k( L7 D5 p

    ( g/ r( I2 R- s) n+ A

    6 U9 M5 ^/ j4 s' L2 a$ U$ \  W实验2:用前3天的天气数据,预测某一天的空气质量
    / y* |) x( L4 d* P使用LSTM模型( L. D5 @" l6 q  Z

    4 r3 J- ~! v5 W; O) r

    9 O7 G1 X4 ~9 V) t结果:0 ]; m* k! J2 u
    Epoch 49/50# @( a" N9 ]" O) A0 }
    0s - loss: 0.0147 - val_loss: 0.0149
      b( X& J* c" t6 h% sEpoch 50/50; X$ Z% O0 i7 Y4 s2 e% d9 N
    0s - loss: 0.0147 - val_loss: 0.0150
    ; F2 \# d  Q" g. y
    % U/ \/ L6 c( Q. o9 }
      k, M% _" T. }) S/ ^+ e) ?
    实验3:用前一天的天气数据,预测某一天的空气质量/ P7 O# k6 v0 [+ b
    使用普通的全连接模型 Dense()
    # I$ c$ n" g5 K% j0 f7 F: L结果:
    3 q4 M: P: H3 p; [8 ]2 {$ uEpoch 49/50, i2 s# A! x" j- _0 R
    0s - loss: 0.0144 - val_loss: 0.01460 o( X3 ], U! b
    Epoch 50/50
    " z3 S) A# N2 ?2 `4 `0s - loss: 0.0148 - val_loss: 0.0151
    ; K* B5 c/ m" y
    : h% T* J/ I/ I9 Z( o/ m1 ]

    5 B! C9 }6 `2 s" E实验4:用前三天的天气数据,预测某一天的空气质量0 q, z4 |  \, G! x
    使用普通的全连接模型 Dense()
    & x! i: ]" G' E+ j: a: A9 e2 ~结果:
    8 M! [% m" u, t  M) u% |. _0 JEpoch 49/50
    / x7 S8 F, A, k2 S: ?- F" L0s - loss: 0.0150 - val_loss: 0.0165
    & p0 {1 O) X, j( J$ C7 iEpoch 50/50- J+ [" k( P+ G3 H* J& k2 ?$ S
    0s - loss: 0.0148 - val_loss: 0.0141) U* Y5 q/ y8 z1 X+ A, l  Y
    ; I+ [' Q+ O, x$ I) Z

    . s7 J5 R) |4 b8 e: W实验5:用前一天的天气数据,预测某一天的空气质量
    , }" t1 t. l; ~+ n; R6 F! J0 Z使用SimpleRNN3 S% X3 m9 |, S0 \, g
    Epoch 49/50
    ; y: W# U4 y% x' \/ E1 B0s - loss: 0.0160 - val_loss: 0.0140
    ( e5 w2 {8 l% W( m8 ~Epoch 50/50
    2 g# _# S% |4 G% }0 x7 O0s - loss: 0.0147 - val_loss: 0.0150
    & g7 @" w7 [- ~7 F- w8 @6 r, s
    6 }9 q$ e  z) w" u# y0 d* m5 T+ i8 @4 r
    7 u& U0 |5 k  e$ ~3 s1 j, k  V+ d
    实验6:用前三天的天气数据,预测某一天的空气质量
    ! \$ _4 v. I! Z* z" |+ D0 f. v* C使用SimpleRNN' H( V( a6 S1 j
    Epoch 49/500 K- ?9 f/ ?" k3 y9 N1 P! F/ Q
    0s - loss: 0.0164 - val_loss: 0.0233
    . n, m# C0 N' M6 c; I) \* o! S3 n8 o$ UEpoch 50/50
    " W  C( W# e* e! p$ k+ e0s - loss: 0.0166 - val_loss: 0.0227( f% r# Q- `6 d: l/ h
    RNN和DNN的区别

    RNN中的循环是指一个序列当前的输出与前面的输出也有关系。也就是说,网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐层之间的节点不再是无连接的而是有连接的,并且隐层的输入不仅包括输入层的输出还包括上一时刻隐层的输出。


    ( I: ]+ [) M9 ~
    ' J& w' y& q- m- C( @
    $ _/ ^0 G3 S+ S
    RNN和LSTM的区别
    ( Y$ g' b7 ]. G- ~: Y7 w4 aLSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。
    & t% c1 g! i& a+ y% p$ s+ {, D3 \
    % v/ N. G4 l/ R' X5 X9 f; {6 y- c/ u
    + ^3 [  T5 f. k% q  [
    但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。* x/ a  b+ [6 v  U$ ~

    5 K( X2 o+ Y# j4 x% q4 x# T
    , x5 S% K9 `1 M请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员
    0 r# }6 A2 G; s2 {  [" i! s
    ( {7 V$ k, W" P; \7 \5 b; L
      p; R, f) L! P, @
    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-4-20 11:20 , Processed in 0.439740 second(s), 56 queries .

    回顶部