QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4430|回复: 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* X) K, ]) W7 s, V% i; ?% Y) u
    3 x/ }( I1 N  g: `( M
    1 D# J! \% w9 T) y, A
    文章目录! t! l9 x, T9 A1 p1 P, p* J9 G4 \! B
    背景
    . Q1 x) L8 O: d# \8 l0 X4 _8 ~结论
    & N) |: p, X  w! J7 g8 Q! M+ n! B代码
    8 r/ i3 a3 f5 H9 F* s实验结果% u0 W' i) l3 h8 z
    RNN和DNN的区别
    6 I" i* E* d, [& g7 bRNN和LSTM的区别
    ( S; b( C7 Y" G# ~& {背景! m! y* [/ {" o$ w8 d0 D: S
    复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验, [8 N( |5 z2 w8 p/ Y
    熟悉用LSTM模型训练
    ) _$ M6 b; G7 w( @5 y7 s验证将时序数据 转化为分类问题后,预测是否有效果0 x; u+ x8 a0 R3 ^7 G4 M
    对比SimpleRNN与LSTM模型 哪个效果最好?
    * Y( h( W* t  V: ~. Z" f& L验证LSTM相比于Dense()模型 是否有提升?2 c4 f: }5 e$ o0 l7 a2 k
    对比使用前3天的数据 和使用前1天的数据 哪个效果最好?- X& o7 h- {1 o3 x/ ?" P5 ~
    结论
    3 T, e- A4 l0 y6 G8 P- X1 E1 w使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好* y0 v6 y8 a+ m
    使用LSTM的效果优于SimpleRNN
    % m; f1 y: r( D& ?代码
    8 C1 C/ G1 g& o( S0 @from pandas import read_csv8 |& @- G4 j* V: J6 U2 h% L
    from datetime import datetime
    4 E7 S$ r; s4 E! \( ]9 j/ Uimport pandas as pd
    2 d( F- X. G8 ~from pandas import DataFrame- }2 q0 `/ a( H! D% T) r. N
    from sklearn.preprocessing import LabelEncoder,MinMaxScaler" ~3 Q7 Q& g0 d1 f! [
    from sklearn.metrics import mean_squared_error% e* L& L( g& h
    from keras.models import Sequential) O! T, Y- c& e$ |* R: u3 _- \! w: ~
    from keras.layers import Dense, Dropout
    . j; N  \6 y8 _6 \5 n; }9 [9 Z1 gfrom keras.layers import LSTM
    $ |. {$ J% w; ~/ \from keras.layers.recurrent import SimpleRNN' ~$ r' _* _! J& v' F, j* A
    from numpy import concatenate
    6 u0 t! d) h0 _6 K) [' B- a$ [3 H7 C" |from math import sqrt
    $ N2 J6 e" K  q3 v) U- s
    / x2 ]# D4 ]- T6 }" B% S0 e

    4 c. D" Y4 i7 a$ Y, C9 ?- ]# `- }8 M1 W# S9 h" s1 c4 j( |1 w1 @

      x: T8 K/ K5 Y; V# load data
    " H( q$ r- @' W6 bdef parse(x):
    $ r) a  `6 l& X0 {. l        return datetime.strptime(x, '%Y %m %d %H')+ l( a3 S& E2 Y! f

    . d& x  V' a4 G$ y" ?def read_raw():. q' B% y4 b7 @( ^; i, M, \9 L
        dataset = pd.read_csv('raw.csv',  parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)+ I/ D& i7 }1 a: m3 o! J2 I
        dataset.drop('No', axis=1, inplace=True)3 B" q% j" N& [+ U; |4 t$ X' Q
        # manually specify column names
    . v4 j- n% I* @. K5 H    dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']2 p) p! b6 m! l# d; k
        dataset.index.name = 'date'
    + b$ r; d3 {; D. X+ r  |3 N    # mark all NA values with 0
    6 N! i6 K! \; h- V6 K    dataset['pollution'].fillna(0, inplace=True)4 r" A- U( T+ `% Q1 l
        # drop the first 24 hours
    0 T, G1 M8 ?) P) `    dataset = dataset[24:]* g/ ~* c" O0 ~3 N1 b
        # summarize first 5 rows
    5 q* g. n9 s6 }+ z    print(dataset.head(5))
    4 a( o$ Y" J; e9 @. ]    # save to file
    & S9 i8 k" O5 w+ J    dataset.to_csv('pollution.csv')8 Z4 P5 [7 i1 s! ?4 U5 q9 R+ O8 J
    * z9 L8 {9 e- y: K/ T; e6 [- F
    % T: c/ b- }6 c' @1 Z% O

    1 x% c6 W/ W: m8 K2 `- s# u

    5 a/ M" ^# ~9 z' l- ^# convert series to supervised learning# S# |: o8 b$ x- m: i0 r
    def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    # C$ |5 F- t9 ^2 z    n_vars = 1 if type(data) is list else data.shape[1]
    , Q: _; |  }4 K$ F- \    df = DataFrame(data)
    ! Z) ^* C. ?$ E    cols, names = list(), list()
    0 Z/ C: E- s  ~# u" T% i& p) p4 w4 C    # input sequence (t-n, ... t-1); V7 S6 j3 S; k
        for i in range(n_in, 0, -1):
    : J- L; Q; w" e% ]6 O9 q" g        cols.append(df.shift(i))
    0 v: w& @+ G9 w2 x1 v4 E- h' e        names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
    6 @1 O; c/ B1 @% C* ^' `    # forecast sequence (t, t+1, ... t+n)( L2 a* g2 y& [9 t) p- o+ m& |
        for i in range(0, n_out):
    4 @$ B% f$ V% K8 @        cols.append(df.shift(-i))# Y/ |3 F) A2 ~* y  P- d
            if i == 0:6 M+ h  g# G0 P* `+ \2 b( b
                names += [('var%d(t)' % (j+1)) for j in range(n_vars)]) a! [* E' `$ }" g$ E( ?
            else:
    3 K  Z" Z$ `0 ?( H" u5 l            names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)], M2 |/ [) V1 T1 n8 e, f
        # put it all together' w1 o+ b+ Y) Y( [, m' A  `; `
        agg = pd.concat(cols, axis=1)3 Q3 o6 `+ R# V4 @
        agg.columns = names
    9 k) o: Q, f5 I+ a+ b6 h' z    # drop rows with NaN values# q/ [5 w& Q, K2 q! s' H
        if dropnan:3 l% z) C' L+ f
            agg.dropna(inplace=True)
    ( s; Z4 ^7 s+ H2 R7 S" A    return agg( d6 w- m" ^- q7 E1 Y
    " \1 {/ f5 i! A, q" ]
    # load dataset
    - O* M& X8 J1 ]$ Udataset = read_csv('pollution.csv', header=0, index_col=0)
    7 c' V5 c! m" j8 z; Jvalues = dataset.values; Y' A: i  u: X, n' |7 G

    " @* r, ~& e) W( V

    1 J- ]& N# C4 y+ `# integer encode direction
    ! m' i8 M- `/ v- Y0 @encoder = LabelEncoder()+ @8 W' J4 a" P5 d$ t6 ~( E) d% L
    print(values[:,4])- m! C# d7 S! b$ Z+ K* U9 ?
    values[:,4] = encoder.fit_transform(values[:,4])
    ( n  x3 N8 l8 ?* E# ensure all data is float
    # }. B6 b* M: h7 Z7 e: bvalues = values.astype('float32')0 j2 W6 ?  @* [; X$ y
    # normalize features$ j/ z# @# r! T" D
    scaler = MinMaxScaler(feature_range=(0, 1))
    - U, S! r1 ]- O) Bscaled = scaler.fit_transform(values)& C+ ^. K; [/ I# `1 x$ k
    # frame as supervised learning
    " Z) p% h* |* j2 o( y( o5 Creframed = series_to_supervised(scaled, 1, 1)
    ( j2 ~. a/ S6 y" ^9 t#reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据  c8 F( ^' ~/ L
    print("columns:", reframed.columns)
    2 E% Z- B+ A4 o$ k; R# u3 m# drop columns we don't want to predict/ j/ F+ V  h" y- z) R
    reframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据; O" M. w; t* V$ Z+ U- }
    #reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据- m  X$ x3 x$ e8 y/ b+ {) D
    print(reframed.head())
    - ]- r3 |0 {2 g! ^8 Rprint("new columns:", reframed.columns)$ q0 W9 t- u& g2 i9 J# p
    # split into train and test sets
    * f6 |& ]5 J* n# n' Nvalues = reframed.values; f7 l8 I2 X) e  h, G. A
    n_train_hours = 365 * 242 u! ?9 z7 m  H" E2 y
    train = values[:n_train_hours, :]
    0 g. G- C/ z4 K8 F5 ~% Q5 }2 Vtest = values[n_train_hours:, :]. [# j8 o/ o4 L: u1 c
    # split into input and outputs' A1 \- v: x; N) e! r: a
    train_X, train_y = train[:, :-1], train[:, -1]7 v! S. C7 F8 V: s# Z6 ?
    test_X, test_y = test[:, :-1], test[:, -1]
    4 k9 A# K% r. H: R# reshape input to be 3D [samples, timesteps, features]
    9 T9 w3 F( t2 ?5 o* K+ @# ]#使用Dense()模型时不用变换
    ; D6 i2 i1 K% A7 @train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))& O' F: L* y6 c# A1 _
    test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))  U3 ~, x4 g; T2 j+ e% W8 ^% e: `
    print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)6 k/ Q2 n: Y  w( Q, @- E) n5 X/ w
    # design network; D. d7 b$ I& b
    model = Sequential()3 X' y7 {6 w5 N- u8 Q9 ^4 l
    #model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2]))): _" }& B; O: n0 {- v. r/ o
    #model.add(Dense(50, activation='relu', input_dim = 8))
    ; z" q1 m# c( q! g  @. kmodel.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))7 R3 G( }3 o3 [! O/ R
    model.add(Dense(1))8 B$ n/ y/ L8 ]; M* N/ ]
    model.compile(loss='mae', optimizer='adam')
    - I' Q  G9 n; E' k# fit network1 y2 n7 H% f( G- Z
    history = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
    6 d. h6 l% g* `0 A  d- |! @# make a prediction
    ( U; ?) ~- z/ U# p+ \: cyhat = model.predict(test_X)
    % L: ]0 m$ H  F; \9 o+ j0 p# w* qprint("yhat shape:", yhat.shape)1 Z7 y3 `, c8 o+ r) f* Q
    '''
    ) H0 I7 ^9 ~1 C1 G计算在测试集上的均方差
    6 h! Z4 c% m3 \' {' M/ {* {test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))( W0 B; b' N. ~: A- y' k
    print("test_X shape:", test_X.shape)- a! P: J8 L8 p! P

    9 ^8 F- u8 t. a' Y+ P
    $ V+ N/ k, u6 Y! l' n+ j
    # invert scaling for forecast
    ( @- O/ R) D" T( G3 Z8 s! }inv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)  X0 [. i5 @% ~3 S+ t3 ~
    inv_yhat = scaler.inverse_transform(inv_yhat)
    ' ]# j- Y/ d+ n) pinv_yhat = inv_yhat[:,0]
    " ?# C/ p9 N: r5 x  g# invert scaling for actual
    0 U! m& X$ `, D* W5 s0 m6 Stest_y = test_y.reshape((len(test_y), 1))3 T3 M. q, P0 _$ i
    inv_y = concatenate((test_y, test_X[:, 1:]), axis=1)
    ! A$ Q! h1 p1 t) oprint("inv_y:", inv_y[:10])
    : C5 [1 M* F, `) Eprint("inv_y shape:", inv_y.shape)
    % C4 a7 U3 c  I2 m# c, F# ~5 i# g4 a/ `( y6 D2 X& T
    % S3 Y+ f8 O* R+ K
    inv_y = scaler.inverse_transform(inv_y)- H! E' F; }( s; x( U4 M
    print(inv_y, "*"*30)  a; U  m: D: j4 l7 a: T5 c! K

    8 P- D& M& r. @4 {0 ~9 Z& T

    & C2 S  K% P4 w9 ^4 N& H( Pinv_y = inv_y[:,0]
    + z6 D6 h# B- `/ S# calculate RMSE/ r: v, k0 G  Q' f% W
    rmse = sqrt(mean_squared_error(inv_y, inv_yhat))% Z/ a8 m) P4 O. E4 q2 }# O, R
    print(inv_y[:100], inv_yhat[:100])8 X  `3 o- g- `/ |' b4 N! {$ [
    print('Test RMSE: %.3f' % rmse)
    " _# c/ t& A9 X% S  x3 t$ R& o" U. I! E" }6 h2 G% H2 Q5 P
    * S( o% h' ^# G  |8 Q' z9 u
    '''+ `2 S0 O7 J) I: U) L9 C8 b* l/ E
    实验结果  ]1 |2 v7 O1 f- r5 }
    实验1:用前一天的天气数据,预测某一天的空气质量
    7 N$ V% Q" e" _& C; p使用LSTM模型
    ) r, E& Z! E; C( z2 }" y结果:( y1 t# ]  c& B2 k" D2 D+ C+ d
    Epoch 49/50
    0 U$ ~; Y- z5 i: [; T, ]3 q0s - loss: 0.0144 - val_loss: 0.0133$ g. Z" k) z  B
    Epoch 50/50$ ~3 f3 U: m  e+ X1 G+ [9 W  M1 c9 b. @
    0s - loss: 0.0144 - val_loss: 0.0133" Q6 B( }/ O3 \; Y0 K' c. r
    % X7 c3 Y, Z: g% T0 K5 O8 k9 |

    5 u! v4 g. \: i* W; }8 D实验2:用前3天的天气数据,预测某一天的空气质量
    " E, e0 y3 c% O5 e1 {0 T- \; c使用LSTM模型! R3 C% r; T) C+ V7 n3 m6 r
    ; |6 ]2 y, B! ^; v9 ^! Z; S' d9 e. V
    % {* G! V: O, N' s
    结果:
    % ~! M5 b3 z# R! `& H& SEpoch 49/50) ~7 e* @5 t  f+ i
    0s - loss: 0.0147 - val_loss: 0.0149
    ! R7 @9 T( \$ x6 ?: y; PEpoch 50/50
      ~4 X2 o: J8 O& O5 T8 J9 P0s - loss: 0.0147 - val_loss: 0.0150
    . Q: B. x7 S6 V, w) O; o
    4 O. G" N  V  M

    # X! E% e) E$ o2 Q3 `实验3:用前一天的天气数据,预测某一天的空气质量
    1 R8 ?% C  x3 I5 V5 r/ |使用普通的全连接模型 Dense()# }2 h; N0 }, s$ F* d/ [  e
    结果:4 N5 I8 K$ |) h0 j
    Epoch 49/50$ V9 R. W# K- j$ O9 ]
    0s - loss: 0.0144 - val_loss: 0.01468 Z7 [+ G3 g; l8 J1 k. c' F
    Epoch 50/50
    : T6 l: r4 o5 h6 H5 [+ r7 r0s - loss: 0.0148 - val_loss: 0.0151: r" }$ M$ f4 ~  T' ?

    0 T# [! A, ?8 r* L

    ; \  D! R2 {2 Q. j3 S( A" u实验4:用前三天的天气数据,预测某一天的空气质量
    $ U+ _2 \, |/ V使用普通的全连接模型 Dense()* w% Y+ O" `" s0 G. y" G9 }4 c
    结果:
    4 \7 z2 q6 }; s: B) O/ ]Epoch 49/506 V# Y4 }# C9 q# a- p( n0 J
    0s - loss: 0.0150 - val_loss: 0.0165
    0 m1 C! g7 U) Y0 i3 W; DEpoch 50/50) C* V6 }2 ~, m" \: n/ \& ^
    0s - loss: 0.0148 - val_loss: 0.0141! L  a; G9 n" Y9 W4 |# ~

    3 j; w& [, ]2 |

    . c; t" t% Z& v) s  F5 d% c实验5:用前一天的天气数据,预测某一天的空气质量
    & o7 C6 u$ R1 T* I使用SimpleRNN9 _" I  @4 n# q, Q- D4 l
    Epoch 49/508 F4 |8 \+ \( s" I9 `) ]4 v
    0s - loss: 0.0160 - val_loss: 0.0140
    + A; _9 n9 m! r' x. |+ J- f2 ~Epoch 50/50
    0 y( H; ^4 q3 h: A. a6 l# d0s - loss: 0.0147 - val_loss: 0.0150' j# p) U$ S! Y" W' I5 e% B/ G3 N' ~/ p
    2 c! @' H, ?( g
    - h* R7 ]0 u/ I' C* H: X
    实验6:用前三天的天气数据,预测某一天的空气质量; S9 X2 J8 ]1 T1 ?( n3 V! i  {
    使用SimpleRNN$ a, p! Z! `" e8 L
    Epoch 49/50
    " T- m# v& x3 }9 H, W0s - loss: 0.0164 - val_loss: 0.02336 E2 j1 H2 U. d+ W
    Epoch 50/50
    ) B+ o/ O) [9 ?. ~! D9 ~3 R6 y0s - loss: 0.0166 - val_loss: 0.0227" O9 E' i4 x. M7 b' V8 b5 b
    RNN和DNN的区别

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


    + z9 b1 u/ \) i5 x* Y

    # ]& O, T0 [4 r$ Y7 P; U
    1 Z/ N1 [) [: N& G2 K7 B
    RNN和LSTM的区别
    9 X8 g! u6 j/ D6 A) s  N. L' FLSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。" s' z: K/ Y) V. z

    3 [  g8 H$ [/ N  K5 o( g( r8 g" S% x9 b
    1 Q1 r# t9 F8 ~' g/ B9 g8 p
    但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。: u' E; y! _0 W/ g7 z- W
    4 J: G* i: }5 I

    , r5 [# O2 g, `4 ?" U: }6 \& w9 H: t6 @请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员
    * v' |! i/ i, y, _
    ! p+ _& R4 ~; M$ K
    : ~/ F/ C! Y9 q" }. h# a; v
    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-9-13 06:49 , Processed in 0.536690 second(s), 56 queries .

    回顶部