QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4413|回复: 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预测时间序列数据) p1 Z/ }/ d6 c- P2 F

    9 `) r2 k$ Y: \- Q6 i
    , t/ ^. t1 Z/ \; g) Z8 ?6 Z# v
    文章目录/ x% t) g. X9 E/ G4 {! [, h
    背景
    # m: |! Z% U/ r" E: `+ c. u! K结论
    ) T7 R; j' Q/ X5 `( M代码
    ( b+ w6 g' q6 l& {实验结果
    + R( X: d  A! ?' I/ v; kRNN和DNN的区别  K0 Z" a; e5 Z+ Y9 i) y) `9 N8 h
    RNN和LSTM的区别
    ; @3 D1 W1 @" V5 L背景! V. M& G! b8 Z# H9 {
    复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验
    / d+ M( n  _' L7 n熟悉用LSTM模型训练
    8 ^) e3 k5 @7 ~5 X; V0 Z验证将时序数据 转化为分类问题后,预测是否有效果0 `- h+ \3 N$ Y$ Y( X9 T
    对比SimpleRNN与LSTM模型 哪个效果最好?
    ( F2 O# _  N% R! J/ V% k$ _9 s验证LSTM相比于Dense()模型 是否有提升?$ {$ D  l. N, w! c. R0 n, _
    对比使用前3天的数据 和使用前1天的数据 哪个效果最好?
    ; j# @  l+ _; R6 x" Q$ a9 O  r  h1 S结论
    5 `3 Y9 _2 i3 ]% a* N0 n5 G使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好( \  R/ |1 w8 T; ~; ~
    使用LSTM的效果优于SimpleRNN  e# x/ i6 e7 j- O' J& d6 e
    代码
    $ w7 _3 J9 v8 ~" @from pandas import read_csv
    7 g5 z" X. ]6 |( \from datetime import datetime1 B% v% Z( k0 K$ h. i; j
    import pandas as pd4 D: \$ ^$ J4 E0 Z6 x  o6 ^
    from pandas import DataFrame
    + K/ H$ I* a+ ~: |% l8 Y5 hfrom sklearn.preprocessing import LabelEncoder,MinMaxScaler
    * [# h- O' a' a! ]( sfrom sklearn.metrics import mean_squared_error
    ' _2 d2 I  h4 k0 Hfrom keras.models import Sequential
    / x3 \" R$ I9 a' F& _8 i/ c# ffrom keras.layers import Dense, Dropout
    0 ~, G/ g0 \3 c5 ]3 f1 J% Kfrom keras.layers import LSTM
    8 G+ y2 a' M- o2 ~  ^5 K, cfrom keras.layers.recurrent import SimpleRNN9 x2 O% c' \- G4 G. N% \  c' i( O
    from numpy import concatenate
    9 \3 ]4 Q( m; s9 q8 ufrom math import sqrt: {1 E5 n: i/ O. q  @4 i1 U! |

    ! |6 P$ [7 S' s2 K2 ^* b
      k( H. y" y, h1 u
    $ J% D  ?4 u. N; p. Z0 u

      L! {) Q0 z& }- a& F+ n# load data
    ) O1 s# a3 t9 \/ ~" q- Y5 Bdef parse(x):
    * s- a6 @' E: u        return datetime.strptime(x, '%Y %m %d %H')
    2 `% s  j1 U( f  S$ ~ # G" ~$ i, |( `
    def read_raw():0 h& _' }& O* _8 H4 _
        dataset = pd.read_csv('raw.csv',  parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)8 W$ O5 c: v! a0 A% D3 o9 A* v8 W
        dataset.drop('No', axis=1, inplace=True)
    / m* c, l1 Z  x0 s, Z1 w  l    # manually specify column names
    & V% s9 B/ F: s: ?/ K' u; Q    dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']
    7 O8 K, z5 ^5 M    dataset.index.name = 'date'
    0 X1 a9 z" i. D1 I    # mark all NA values with 0! f, j/ |( T2 {* e0 X" o9 T
        dataset['pollution'].fillna(0, inplace=True)
    * b8 U& S4 t0 h  Z    # drop the first 24 hours3 _: P, i; f1 f% m: R( P
        dataset = dataset[24:]
    - z% X1 I: f! w9 I( z4 X' I& D/ s    # summarize first 5 rows5 G2 d3 m0 U/ M' A8 [6 i' T! \
        print(dataset.head(5))* T) ~  [0 K, d3 }5 m+ E
        # save to file
    4 _2 V# w* T) f" A- z    dataset.to_csv('pollution.csv')2 u! b7 w3 w2 ]+ u/ [0 L# Q; P
    & M1 `6 E7 s: w

    % ?5 M0 E# U% \6 A6 l; Z& F( F
    : e* \& o2 U! d8 y( b/ c# R
    % Y1 X0 n2 f7 {0 L# Q* b8 s
    # convert series to supervised learning
      X) J( G' Y& S0 @! P" jdef series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    1 l. p1 ~) g6 b0 V$ d) x0 E, T+ @    n_vars = 1 if type(data) is list else data.shape[1]+ y5 `5 u4 ^, W
        df = DataFrame(data)5 R/ l" c% G! F  A, {
        cols, names = list(), list()
    ) u8 q0 f1 E. i9 B- d! K7 z    # input sequence (t-n, ... t-1)
    0 C; I! V. d. c5 S; j! |1 I6 ?$ y    for i in range(n_in, 0, -1):1 s6 v  t# q( h& R1 w
            cols.append(df.shift(i)), Z0 d6 b  K/ f) f& m
            names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
    " a! G6 I! s+ u: s$ P' h    # forecast sequence (t, t+1, ... t+n). L, g0 ]* i  Z4 x: i. W# @& P  R
        for i in range(0, n_out):6 N. D' N4 d. o/ `% w0 N
            cols.append(df.shift(-i))6 q! V( y( x9 t  I# ~  f
            if i == 0:5 l; i# M# M1 T0 P! v+ N9 Q3 s- E
                names += [('var%d(t)' % (j+1)) for j in range(n_vars)]! j2 r5 a0 I3 @, m
            else:; ~. y; }) g1 e% I# _7 [
                names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
    " T. [2 G- R/ a* O, C- c    # put it all together
    5 y1 l# ~* [9 j9 I" C    agg = pd.concat(cols, axis=1)- {8 }) \! v' r+ b. Q
        agg.columns = names
    , w' g0 C' N/ r& _    # drop rows with NaN values
    ' }5 b  V9 }2 B/ g, ?* R  g    if dropnan:1 V) h  U0 u9 T# G% J. W% @: f
            agg.dropna(inplace=True)
    " M+ u4 `" E9 r3 X, z3 C2 f    return agg
    # p" ]( T* _9 Q  s. J7 _
    , R. u' T7 l' D0 o# load dataset; b/ I4 g: u; z
    dataset = read_csv('pollution.csv', header=0, index_col=0)
    4 q7 h3 g1 M/ c8 ?8 tvalues = dataset.values% K: A: g: ?; m+ T( S

    9 Y, k5 l$ a8 c3 {1 }* S

    ( _; u% F5 l) c# F9 u# integer encode direction( S# `1 q8 E7 D1 B! s
    encoder = LabelEncoder()& U3 e+ o4 b3 B
    print(values[:,4])
    4 r( F2 E3 C( s* K+ b% S( gvalues[:,4] = encoder.fit_transform(values[:,4])
    8 t& K! T3 W8 I/ F# ensure all data is float$ `3 R( p7 [# X
    values = values.astype('float32')
    ' J. ~4 X% m# k& \7 }5 F- V  K4 d. y# normalize features' q, N. z# n7 F# g
    scaler = MinMaxScaler(feature_range=(0, 1))
    % A4 J. ~1 @' G" n& K3 Fscaled = scaler.fit_transform(values)
    9 G' @( }9 X) H2 e# frame as supervised learning
    * r/ T) q: {# _  A* [) treframed = series_to_supervised(scaled, 1, 1)
    ) n  K" z) ]' N2 V+ q#reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据' m( K% ?2 T5 I. I) r! a
    print("columns:", reframed.columns)  B$ m, I% V1 C  r! {) j  X
    # drop columns we don't want to predict
    / [7 r- v* S* i3 p3 h$ kreframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据/ P3 T' u9 E8 E9 T7 R1 f
    #reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据
    . Q, s5 x0 h4 \/ U9 i, g! r: mprint(reframed.head())
    - }3 t1 ?( A$ T# k+ \) ~print("new columns:", reframed.columns)* O8 G# |+ C0 C6 M9 O% }/ Y' ~
    # split into train and test sets
    # ?0 z$ ]" b6 f5 P; _values = reframed.values
    4 n  v  T; I2 t8 L6 H9 }n_train_hours = 365 * 24
    4 u: \: W9 r# B# ftrain = values[:n_train_hours, :]
    - H: J$ e: K8 S+ Qtest = values[n_train_hours:, :]
    5 s& O* M6 q" a: U" J# split into input and outputs
    1 x% R6 c. m* R% S/ z3 e! [: [train_X, train_y = train[:, :-1], train[:, -1]- ]9 F" k: _% }0 [
    test_X, test_y = test[:, :-1], test[:, -1]
    4 P/ w0 y6 f  e' v7 f+ w# reshape input to be 3D [samples, timesteps, features]/ I$ o# V4 z! E; q+ K( c3 u
    #使用Dense()模型时不用变换9 M# S- K6 ~7 ]
    train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))3 s7 Q3 [& s4 ~8 o+ f
    test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
    6 k/ K/ m. e- e; [print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
    5 W& R! W+ w, {7 n" K% I/ e# design network( y. V, Z9 _( J1 f
    model = Sequential()- g7 ]' C% A7 A( i/ k0 u
    #model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))3 _( l/ J/ t9 p/ I2 M8 U6 Y
    #model.add(Dense(50, activation='relu', input_dim = 8))
    . v3 U% B2 `& v6 L5 wmodel.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))
    8 \' j* K* [2 Nmodel.add(Dense(1))
    : ~% ~( K  h/ M8 Y) omodel.compile(loss='mae', optimizer='adam')
    / @9 A9 H' J9 h' h$ U4 U# fit network
    5 B& g+ y! h7 s  `, hhistory = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
    + L/ ?: V  V  Q: d) O9 e7 D# make a prediction% p7 b! F1 L  a0 y5 H, W6 m
    yhat = model.predict(test_X)
    & Y1 X' i/ m1 }7 A$ J  Vprint("yhat shape:", yhat.shape)4 {# J" s6 c% Z' p3 k9 A# z+ Z! x
    '''
    8 Q5 `0 E6 Z! O" U" j计算在测试集上的均方差- t% g- f, S. X  V' ^+ y
    test_X = test_X.reshape((test_X.shape[0], test_X.shape[2])): E1 ^7 m+ }0 f; V+ `
    print("test_X shape:", test_X.shape)
    * c$ r6 i% i2 d
    / O3 g* z0 j$ n2 f

    ; `$ Q- {& g8 l) f8 _, l# invert scaling for forecast
    # l, S. Z# k* k4 A; j* h. yinv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)
    ; u: ~# O- A) s* W# x9 Iinv_yhat = scaler.inverse_transform(inv_yhat)
    + U/ @( @6 |6 b# W8 Qinv_yhat = inv_yhat[:,0]- X. H3 d3 T  `
    # invert scaling for actual
    & @+ y1 Z8 k( ]' [5 Otest_y = test_y.reshape((len(test_y), 1)). Z/ @" M2 {% {: q* Q2 |5 A" J
    inv_y = concatenate((test_y, test_X[:, 1:]), axis=1)
    ( g5 n" v9 [2 r/ W; q# X" eprint("inv_y:", inv_y[:10])
    2 P7 \8 K2 }. N/ e- Oprint("inv_y shape:", inv_y.shape)
    0 R/ v0 {$ C7 W: q
    " ^$ s4 }* G$ p) @
    # \( y8 R7 u( j0 \% N4 Z
    inv_y = scaler.inverse_transform(inv_y)4 g0 D/ n' n1 R# ?4 ]. s
    print(inv_y, "*"*30)
    ( y. u' x6 x, C9 k, g' L
    ' l6 {! p4 o: U0 h- y4 `

    / ?( q4 {( D! w7 t3 |: Einv_y = inv_y[:,0]
    ' \0 p) n' K) T3 v/ \5 x8 n% c# calculate RMSE
    & y. Q5 V: Y6 e. V) Grmse = sqrt(mean_squared_error(inv_y, inv_yhat))
    ( R0 O/ Q# A& zprint(inv_y[:100], inv_yhat[:100])
    * v" h* G' r2 g* ?+ Dprint('Test RMSE: %.3f' % rmse)- h) L# f8 T1 g
    " M: r) H; e1 W: j! i
    6 r! @+ L1 @2 ]0 e, ?% p2 P4 k
    '''/ g5 e8 R( K! h. M: j" I
    实验结果. u" C, [( P+ n
    实验1:用前一天的天气数据,预测某一天的空气质量
    ! o$ L4 I$ N# y9 P9 Q- U5 H3 `6 Z使用LSTM模型
    ' y4 T8 Q  E8 n( g3 Z4 I2 B3 J+ c结果:
    2 o  j! L2 K* v. u/ `. A: J9 SEpoch 49/50; P  s# f' t7 k( x. s
    0s - loss: 0.0144 - val_loss: 0.0133
    0 W9 @9 M3 d5 L* H6 m5 aEpoch 50/50
    ' M) g" b( a2 Y% o0s - loss: 0.0144 - val_loss: 0.0133) k3 {: H0 H" W" B+ C' P3 p
    # a' `( h. H6 @
    * h, I; c1 R9 T, ?8 A
    实验2:用前3天的天气数据,预测某一天的空气质量
    ' q8 X, c1 a9 X% |% I( e使用LSTM模型( t3 j  x' w, S6 h
    # H( k1 u+ h& T+ x& Q0 ^, D; v

    # m5 N% [2 P) [( i6 z( U0 E结果:
    / w+ Y8 h& w8 K* ~Epoch 49/50
    ' Z  E' Z" ?4 o) Z" F' g) m0s - loss: 0.0147 - val_loss: 0.0149
    ! n0 T; }1 b1 j+ S7 G+ p9 b. M, YEpoch 50/50& M$ H- q; H$ w+ J
    0s - loss: 0.0147 - val_loss: 0.0150
    $ K  P0 g  d) R" T7 h( }
    5 n" ?. o4 o6 h) Q2 z& o3 q
    ( Q; X0 g/ {+ K( P: v' _1 P
    实验3:用前一天的天气数据,预测某一天的空气质量
    " q. n% Y0 V8 k! B8 W! X使用普通的全连接模型 Dense()/ w% v* r, g% N( B" F. ~1 x
    结果:) E  R9 O1 U7 t. ~2 Y
    Epoch 49/50
    5 |3 V- j$ |# H  B. G0s - loss: 0.0144 - val_loss: 0.0146' N$ E' S! Q  f: b4 n
    Epoch 50/50
    6 Y# p- U. |3 \/ Z) W0s - loss: 0.0148 - val_loss: 0.0151
    # ~7 X6 q% Z* u) Z- `  v! Q) X8 [% Q+ `0 H0 L' c0 Y! X  T  R$ K
    0 r, n9 s" I* N; z
    实验4:用前三天的天气数据,预测某一天的空气质量8 W. @" B, r" q3 u" ?
    使用普通的全连接模型 Dense()
    7 K1 l, n: I. B" P" D% B% ?6 _结果:
      L8 ~; @$ g" I. F4 S% j0 ^8 ?" AEpoch 49/50, O: N$ ]9 z5 c4 ?+ I9 B  L' d. j
    0s - loss: 0.0150 - val_loss: 0.0165
    % U; u$ i% e8 ~, g% fEpoch 50/50$ e0 b& V/ Z% c% o0 W/ d0 Z  g% I
    0s - loss: 0.0148 - val_loss: 0.0141
    3 Y5 ~$ N% E8 @# l- r, u- s& E3 g! C/ C5 h
    % J( T1 E/ ], {. d- {, x$ r
    实验5:用前一天的天气数据,预测某一天的空气质量( w) Y& m/ t, Z. q% R$ z5 t" r
    使用SimpleRNN
    : V: n: |$ p5 WEpoch 49/50
    2 @; Z; p4 u! P0s - loss: 0.0160 - val_loss: 0.0140
    ! W/ |9 J9 ^; C& O5 T: }6 EEpoch 50/50
    , [& J, y. Y1 @! Z7 g. M4 T0s - loss: 0.0147 - val_loss: 0.0150
    ' V! I; P. o6 x. m
    . G1 S1 \- X3 B( R3 ~: }* f! d
    9 G% o2 ^; A+ \
    实验6:用前三天的天气数据,预测某一天的空气质量! A2 J8 o6 ~0 p, Q- g
    使用SimpleRNN8 M% Y: M. m, `  ^. s- |* S( a
    Epoch 49/50$ m, v1 i6 i" j1 R: A' l9 d
    0s - loss: 0.0164 - val_loss: 0.0233" l4 a- r4 k! Z  g. n5 N, Y# }
    Epoch 50/50" O) F7 N$ S3 f/ L3 v$ f% h% |
    0s - loss: 0.0166 - val_loss: 0.0227
    + O6 s8 e; {/ ^" eRNN和DNN的区别

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

    ; Z7 e5 C$ j  v9 y

    8 N+ Y9 h. A9 A9 j' s( I* [& b$ t& T; |$ d
    RNN和LSTM的区别
    ; @: }1 F* o' h/ P' QLSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。
    * y5 v* {$ m" D; ~: I  }
    $ a( E' n0 V) w. M: M

    5 T2 S# [- I( [/ Q/ w6 j: W但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。+ _1 X% d. I* C9 C( j* d5 \' }, M
    ' `/ O& o4 v0 G' F

    * Z) w) v9 O# ~! v. h# f) {请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员
      T0 N, B0 J! ?& `$ I
    ' p1 u) n5 w" K
    6 v' _" G: ~' v+ N
    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-8-24 16:01 , Processed in 0.414082 second(s), 56 queries .

    回顶部