QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4467|回复: 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预测时间序列数据/ Q" t% E4 Z/ p
    & f* b  \  _$ E% H& D

    " y& l' f  u( |: f6 w' H$ I文章目录
    " |# r. n# r! f, l% D+ x背景
    . @' g, B  f$ c结论4 i  K, c5 C- ^- N$ z) Z( c( s$ X1 O: ]
    代码
      N* r, o( I0 @1 W- ~0 Y实验结果) v' a! O( Z" Z2 S; o1 T
    RNN和DNN的区别
    ! V6 M+ E) Z* r( f& `RNN和LSTM的区别
    # G: P: I" Z1 Y5 [7 E: k" w背景
    7 [8 p% K2 j8 l4 R复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验: G" G7 T! ]. z6 g% b
    熟悉用LSTM模型训练* j% F0 c8 T% _( D  e; g
    验证将时序数据 转化为分类问题后,预测是否有效果  e7 I: V" D" r
    对比SimpleRNN与LSTM模型 哪个效果最好?
    + q# q7 }: ~! _: l, E, i1 a验证LSTM相比于Dense()模型 是否有提升?9 G( t7 ]4 ?+ C
    对比使用前3天的数据 和使用前1天的数据 哪个效果最好?- c  {% r0 q' f' d" p5 O
    结论
    ' t5 K5 M+ A, R  ]  X2 P4 I( @使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好
    9 D( E& y/ F2 k. {使用LSTM的效果优于SimpleRNN
    " }' M% ~1 {7 p" {# R) M+ c  J代码
    : F: _# s4 d6 H/ ffrom pandas import read_csv+ t2 Z# c1 L# V( F- o* D! `; O
    from datetime import datetime$ d8 v/ `  P! ^3 T/ o/ a. N! i
    import pandas as pd
    ( ~: W% O- C* m, y  e- hfrom pandas import DataFrame: S2 a' [$ R% L' t
    from sklearn.preprocessing import LabelEncoder,MinMaxScaler
    " k7 j9 i  F9 A7 ^6 dfrom sklearn.metrics import mean_squared_error4 `% S; ?0 r3 b. d; E5 U" N1 {8 `
    from keras.models import Sequential
    ' k, x0 A) N' I2 f! g  u/ q! cfrom keras.layers import Dense, Dropout& L0 `* d5 T9 |* S" Q
    from keras.layers import LSTM
    3 \1 b$ e% @! `; E& H) I: s; ]from keras.layers.recurrent import SimpleRNN
    1 T9 {- m, G( ]( |, ^1 E7 Mfrom numpy import concatenate
    ' P# s! c3 y- E$ cfrom math import sqrt
    ; _2 n$ J# ~6 s. \6 i+ F
    ' L5 I+ ~# [' L( ~: ^
    1 P, I" q) l4 _- Q( x
    & D/ P  U8 U7 A& Z! G4 M
    4 K3 T3 {3 N6 @. \& O
    # load data0 g! I; }( u" q& p* I1 [
    def parse(x):
    1 j, Z, R' Z: Y1 q9 R8 f        return datetime.strptime(x, '%Y %m %d %H')
    1 G  H" E9 H+ _; W0 b3 q
    - M' ?! n4 l; ddef read_raw():
    9 q9 J9 i, m3 [0 ^    dataset = pd.read_csv('raw.csv',  parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)* X% t( ^/ ?; {' R. K) }8 Z
        dataset.drop('No', axis=1, inplace=True)% ^# V  a; a' ?2 `
        # manually specify column names1 M. I$ W5 g* |" B- c- I
        dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']1 j# W  `+ r, I! `+ o0 d
        dataset.index.name = 'date'$ z2 P4 _" m& n4 |" T, F
        # mark all NA values with 0
    : N) |  M" K+ |5 P7 b    dataset['pollution'].fillna(0, inplace=True)4 J. B! G' I0 Y4 n
        # drop the first 24 hours
    $ k# R+ b6 v" D" x9 ?8 k    dataset = dataset[24:]( _. e( ~  g2 \) d
        # summarize first 5 rows+ O2 }. s7 `2 l! ~
        print(dataset.head(5)). _* z8 @! f6 z; G% z
        # save to file
    % Z  X/ A$ f+ E( T    dataset.to_csv('pollution.csv')
    8 r# a' ?% K9 M' Z
    6 R  ~) o- ?7 c) x, X7 y8 ~
    9 ~: ^1 i5 B% k4 h+ a  W+ V/ n- p

    - M4 j3 ~* X8 ]: F

    # _* _8 @4 b  k0 F+ V" u% s/ g; ~# convert series to supervised learning
    ( A5 P( ?3 O) Tdef series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    ( c% l/ _: x: }    n_vars = 1 if type(data) is list else data.shape[1]0 ^9 A6 ]$ v4 Y: a6 \$ G" d" R
        df = DataFrame(data)
    8 ~5 y- e2 \6 F7 |, j. W    cols, names = list(), list()
    0 Y# n) a- h) ]    # input sequence (t-n, ... t-1)
    . t3 u% l/ {, j) \$ W9 P    for i in range(n_in, 0, -1):* X0 y& d% S, I+ n
            cols.append(df.shift(i))
    7 s2 {( |, R! I& y$ `        names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]6 `3 F$ ^7 v+ x2 h% ?; f% b7 ]+ |" c* w
        # forecast sequence (t, t+1, ... t+n)
    % l1 x3 ~1 E  j% M    for i in range(0, n_out):
    - H5 a* a) i) {- O& T        cols.append(df.shift(-i))
    6 k0 {- W2 ]$ }, S! s5 I* H/ {( U        if i == 0:
    - A) z# ~7 L: Y4 C, r+ d) N6 z            names += [('var%d(t)' % (j+1)) for j in range(n_vars)]8 F/ Y; M5 \1 q9 v. c! W3 u
            else:/ p$ g$ P8 b" W, [9 ]
                names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]# g( j* \, L/ u: {4 \3 @9 _
        # put it all together
    8 Y2 k. p8 J( K- d; B0 m2 U& f    agg = pd.concat(cols, axis=1)
    $ l2 E* c6 ~: z% h9 b# P) N+ A    agg.columns = names8 [# v6 e! W! S+ q1 w' W9 @
        # drop rows with NaN values
    5 S* \5 E! @& i. h, F  ]$ g( E    if dropnan:) D) D' v$ M6 ?; A
            agg.dropna(inplace=True)7 k% |( i8 m0 A) F8 ?5 x
        return agg' u% \9 A, R$ {% j

    3 W: T" C" g* [9 g/ Y5 e# load dataset
      F8 E1 f% u7 y/ G, R' ]  Y$ P% e. ddataset = read_csv('pollution.csv', header=0, index_col=0)$ D! U; t7 ?! f4 O& t
    values = dataset.values
    % O6 O; z5 x9 J- b+ l" v# h( Y5 ~
    ' h' N' H3 M  B. e! O$ K
    * u! Y4 l9 _+ ^+ J, f0 a7 x" b
    # integer encode direction
    # D8 y  Q  W3 L/ Rencoder = LabelEncoder()
    7 S1 I* I3 R3 Q  ~9 M& Z& \6 _5 |+ z! Qprint(values[:,4])
    4 S# c* r/ _+ ?  svalues[:,4] = encoder.fit_transform(values[:,4])
    8 X1 y& H3 L$ j# ensure all data is float7 E4 u: a; D% Z1 A. S+ a$ \" n% D
    values = values.astype('float32')2 U! T" g$ S6 f, L
    # normalize features& z6 }( Y8 N+ K0 j
    scaler = MinMaxScaler(feature_range=(0, 1))) I7 Q$ X& A( G5 p
    scaled = scaler.fit_transform(values)
    - b& L7 S' W; n+ R# frame as supervised learning
    ) U$ l& L$ q2 Oreframed = series_to_supervised(scaled, 1, 1)
    , f: c+ _& h3 b7 s9 _#reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据% K3 ~( u3 m% {
    print("columns:", reframed.columns)" n$ J2 I) L/ o0 w! c$ N6 D
    # drop columns we don't want to predict. k7 r& _0 l! q1 h4 o
    reframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据& E* r: t* E) g
    #reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据: f- C2 `+ [- x
    print(reframed.head())# t4 c5 K% P  q$ W: t# j# U8 d# ]
    print("new columns:", reframed.columns)/ h3 @; Q7 E3 g1 z
    # split into train and test sets3 T2 ~4 l& E- c
    values = reframed.values4 s  Z2 x1 ^( R6 d0 G2 P$ Q
    n_train_hours = 365 * 24
    ; e' s" P. _5 qtrain = values[:n_train_hours, :]- i; G+ ~( x  w0 {* ]
    test = values[n_train_hours:, :]3 z5 V0 v7 e7 D0 }
    # split into input and outputs
    6 O3 b0 [2 m4 B- q" @2 t% `train_X, train_y = train[:, :-1], train[:, -1]% l7 W, \. \  q+ o" {( A
    test_X, test_y = test[:, :-1], test[:, -1]" m* }: b: \% d5 @8 R0 ~% s
    # reshape input to be 3D [samples, timesteps, features]0 S# [  I$ r/ E" G0 u
    #使用Dense()模型时不用变换
    % \; L' I3 ^$ l+ ctrain_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))& C/ E; T6 R% B& E+ a% u3 W
    test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))$ H, K# K: u6 w6 e; f" ^  k3 F0 Q
    print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)* t! j- i" W8 U3 w; ?  n1 A
    # design network
    6 M+ a6 {% g; _model = Sequential()# i! k% w0 D6 C. J7 b. w6 p
    #model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))6 Y: C+ H( ?) d! j$ d
    #model.add(Dense(50, activation='relu', input_dim = 8))' k* M7 k4 w5 j0 d( m  e; L
    model.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))/ X' d, {9 o1 k# _: Z0 ^5 K
    model.add(Dense(1))
    ( ]7 b9 X( k& ~! a+ g0 H4 wmodel.compile(loss='mae', optimizer='adam')( H8 A2 P; c9 z( U# J3 [- g
    # fit network
    5 D" P7 d9 S/ `' u# V1 y% O( S$ Rhistory = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
    5 s% N1 @- e- r# make a prediction
    2 O1 N- f; Q& C7 Y' {+ fyhat = model.predict(test_X)5 ]; ~. |; l( }' U: d
    print("yhat shape:", yhat.shape)0 H' o7 ]& w0 {' e- J' i
    '''6 ~/ z+ \4 q, h+ \: K
    计算在测试集上的均方差
    ( ?- c( O0 u  X% e* B$ ~0 W! [test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
    9 H! q9 e6 d, b% Nprint("test_X shape:", test_X.shape)
    ( T" ]5 Y7 R. r: m' t' }; I& p
    6 Z, g+ X& J$ c  o6 Q
    3 d) q* i* I& ]
    # invert scaling for forecast
    0 g! O! M9 F5 Cinv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)5 w! U# [2 d* ~, ^* {7 N
    inv_yhat = scaler.inverse_transform(inv_yhat)+ F9 m7 {2 R& `. f3 D; P% `3 y) ^% l
    inv_yhat = inv_yhat[:,0]0 \/ X) B' D" [$ i* k' q
    # invert scaling for actual
    ; O1 J- i$ W0 ~" H6 Z- b; e% ytest_y = test_y.reshape((len(test_y), 1))" R. w* Z; k3 J0 U8 n+ j1 `
    inv_y = concatenate((test_y, test_X[:, 1:]), axis=1): g# }' k. ]5 a, {4 I/ I4 v$ K
    print("inv_y:", inv_y[:10])
    & D- m6 N7 ]8 e) W) q& ?- q8 @print("inv_y shape:", inv_y.shape)+ Z4 O; D% f/ E- R

    ( N+ l* W; ~6 e) G6 |

    7 B' _; p0 z7 C8 z  a8 q; @. jinv_y = scaler.inverse_transform(inv_y)
    3 [& X& K- G3 H* H5 g$ P! K; Sprint(inv_y, "*"*30)5 T5 [. G: t/ g; P+ E/ R% ^. _6 N

    0 u# ^, W2 X( \) g& H( {
    ( ]9 b) L6 o! e' z7 C, R% H
    inv_y = inv_y[:,0]. T$ @) F3 N& b' N- S
    # calculate RMSE( Z$ [( w4 X- N2 G
    rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
    : h0 ~$ Z: t* I6 b' tprint(inv_y[:100], inv_yhat[:100])- Y+ T6 k. b! y: \0 n3 S- y
    print('Test RMSE: %.3f' % rmse), L' T9 e! s2 P1 a" `
    & L; w3 |% ^( a- U4 \5 a
    8 I4 Q$ t  V5 D
    '''2 v6 _- q( C* Y0 ?& b6 ]& D! r
    实验结果9 z& L# b2 `* S5 R6 j
    实验1:用前一天的天气数据,预测某一天的空气质量
    & G' J& C. y7 r使用LSTM模型
    ) x0 W+ M0 q" U6 D结果:
      b0 r  C0 K9 z3 e6 k# _5 xEpoch 49/50
    9 l1 Z: f4 t! Q0s - loss: 0.0144 - val_loss: 0.0133; h9 b7 V7 W- v0 Q7 O0 T% i
    Epoch 50/50' H7 R# Y  ]6 o# i9 m
    0s - loss: 0.0144 - val_loss: 0.0133
    $ V  |8 ?  a) M+ A. I. X! F
    * c8 g; h- C. y4 {9 A

    $ A8 V) q6 K; l' x3 P实验2:用前3天的天气数据,预测某一天的空气质量
    # o0 H  @5 ~* i4 q使用LSTM模型$ a) b  D& K6 i2 A

    " _. q' d" X% [) G
    4 b5 A) u2 \( {# R. ~+ k
    结果:5 y3 n- r: u" S) z& G* f" k* e3 S
    Epoch 49/50
    # w& P' y( v: ?& {0 I/ M" q/ `0s - loss: 0.0147 - val_loss: 0.0149  x& {( g* \4 B/ @% b7 G
    Epoch 50/50
    + v5 O: V+ p" K5 \; w5 n0s - loss: 0.0147 - val_loss: 0.0150
    - C$ ]* v3 a0 \9 F  @! H2 `3 D
    $ b# l1 U2 m7 y4 S9 ^7 O$ ^
      \6 U4 P0 C% N: y
    实验3:用前一天的天气数据,预测某一天的空气质量
    3 E3 M4 O* x  A8 O0 F使用普通的全连接模型 Dense()& ]0 R. {$ ^( I5 x9 g2 {7 f  ~8 k
    结果:  _- \5 q, x6 b& s  I* _  L, N
    Epoch 49/50* b( ^! B$ S: I* ]+ a
    0s - loss: 0.0144 - val_loss: 0.0146, {* {0 Y! f8 }% w
    Epoch 50/50
    ( o, c* O5 D9 ?$ q' R3 q0s - loss: 0.0148 - val_loss: 0.0151; H$ K8 z2 g2 p" |# E4 L
    + y# t% F# s& L9 A0 X9 V
    + K1 W, `# g9 l  p
    实验4:用前三天的天气数据,预测某一天的空气质量+ I  B! Z/ V1 S5 }. g  |7 v8 n
    使用普通的全连接模型 Dense()
    * Y* t: \1 Y# S( l结果:, l& F% o$ r. k& ~. Y( P. Q
    Epoch 49/50: U: }! W8 ?" J" |7 F( [+ {% |! S4 T" [
    0s - loss: 0.0150 - val_loss: 0.0165% ~" F: a+ k3 _4 r, x( L+ V
    Epoch 50/50
    + w$ I  z- @9 B0s - loss: 0.0148 - val_loss: 0.0141
    ( n  k' ?' ?7 t# u) j  r* y5 |. \1 T% @0 p2 C6 @% N
    7 `* a/ L- j: I  z
    实验5:用前一天的天气数据,预测某一天的空气质量* ?4 i& o2 e/ q" n6 V1 ~! f
    使用SimpleRNN8 d5 i1 c/ y/ G8 x# J# B/ a
    Epoch 49/50
    & y9 ?; o7 B, J; g$ P0s - loss: 0.0160 - val_loss: 0.0140
    ( H& J  z" B' h& ?. ~Epoch 50/50+ S$ ?  f# z9 f9 `
    0s - loss: 0.0147 - val_loss: 0.0150
    6 j7 \; g/ F- a6 @
    0 i5 X" F5 C/ V8 r2 a! i

    ) L7 z: o- n/ [% S实验6:用前三天的天气数据,预测某一天的空气质量
    ; W; H/ J" f/ d6 A/ {0 w  Y使用SimpleRNN
    6 B  Z! F; H" ~. B& j* z' yEpoch 49/50
    , c& ]$ r& w0 z# G0s - loss: 0.0164 - val_loss: 0.0233
    # {6 r2 p$ G% Z/ d: G! W0 UEpoch 50/50
    , z. ^: A% j4 n7 _* o; Y' `0s - loss: 0.0166 - val_loss: 0.02276 S5 [7 d2 c- c3 L2 d
    RNN和DNN的区别

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


    4 W" `0 c  E4 G( N
    * X& N; i( g, R6 t% p$ {6 F

    ( I+ T! v% X( N& k3 b
    RNN和LSTM的区别
    ! a# S- g! _! w3 e4 PLSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。
    ; [6 G2 U& a, {: m% U2 U; _( b9 a0 T  h% _7 b

    4 y+ d4 z; T! ~" |; F8 K9 L但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。
    $ r9 c, ]3 T1 W6 Y6 K1 N& W4 A0 M4 N* s( s! J7 }; g1 `, O( E3 n

    6 B8 i  P0 I, p7 M' }+ d请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员

    & {, l: q# U7 T7 N! a$ ^9 [6 d- L8 k
    - l1 e1 K* x. \) V+ E# n6 X# s7 Q: |  c, c0 X7 m: m5 O& c# m
    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-10-13 07:52 , Processed in 0.827499 second(s), 55 queries .

    回顶部