QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4366|回复: 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预测时间序列数据
    9 L9 u( u; {4 [
    : z7 Q) w" j% L( l
    6 d0 ?' S8 Z9 c( j
    文章目录
    / S" L/ X9 z0 ]4 I- j背景
    & m$ M( r& j; p; s结论
      }' z7 j- z$ \. U4 Y! A* u代码
    : o2 j3 @9 {/ e3 P1 k( P4 M实验结果
    4 R" y1 [1 O# V9 ?% B* ARNN和DNN的区别! x* k& x- q9 I5 p
    RNN和LSTM的区别
    + G6 V/ V: A* F$ Y. T背景2 p5 I, D1 x7 u/ d3 v
    复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验5 H1 j8 p' S2 ~+ \1 y7 `) D
    熟悉用LSTM模型训练7 E; }/ N, i: \3 h7 R0 Z) o7 e% k7 F
    验证将时序数据 转化为分类问题后,预测是否有效果
    / l8 [7 J+ R/ |9 N4 h% J对比SimpleRNN与LSTM模型 哪个效果最好?
      M2 i0 v) @2 ?( B4 Y验证LSTM相比于Dense()模型 是否有提升?
    * ]; \) j3 v" I3 `' u/ X对比使用前3天的数据 和使用前1天的数据 哪个效果最好?
    6 k$ V3 u' k% K7 r结论: J! {8 L! U* S% g0 C6 q( l; D
    使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好: F' v  B% u- q' U; P
    使用LSTM的效果优于SimpleRNN" [' R0 g6 _0 A! y
    代码6 i4 X. H6 u4 u6 Y3 B( b
    from pandas import read_csv
    9 x8 B8 e, N6 ]7 Y5 O5 Z# ~from datetime import datetime& B0 D# f7 z2 x0 `) L- \
    import pandas as pd8 y/ d( c, r/ R# o, i2 s
    from pandas import DataFrame
    % K1 J, P' _7 z( y6 ?- pfrom sklearn.preprocessing import LabelEncoder,MinMaxScaler8 J9 I- H- X6 m+ `0 a: C
    from sklearn.metrics import mean_squared_error" [3 \- h* s  M
    from keras.models import Sequential
    # E  r9 X$ z3 k  hfrom keras.layers import Dense, Dropout
    * O" U& Z8 |$ c! I9 ^* \7 [from keras.layers import LSTM, s( ^8 L! Z. y5 O7 x6 t; E
    from keras.layers.recurrent import SimpleRNN
    $ Y8 M2 i' Y# efrom numpy import concatenate9 n+ w7 b7 Z& X4 P
    from math import sqrt) T- @$ F0 c; q, {1 Z
    ' G8 ^, |/ d6 ?% l: o

    ) Y1 d' O1 U% l0 b& u2 ^- B/ h* d, T6 J) D2 ]0 O1 f- ^; k

    ; r  }* l* q2 F# load data: I# R! I( X9 l5 ^! y
    def parse(x):+ ?' F) u6 A: m1 s/ i
            return datetime.strptime(x, '%Y %m %d %H')
    4 v( H$ f. S# N9 N, E  |
    - h2 P' o/ N3 e+ Q8 vdef read_raw():/ Q0 f. E3 _$ p8 C. U, C
        dataset = pd.read_csv('raw.csv',  parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)
    7 u( E3 z* Y" c# o0 N6 {  w1 X0 C" W" b    dataset.drop('No', axis=1, inplace=True)) B" q0 j8 @" L3 R
        # manually specify column names% @  V# N) P8 {% r2 B( A
        dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']  s3 {+ t) s+ Y& p7 ^
        dataset.index.name = 'date'
    7 ^7 F$ O1 N  g: A2 k    # mark all NA values with 04 H$ L7 }- C  e7 g4 [
        dataset['pollution'].fillna(0, inplace=True)  ^4 N0 X# q/ [0 [
        # drop the first 24 hours
    ' i9 P6 H  Y9 o" x; q    dataset = dataset[24:]/ u" P& e% ~" [* n& C) k7 u
        # summarize first 5 rows
    7 Z, ]  ]  G2 [8 W  R: f5 ^    print(dataset.head(5))+ V) c2 u) J, _- i7 A1 O2 p
        # save to file8 E( c) `; n) _; l5 ^- |% L1 l
        dataset.to_csv('pollution.csv')
    3 N& k; z" k4 V& m
    + H0 F3 \$ L3 @) M' T4 c. h1 y$ S

    2 A% Y( d. }2 u7 M" q- }" o3 m. ?) g9 l$ _* B: i( \

    8 i+ Y4 _0 T: P# convert series to supervised learning
    4 V$ R. c2 N' B3 `2 Wdef series_to_supervised(data, n_in=1, n_out=1, dropnan=True):# y8 s0 c% }% |6 i
        n_vars = 1 if type(data) is list else data.shape[1]8 O( T7 z( _3 B9 ]2 i' }  n7 T
        df = DataFrame(data)
    8 o& B5 j8 B* I" N; k2 M" b    cols, names = list(), list()
    : j1 U& `) a( D0 P. J5 d) }% |    # input sequence (t-n, ... t-1)% Z  P1 x# a# _( o, T# L! j% ^" o0 a
        for i in range(n_in, 0, -1):* `( X" m! R) P: X% _+ A
            cols.append(df.shift(i))0 v4 e; P% E/ T. y" C
            names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]; t: C! D- A& }2 G9 \; t0 B" E
        # forecast sequence (t, t+1, ... t+n)6 q7 I2 B0 @9 C# c
        for i in range(0, n_out):
    % d. m% i6 _* u        cols.append(df.shift(-i))+ O% v1 E; i: F6 G; P
            if i == 0:
    2 {1 I! A3 J2 ^/ Z" m            names += [('var%d(t)' % (j+1)) for j in range(n_vars)]- y2 I- G8 L5 B" b" r2 d
            else:9 V: N. d' t4 N
                names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]; B3 S% w0 V' V5 e! m
        # put it all together
    4 [' s* y/ n8 z. \4 S/ k    agg = pd.concat(cols, axis=1)
    + R9 ^- Y* Y+ G- e  r  [    agg.columns = names
    + X" W$ G$ z6 a% t5 l    # drop rows with NaN values
    ; c" \7 [% ^3 C/ z6 U& ?' p    if dropnan:  D* e  u" v/ _
            agg.dropna(inplace=True)0 l0 f% f6 j0 \3 J# p4 ], ?
        return agg
    ! t. a3 L& N8 t& r : \* L4 A3 k' K" d/ R
    # load dataset
    ) u" E) H2 K2 x, t( Z% q: }7 U6 jdataset = read_csv('pollution.csv', header=0, index_col=0)
    , [9 R9 `9 C/ q& _: |) Z" ?values = dataset.values1 r6 n' ?1 r/ v& ]- v
    0 C* u: ]/ L, D, c9 {, U* ~3 D; n
    / }! X' W$ {! L. z
    # integer encode direction
    5 y+ D% G! J2 U7 l0 x! F9 cencoder = LabelEncoder(), E9 ?& S8 ?  R" T; r
    print(values[:,4])
    6 |. G# X/ p7 ?1 a' l7 p1 evalues[:,4] = encoder.fit_transform(values[:,4])
    7 ?* {; Z3 Q6 a; p* _9 X" `# ensure all data is float
    - X5 j. u8 m: e$ w" m  r4 ^5 ^# wvalues = values.astype('float32')
    # j0 K. u- m8 ]" ?% y8 L# normalize features
    8 j3 J, J. ]) O  u% @, U: Q* v5 o2 pscaler = MinMaxScaler(feature_range=(0, 1))
    # {: l% }* H% _6 P7 n; z4 |scaled = scaler.fit_transform(values)
    - ]! y& h! y+ n+ `# frame as supervised learning
    % d* o7 T. ^" ?' V6 f- H1 M9 A0 ]reframed = series_to_supervised(scaled, 1, 1) ' R( Q* w; C5 n$ d9 R
    #reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据% L/ p# q' j* ^3 Q" o- m1 \& j+ C! _
    print("columns:", reframed.columns)6 B2 C& |- C% |9 P" f3 u
    # drop columns we don't want to predict
    5 R- z" M" `7 r2 ureframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据
    2 `& z: E" {. J) t5 Z8 u#reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据
    : r9 e) Q4 S5 _8 J& v( sprint(reframed.head())
    & @3 _$ `7 f# O# Zprint("new columns:", reframed.columns)
    . q& B: T9 z9 B  o; W# split into train and test sets; D- i( p, k! D- q' N- s6 B- _
    values = reframed.values% N* @' d. _" p3 M4 x# T: u$ R
    n_train_hours = 365 * 24) U; _* I5 N& r& {# U6 R* A
    train = values[:n_train_hours, :]+ {, c. j! }, N
    test = values[n_train_hours:, :]
    ) ~( s3 q1 R7 }" Z, E# split into input and outputs
    6 o. q6 c5 A+ L8 gtrain_X, train_y = train[:, :-1], train[:, -1]" {+ w/ m/ S* ~* g
    test_X, test_y = test[:, :-1], test[:, -1]
    ) g8 @1 Q# K( _5 f+ G, L# reshape input to be 3D [samples, timesteps, features]
    / O3 |, d+ L+ {( A% Y) T$ M#使用Dense()模型时不用变换
    4 O6 P/ G' q7 htrain_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
    8 v" G* ?0 [# j; Q$ Ctest_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
    - h2 i( _: S8 o% @$ Qprint(train_X.shape, train_y.shape, test_X.shape, test_y.shape); o* g& |  s, n0 y; o. T, T
    # design network* z6 x( d! h2 c( ~' \3 f
    model = Sequential()
    0 A7 @/ e9 z/ O! u$ R+ c# `* [# Y+ D7 Q% s#model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))2 Q' R( W( A  B
    #model.add(Dense(50, activation='relu', input_dim = 8))( `1 I# W5 z6 k4 P- F0 a6 J7 G0 _
    model.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))
    2 U/ p4 o! _% h  r  cmodel.add(Dense(1))
    ) F% b2 U& [: k4 R' ]: Wmodel.compile(loss='mae', optimizer='adam')/ ?# ?: u$ P4 ~2 U& T# C
    # fit network2 x2 }: N% Q% ]" }
    history = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
    1 v2 z3 J9 E) z# G' x# make a prediction- F$ r8 X5 l) X0 t. h) _( f
    yhat = model.predict(test_X)
    ' |0 Y) S; d3 Q: V( rprint("yhat shape:", yhat.shape)8 `, P$ m$ c& ^
    '''
    4 C/ [' w: N0 ~& `0 w/ T- V' D计算在测试集上的均方差
      W, F$ ~7 b7 Z' {7 o7 H$ M! Ztest_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
    1 }6 f4 k) u; a( O3 iprint("test_X shape:", test_X.shape)# a, ^% t1 T, r, I# l3 H, {
    1 ~" a3 o2 H6 e$ E" d! v8 {% {) E
    9 H0 {1 I8 [' F- e7 l- v, ?) e
    # invert scaling for forecast5 |4 \" Z, B" {* A
    inv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)
    / @' j: `. N$ ?6 ]5 L8 {- Z1 [inv_yhat = scaler.inverse_transform(inv_yhat): o, x" Y7 m+ t- U* _( y
    inv_yhat = inv_yhat[:,0]1 R+ U, _( x) x$ Z& |* Y+ p
    # invert scaling for actual
    5 e" e+ I0 d$ Z6 R6 y0 wtest_y = test_y.reshape((len(test_y), 1))5 _; S6 E: [) ?- D( r1 I- u; m* _
    inv_y = concatenate((test_y, test_X[:, 1:]), axis=1)
    / Z+ n7 C2 t$ zprint("inv_y:", inv_y[:10])( Z8 w# K$ U7 D8 e9 N/ c) R
    print("inv_y shape:", inv_y.shape)
    7 `# S) P* S  x* O- [, ?/ g" I( I  f* Q: {
    $ G5 h- v. ~# G6 z, Y  f
    inv_y = scaler.inverse_transform(inv_y)
    . \) }3 K; }7 J6 n5 W  a+ nprint(inv_y, "*"*30)0 Y/ V! n$ G4 z* G& z0 z0 t4 z& s
    + m9 l( p4 o3 Z9 k  C
    $ t$ D, P9 q( Y! W) A3 p* V% k
    inv_y = inv_y[:,0]# }7 g+ i5 v: x3 K, N
    # calculate RMSE
    2 @; J7 I4 ~! Nrmse = sqrt(mean_squared_error(inv_y, inv_yhat))
    ! ?) t# g6 }) Zprint(inv_y[:100], inv_yhat[:100])3 P5 i" W' j9 |( R+ w* m4 J% \
    print('Test RMSE: %.3f' % rmse)
    ' H  A7 P( v- T; U4 J4 P4 B1 H' i# v. ?- b) A. t& P  `) y
    9 u% |( @2 g+ ?7 W
    '''
    : m( C0 d$ ]: O6 i# K3 s实验结果
    4 E5 p/ D+ r8 Y2 G; C% G
    实验1:用前一天的天气数据,预测某一天的空气质量
    ; |- j* \& D/ a4 h$ C9 X使用LSTM模型
    ! d$ a+ u, [2 h8 V结果:" ^2 P5 e+ b1 S% S% D, L7 ^2 L
    Epoch 49/50; S+ Q1 F+ q6 F% Q$ [3 Y. m
    0s - loss: 0.0144 - val_loss: 0.0133
    & Q* h6 d" V2 G1 LEpoch 50/502 O1 z% s& V* S5 @! J6 d
    0s - loss: 0.0144 - val_loss: 0.0133
    $ s0 A$ ^' _% u4 l( u! U
    ( U2 @& U( z6 B0 L& z

    : s. C" a6 T0 ]: U( }实验2:用前3天的天气数据,预测某一天的空气质量
    0 Z: a5 I7 U" a" b3 W使用LSTM模型
    : H$ b, G6 B8 Z3 \
    . o1 n5 n4 s6 O3 s3 ?
    " a- u  I; k2 Z$ b
    结果:. z  i4 \0 ~& B  D3 }
    Epoch 49/50
    3 U% h5 u* N1 ^3 e4 T0s - loss: 0.0147 - val_loss: 0.01497 F8 K; L$ }; W7 e7 N3 k
    Epoch 50/50
    ! K. G, R% y: B- o0s - loss: 0.0147 - val_loss: 0.0150
    3 F9 [* D' C& P  K4 O4 H7 `+ T$ K6 K% K7 O9 c+ T- j
    2 M& {8 Q; B( D  I
    实验3:用前一天的天气数据,预测某一天的空气质量- f; y, r1 y8 g
    使用普通的全连接模型 Dense()+ ?- g' Z" P5 K; Q, y& D- a
    结果:
    3 T( y) b6 ~/ _Epoch 49/50
    9 K& y4 B/ D% H0s - loss: 0.0144 - val_loss: 0.0146, `4 S% x& X+ n$ b; O9 ~
    Epoch 50/50
    ' G% f8 ^1 G2 H! q  c; X% h& m9 a0s - loss: 0.0148 - val_loss: 0.0151
    ; R* K7 [" g7 f) d* J
    , H% Z1 r, p  n: j- s
    : D& U6 B6 a0 A* C( R# i7 a
    实验4:用前三天的天气数据,预测某一天的空气质量
    4 J. H! F+ b" w! A/ {2 D使用普通的全连接模型 Dense()
    9 G& A2 b# F' a6 I$ ~9 B结果:
    / j5 n6 q" Z+ J& |Epoch 49/50" X$ @. f& u" g  @* @
    0s - loss: 0.0150 - val_loss: 0.0165' g' J$ s1 T! S- s, J1 }6 ]& i5 b
    Epoch 50/50' ^6 B( f1 _% R+ X1 T" ~1 `
    0s - loss: 0.0148 - val_loss: 0.0141/ R/ l+ m8 K. O/ S$ O, t/ A" M
    ( ^! l# o( x1 `8 J( ~7 ]) R  d8 {6 c6 u7 ^

    # F( p2 \8 r0 P实验5:用前一天的天气数据,预测某一天的空气质量
    0 }+ y' Y9 l2 x& n9 Q0 ]使用SimpleRNN
    1 O, r. Y& r* a5 A+ `% y* qEpoch 49/50( x& ?9 K2 s0 ?6 [& S, t
    0s - loss: 0.0160 - val_loss: 0.0140! f* ~) u$ ^- S  R' X* W6 H
    Epoch 50/50
    : _7 m: r3 U! A0 x8 o6 g, u9 k1 `7 L0s - loss: 0.0147 - val_loss: 0.0150
    % v6 Y5 ~: s9 ], g. U# [' @. j' g. Q

    - d% W% x* H' m8 Y* C* f- R实验6:用前三天的天气数据,预测某一天的空气质量
    ; L. g8 ?# H! L9 C+ u使用SimpleRNN$ f8 i: A2 L' O; ^- \5 x' P
    Epoch 49/508 n4 _* O& a- j/ M. j% c3 _! T
    0s - loss: 0.0164 - val_loss: 0.0233/ c* U# m9 ]) S* Y( y& V8 L$ O
    Epoch 50/500 ]" U: k2 }) g8 J" `3 G' G# _
    0s - loss: 0.0166 - val_loss: 0.0227
    # e" f$ O9 _8 _2 N7 ^, S3 vRNN和DNN的区别

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


    , a- a7 Z( z2 Y, q8 p9 V
    : b3 y5 c, w3 K; L# w. w7 l( A3 J

    ) p, I  T$ `( u+ A% S" u8 r, m/ {" ^+ K
    RNN和LSTM的区别: @, E. Y4 H2 [4 n+ r3 ^
    LSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。9 Z" l) U5 x( r

    - R! w* k0 n/ l" ~

    / `7 C% y2 @" N- [  P# F3 X4 w但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。' Z3 T7 ]3 s" t" Y- Y7 n

    $ M1 t+ ]: G9 i( }4 a. S
    8 Z0 F) p5 G8 _6 J8 S. y5 `请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员
    3 b+ b% h& \( c, ~& J

    ' V- Y4 w( D1 |& v5 c# \- [- ~+ g3 j8 g5 G! Q8 T$ p6 E
    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-6-10 19:00 , Processed in 0.414167 second(s), 56 queries .

    回顶部