QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4456|回复: 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预测时间序列数据
      m5 q8 s; x7 v2 q
    1 M5 ~  Q* l# s; Y; j* G9 N

    7 M. ?* j. E0 L% K文章目录  ^8 n( {* Z/ \
    背景8 T1 j5 f! Y& H4 w" D- Z+ y/ R6 C7 ^
    结论
    4 t! R) j  f) H- Y代码# u1 }+ K. y5 x4 q, i0 d; }% a5 v
    实验结果
    1 m# N8 Y% y5 Q+ D  dRNN和DNN的区别
    6 ]5 Y5 s5 r) X; p1 k3 \" mRNN和LSTM的区别  D% `8 A$ X, C4 }
    背景' l) o0 B3 |( a1 e6 V% x
    复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验4 X8 }3 k" [& t9 ?7 A8 ~" L+ v  [
    熟悉用LSTM模型训练
    $ M" T5 v7 P" a/ ]0 g8 x! t验证将时序数据 转化为分类问题后,预测是否有效果# ~7 H& P) T1 d* d
    对比SimpleRNN与LSTM模型 哪个效果最好?% I5 C+ U/ Q2 D% F
    验证LSTM相比于Dense()模型 是否有提升?* Y+ k7 U& o2 B3 @; O! A3 z
    对比使用前3天的数据 和使用前1天的数据 哪个效果最好?/ c6 N; s' F4 s: n1 A1 i
    结论
    * ~7 b& ?" W& ~使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好
    + W, e$ u  l2 ]/ x使用LSTM的效果优于SimpleRNN! ?$ f0 E( ]" r+ B+ K& H  s
    代码
    / H4 h3 A, Y" \" K" i( W4 f8 x& Ufrom pandas import read_csv
    3 q. f# Q. ?, T  {9 ~/ `from datetime import datetime  B2 v: {9 C- E1 X3 D0 B
    import pandas as pd7 a8 n0 a8 h! C. \- X9 C
    from pandas import DataFrame0 P/ A, _, N9 i& [! G
    from sklearn.preprocessing import LabelEncoder,MinMaxScaler* x) z# ~; j2 W6 N
    from sklearn.metrics import mean_squared_error5 d" C5 h( p9 B* t+ w: V" H
    from keras.models import Sequential
    # l* t% W. Y" _1 _, F8 jfrom keras.layers import Dense, Dropout# T9 p" N0 E6 k& B7 r* w; @
    from keras.layers import LSTM
    ; h" M' |: Q& q& V4 M6 Cfrom keras.layers.recurrent import SimpleRNN
    " L1 ?* }; i0 ~% h$ Cfrom numpy import concatenate; W. Y. J. N2 ]2 B! `1 E! C0 b
    from math import sqrt
    6 T' R5 j9 s- u3 H( U- W( k) w0 h7 M; P8 q4 O3 j

    * k% t3 o" {# n! ^5 [# ?: j  R1 v
    8 M2 e1 x  ~- l$ X
    # load data( R4 w7 b& X' D, G5 `( G/ n! f. o
    def parse(x):
    6 Q! E- O+ B# I+ u        return datetime.strptime(x, '%Y %m %d %H')
    ! u- n: ]; j- k  w ( X/ C8 _) Q5 k
    def read_raw():) c  X  R; n& K+ D
        dataset = pd.read_csv('raw.csv',  parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)) t9 P% N1 d5 u* O4 b
        dataset.drop('No', axis=1, inplace=True)
    5 M3 q1 y. J( {6 M& N    # manually specify column names' x5 N) W6 r. u$ I( x
        dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']; d1 [9 y  x. b5 O6 E; ]8 k
        dataset.index.name = 'date'. }! O0 M3 O& [; w3 M* l# G3 k# {
        # mark all NA values with 0! H9 o# x, T* @" ~3 N" V
        dataset['pollution'].fillna(0, inplace=True)
    5 b4 w! x2 x! m. P% M    # drop the first 24 hours
    . @' ^: t" P: l. f    dataset = dataset[24:]
      D  A, ]. L: a4 N    # summarize first 5 rows
    ; M, t; T4 b* a: g    print(dataset.head(5))
    4 @- d2 B5 B0 w. Q    # save to file, m9 u: N% b) Q' d
        dataset.to_csv('pollution.csv')
    . l; \, K# s' }& _  X: }! a. Y/ B
    , c! O% n, Q6 M' ~; J  `  `

      z: I4 F+ w; i5 c3 `
    2 y$ l& e# X+ \! M  v6 J3 x

    7 ]% n, [$ P! P* ]- k8 }9 \+ Q3 J3 Y# convert series to supervised learning+ B9 J- q) q" U! z! ]/ Y
    def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):( R* Y9 d; L: P6 Z4 `$ \3 }( g, Y
        n_vars = 1 if type(data) is list else data.shape[1]% T. v$ y* h9 b- B$ S
        df = DataFrame(data)6 h7 M) z) p% y. h) Y9 E0 T
        cols, names = list(), list()' h6 t( X9 r" L( i0 K
        # input sequence (t-n, ... t-1)
    ) t7 s; {) T2 u; X    for i in range(n_in, 0, -1):- E6 |; a4 x9 U4 q( Z, W% S% {
            cols.append(df.shift(i))
    ! _' I7 y. g* W( i0 [1 ^        names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
    8 Q/ N/ Z& W! C0 B- b    # forecast sequence (t, t+1, ... t+n); Q. W) P6 i$ Y" ~5 L! L9 Z' f1 }/ V
        for i in range(0, n_out):" N; N3 O8 T! P7 v
            cols.append(df.shift(-i))
    / G) f( U2 w3 ~0 x' d        if i == 0:5 b1 w8 b; q: |: X5 m: n
                names += [('var%d(t)' % (j+1)) for j in range(n_vars)]+ ?0 g7 q( K3 d: e3 o: d: K5 m
            else:
    . H) }9 R' Z' d4 V9 J            names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
    + Q0 S# ~& U5 v. f9 l# D2 ^    # put it all together
    ( j2 u; x/ m' R2 f    agg = pd.concat(cols, axis=1)
      F1 W6 X* o( N$ o1 ]: ]# {+ k    agg.columns = names
    6 ~  \- X! T3 s* @+ d    # drop rows with NaN values
    - c3 I, o& T9 u3 ]& y    if dropnan:# T: }: `7 W7 a$ P
            agg.dropna(inplace=True)
    , J5 i/ E+ S6 C) O9 h" O    return agg
    . Q) @$ Q7 t& o" @3 h
    ; v" F) C/ u7 I# load dataset
    : i" c  O: [7 R" W% q- idataset = read_csv('pollution.csv', header=0, index_col=0)
    " l, u( @$ O0 i  l, F; xvalues = dataset.values
    / `3 y" @! l) P% _
    & h( _5 J- R. N9 o  i) `
    4 B! w0 l/ K. W6 n3 Q& F6 U" x
    # integer encode direction; |$ g2 ~1 _' v- R, t
    encoder = LabelEncoder(); ]; B" `* K/ }4 g$ T/ k
    print(values[:,4])
    . N2 }: B  n! H: Z+ dvalues[:,4] = encoder.fit_transform(values[:,4])/ d6 G7 P; ]% X$ }, c& t
    # ensure all data is float
    * S+ w* V* Z- E$ {, c2 x+ R2 kvalues = values.astype('float32')
    % f/ |! N3 l$ C; C+ a  D" v# normalize features
    $ R" h  `" o9 a& Zscaler = MinMaxScaler(feature_range=(0, 1))8 D' Z# N, j% J8 o4 h& y9 X
    scaled = scaler.fit_transform(values)
    7 {. k+ O1 c/ D. ]# o# frame as supervised learning* Z. Q6 T3 E- z4 w
    reframed = series_to_supervised(scaled, 1, 1)
      J* n4 U. j( H#reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据9 W3 _# Q( O1 ]. V
    print("columns:", reframed.columns)
      ?) ^2 H6 D( p# drop columns we don't want to predict
    " R5 R$ e& y6 O8 c9 G/ Q+ X0 mreframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据/ y9 S  F( d* r4 A  V$ q4 c
    #reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据
    6 x7 M' q# T# f- U% D1 w9 A+ O! ]print(reframed.head())- _6 o/ Q& G( {$ B; w( N
    print("new columns:", reframed.columns)! I! ]3 `$ l$ Y, P
    # split into train and test sets, h. M0 ?# X3 }9 g
    values = reframed.values8 o5 s7 K( d" |( m7 A
    n_train_hours = 365 * 24( e- _1 A$ ?1 R
    train = values[:n_train_hours, :]
    ( U9 s, B& _7 M# r% ptest = values[n_train_hours:, :]
      H& U$ R. b1 {, a0 }) M. }" f# split into input and outputs
      O( C- C! t: O2 Y% f7 [+ jtrain_X, train_y = train[:, :-1], train[:, -1]* Y; ?8 S; T  P4 a) M2 K0 V! |8 l
    test_X, test_y = test[:, :-1], test[:, -1], S+ L! g* s3 p4 W
    # reshape input to be 3D [samples, timesteps, features]- f  S* B& m5 V7 W# G5 R8 @
    #使用Dense()模型时不用变换
    2 Z# M% H5 b- K" }$ ]+ l  [train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))0 w0 `2 j& \6 h6 E1 |
    test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1])): M. G9 L7 o+ C0 u0 b
    print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
    9 |% V$ k& G# d1 H$ K' H) P3 F" s# design network* L3 j3 j; h% U8 p  }. ^
    model = Sequential()
    6 I$ Q) d6 }$ ?2 ^5 ^( K( n9 @#model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))* x( w, }6 D+ _( C( H7 B
    #model.add(Dense(50, activation='relu', input_dim = 8))
    4 S; u# D6 K: dmodel.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))$ k) o6 \0 p) j
    model.add(Dense(1))+ v1 A9 O8 ~! W6 R# j) o/ ~
    model.compile(loss='mae', optimizer='adam')3 t3 I1 P! O9 M& O
    # fit network3 K  N0 b! r& c: n# t
    history = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
    ) z& @5 b! r# ?* _) W# make a prediction
    8 v5 b1 m, U+ X& m, G; fyhat = model.predict(test_X): }9 X: \# x. Y0 L, E" t1 B+ V
    print("yhat shape:", yhat.shape)& Y& o8 H4 o9 c
    '''" u0 C5 c- a5 L$ p9 O0 f$ u4 d
    计算在测试集上的均方差6 P0 L" z5 ~- z" ^" {4 G7 D5 H
    test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))4 y% i% f" n( @
    print("test_X shape:", test_X.shape)
    # k/ R! S3 r2 O, f
    0 `$ l- T8 G, ^# x

    ; X/ e, p( o! _; G0 t3 I# Z# invert scaling for forecast
    5 m. ~7 W. s  D$ R! Y- g8 y& y8 dinv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)
    * H) p. U8 L/ hinv_yhat = scaler.inverse_transform(inv_yhat)/ s6 p0 n8 T2 Y1 W0 Z% c
    inv_yhat = inv_yhat[:,0]
    ; p# J; h  j+ c8 j, z, b; V- a# invert scaling for actual1 s8 V+ m3 `$ x/ D* B
    test_y = test_y.reshape((len(test_y), 1))) |+ {1 `: Z* E) w% k$ ^) H
    inv_y = concatenate((test_y, test_X[:, 1:]), axis=1). a5 }8 b3 T* ^# e) S
    print("inv_y:", inv_y[:10])" N! t& w8 a1 _# G/ {
    print("inv_y shape:", inv_y.shape)
    # E% i0 s! e$ l; d+ R
    2 l) \8 I: i! @, z2 k" Q

    * R" P3 F/ a6 x2 r# rinv_y = scaler.inverse_transform(inv_y): ~9 Y" r2 G7 `" f
    print(inv_y, "*"*30)) ?- s& q# {! H) s/ s9 s
    # E$ z% C, u  \! i8 b8 x% D

    1 X. f: L; E3 D% Finv_y = inv_y[:,0]
    # v* Y1 E: T! G+ l/ [# calculate RMSE' r+ k" {1 w0 G9 {" {
    rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
    : o2 R9 z! f  R+ P2 Fprint(inv_y[:100], inv_yhat[:100])
      P7 E: G4 d* C* C2 \  r: Q% F" cprint('Test RMSE: %.3f' % rmse)
    ! H8 n' F7 [% u
    + u: E- \" G- ~( s2 g

    / C" ?8 h6 w1 {3 J# X2 f'''
    + D* }2 W( _4 z7 o) Y9 s实验结果
    ! p3 \! a6 U& s. D
    实验1:用前一天的天气数据,预测某一天的空气质量$ E8 l0 C: ]8 D: [" ]
    使用LSTM模型
    6 G8 f4 ]' C+ W* N- W9 r% d结果:
    0 z* ~: }9 N; ]# j1 }Epoch 49/506 H7 J3 G1 k' `( C
    0s - loss: 0.0144 - val_loss: 0.0133. }) z: {, U* d; L
    Epoch 50/50
    3 [* U7 M$ `  G/ L0 _) S. m0s - loss: 0.0144 - val_loss: 0.0133
    7 h; d3 ]' f) q" s
    3 ^: h1 s% u$ g4 u3 e
    4 o1 _( ]: K1 ]; K3 D
    实验2:用前3天的天气数据,预测某一天的空气质量) m, w  v1 I& }2 }& u3 U- Q
    使用LSTM模型
    4 D! f" t5 b8 Q0 E+ \4 Z, C3 x
    0 C6 V& W! B8 X& R' C9 H' R

    & U. X9 M" L1 r, t5 D* X结果:
    2 ^3 A! J, {: @; s" MEpoch 49/50% K- a( H: P2 R; W/ H" L" {: y2 Q" n
    0s - loss: 0.0147 - val_loss: 0.0149, I. h: X7 q) w+ Z
    Epoch 50/50
    7 D( t  M' z( [! o6 g0s - loss: 0.0147 - val_loss: 0.0150# o/ |2 F/ V& K% K  u" J
    9 h! u+ q1 F* Q) P5 c. f

    " A& j- I$ t" D. m! ]2 ^3 r6 J5 F实验3:用前一天的天气数据,预测某一天的空气质量
    5 g6 W1 b7 X4 o使用普通的全连接模型 Dense()
    ' [, C5 {9 n* X# I$ q/ ~0 ]: c结果:
    / ^2 ?# \  @+ xEpoch 49/50
    3 Y/ r( `- x; V" L0s - loss: 0.0144 - val_loss: 0.0146
    0 k; z/ B( ^2 n- F" r( `6 U( XEpoch 50/50
    - C/ ?* r3 w; n. F5 v; S" B- J) h0s - loss: 0.0148 - val_loss: 0.0151
    4 F. z6 z/ U' |5 s" p/ C' r- \
    ' j  I( J" u" k" u9 A

    2 ?* u9 _( c( a- f$ Z" I实验4:用前三天的天气数据,预测某一天的空气质量
      F0 k1 ?# V9 @使用普通的全连接模型 Dense()* [2 ^" A# }$ A; |- ^
    结果:
    ; d+ g3 I, V% s  d- UEpoch 49/50; l& R" b9 }  y4 Y2 V# L- e
    0s - loss: 0.0150 - val_loss: 0.0165, ]# m2 @2 ^, [
    Epoch 50/50" [+ g, }1 i% J# R; A
    0s - loss: 0.0148 - val_loss: 0.0141  X; @; W& I9 x2 O6 U8 W+ D4 n
    ( K: T$ R& [! }6 T

    " v7 ?. Y4 Y9 G6 F1 W& z3 k! p1 P实验5:用前一天的天气数据,预测某一天的空气质量
    # a. d- ?. E6 J! b) s  Y5 j使用SimpleRNN! L9 V( x$ _# X
    Epoch 49/50$ {) k4 [5 p' v! K
    0s - loss: 0.0160 - val_loss: 0.0140
    6 O5 ]. z: f2 _& E, gEpoch 50/50
    . I' J9 ~! S5 a7 S+ z: v2 Y" G0s - loss: 0.0147 - val_loss: 0.0150
    % s8 y# y: o; q  y: s7 M) T1 q5 ~- ~- n. r
    . p2 P" e/ b) l0 ]  Y! N
    实验6:用前三天的天气数据,预测某一天的空气质量
    - p5 ]8 J- B  B# h3 f+ }$ s使用SimpleRNN4 ~  ^1 T  k% P
    Epoch 49/50% \0 f( L/ `6 |' ~# r2 m
    0s - loss: 0.0164 - val_loss: 0.0233
    + x* ^" S: [! {! }Epoch 50/50: u- n- {$ t# C8 c0 o$ ]4 e
    0s - loss: 0.0166 - val_loss: 0.0227
    3 n; I, g' e4 F/ d% d% X/ e$ gRNN和DNN的区别

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


    0 n- ~! D3 }* L5 \1 k4 y
    0 @* C& n; Q, ^# `$ O
    / x( {% u* U1 Q% ?
    RNN和LSTM的区别
    " ?9 C, L1 J* |: p; T/ I4 m2 QLSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。
    5 M4 w$ c1 j3 d! m! l1 \4 l2 ~" Z( ~) k8 c  r4 o1 ~8 Z

    % r' }3 V" P* e+ s7 u/ Q4 s但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。9 z7 U, b% u0 ?3 l

    - q2 G/ h' Q: i' C4 b- e/ [
    $ O6 m( d8 G6 }1 U" K/ m  y请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员
    ! M7 t4 n8 r4 ~% L0 a  W
    ( b9 P! |0 _( u: X  l$ o" X
    7 a- x: g. V' [. k# \" t, W
    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-10 03:21 , Processed in 2.639722 second(s), 56 queries .

    回顶部