QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4327|回复: 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预测时间序列数据4 s% v% N& V/ g9 O% c7 w
    " g2 g/ Y( [8 L

    & u6 d9 J  S7 k& x, ^文章目录# J& T3 k4 L# K% Y
    背景
    % x, U% X) g* h7 r9 q1 b结论  v  u* E# J; U. R2 C) J! j
    代码4 `0 }! F! p4 I- Y- `
    实验结果
    9 ]. E5 y; n& V$ XRNN和DNN的区别
    1 q% o# A" K' j8 g5 L  [) aRNN和LSTM的区别4 Q: O" g& r4 X) x1 f
    背景' M# b0 I- E- V. W3 h8 a% W9 K
    复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验
    & p$ |; X8 Y1 h. L0 m熟悉用LSTM模型训练. W) {4 t! ?' z& L, w
    验证将时序数据 转化为分类问题后,预测是否有效果! `# s+ V; a" z" Z1 q7 F
    对比SimpleRNN与LSTM模型 哪个效果最好?& B. [) e% ?6 J* M
    验证LSTM相比于Dense()模型 是否有提升?$ \! c5 [9 O- X% f' F+ ~& Q: l
    对比使用前3天的数据 和使用前1天的数据 哪个效果最好?
    ! ?: S3 ~1 S5 I" v, |1 a; @) h; T# F结论
    ! I% A0 e7 \2 D" Y4 D& Q& f使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好
    6 ^: k2 [7 O0 P+ q  A9 Z: q) w1 @- g! C使用LSTM的效果优于SimpleRNN
    & {  l5 u$ m8 _. w代码
    ' m: H* v  ]9 `* n- Ofrom pandas import read_csv
    : y: z( W1 Q+ p( N- nfrom datetime import datetime
    9 i) L3 _4 N. N. uimport pandas as pd
    - C1 p, H5 k- R" Zfrom pandas import DataFrame$ C0 e! w7 E' G0 Z
    from sklearn.preprocessing import LabelEncoder,MinMaxScaler
    " Y! @$ Z  }6 |! T" o1 E% I9 p( Bfrom sklearn.metrics import mean_squared_error$ W; I* J. p, o
    from keras.models import Sequential$ p3 L. s3 o' }" N9 ~9 v4 K* q
    from keras.layers import Dense, Dropout
    / [* h0 Z% ^/ P% |& r* [from keras.layers import LSTM. }6 ?; X* O0 i
    from keras.layers.recurrent import SimpleRNN
    + Z* @3 A: e9 u0 \; ofrom numpy import concatenate; ~! E  p4 `& ]" I5 S
    from math import sqrt
    # e% y8 \* H& i0 c3 i+ v) f& R+ z" T( o7 P6 S! {; b

    & ?! I- _5 l& o& j% k
    ( G. {  n" l  F2 r

    ; c, Q2 w8 F1 C  G6 l8 K# load data
    7 Y! b% D. D  p; qdef parse(x):
    9 o) u. c% @/ @: |: a+ d        return datetime.strptime(x, '%Y %m %d %H')) Y- K- H+ o9 T& n, \

    9 \" m9 G1 V" {) Fdef read_raw():2 k' j3 Z2 x# }* Y* a" f% |
        dataset = pd.read_csv('raw.csv',  parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse)0 L6 U( d+ Z* U2 e
        dataset.drop('No', axis=1, inplace=True)
    # g  `1 F: n% f* ?9 r0 {    # manually specify column names* U2 u4 M0 {9 ~+ B3 ^
        dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']8 \5 B% r/ a2 {2 i  A3 Q) n
        dataset.index.name = 'date'
    : W2 R& ], X3 j    # mark all NA values with 08 I) r" O& z5 ~" l; G
        dataset['pollution'].fillna(0, inplace=True)2 D4 h; o1 t1 e. Z( W! w
        # drop the first 24 hours$ ]8 A  r+ V% H. u
        dataset = dataset[24:]( Y, V4 ~+ v- S8 j! |7 ^5 f
        # summarize first 5 rows
    - A9 w1 M8 Y5 M    print(dataset.head(5))8 S) t2 w* {5 l2 d
        # save to file& o* R0 J* B  ^! I: g
        dataset.to_csv('pollution.csv')$ t  j( _: ^9 F3 F$ e5 j0 I" w
    1 G. B- O2 u8 f. S

    ! t% L# M: Y/ g
    * t+ D4 y0 W/ Y% ]( y& W
    ' f1 z9 [% F5 N& L$ c
    # convert series to supervised learning% q3 c% p8 S1 k5 l% v
    def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    + t" Y3 V. o) E  t1 z5 Y    n_vars = 1 if type(data) is list else data.shape[1]
    ! w2 Z* W' S* v, f& |0 Z- W    df = DataFrame(data)- `6 O! _% f1 H7 d: ~- |, L% W
        cols, names = list(), list()1 {1 D2 M' X! b! W& k, t) h
        # input sequence (t-n, ... t-1)- w, V: C1 G' D* U8 }1 i2 S( e
        for i in range(n_in, 0, -1):
    7 U+ J* B3 C! k( }& \        cols.append(df.shift(i))
    . Q8 ?0 I" n# Q2 ]: C        names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]' ~7 X/ H7 T5 \- B  O0 U4 i
        # forecast sequence (t, t+1, ... t+n)
    2 ~! H! E% P6 f- o4 M    for i in range(0, n_out):3 G1 X+ Q+ ~- e9 F4 O, q* x
            cols.append(df.shift(-i)); |* w9 m' T# ^. |$ L
            if i == 0:/ S2 ?% i8 q; G: W2 P% s
                names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
    1 c2 D: ~1 n2 e1 ~        else:; Q6 r6 t% J5 M6 v; x
                names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]  l( U+ R! E7 E1 f1 w- T
        # put it all together) u8 g" k9 v/ J6 P" t4 L: E
        agg = pd.concat(cols, axis=1)" z" n: m7 y) f  ]- F' \7 C: Z, U  U
        agg.columns = names
    , d' L) w4 |& k! o3 J9 Z  L8 q. P    # drop rows with NaN values) w+ C3 A+ c2 @8 a7 v& F
        if dropnan:
    ; S3 C$ A( `, A- U) C4 e        agg.dropna(inplace=True)+ k) M# J4 X2 C4 V, U! i
        return agg; j+ E' R% `. A

    ) q& U2 z0 r& k" ]# load dataset$ W# C- f+ A1 k# J6 n4 h
    dataset = read_csv('pollution.csv', header=0, index_col=0)5 J) m6 ]+ |. X8 c5 G- D
    values = dataset.values- [, P  u1 U  w3 d) ~5 i
    4 q; y3 p, D: {' c+ C

    % a% L( t+ w- L9 g# integer encode direction
    * p- ], M* i# T/ }3 L6 c4 s( o: Fencoder = LabelEncoder()
    ' {  Y: v: \  E( m8 aprint(values[:,4])+ N7 _7 Z/ d" V  ~* T% Z4 f
    values[:,4] = encoder.fit_transform(values[:,4])
    . o# v. K# Y# `6 ^1 X. S8 e# ensure all data is float
    & U: G2 |7 k6 |6 I# Rvalues = values.astype('float32')
    ) b$ E3 l  _9 @0 y/ i( N& E8 q1 ]( S: t# normalize features
    1 b, h8 b5 y7 ~. o& P0 Rscaler = MinMaxScaler(feature_range=(0, 1))
    - U6 U6 J; S" o# M5 B3 _scaled = scaler.fit_transform(values)# c$ i: ]" A0 a% J
    # frame as supervised learning
    4 [* E: G/ H1 z& C/ @: ^reframed = series_to_supervised(scaled, 1, 1) & b+ X$ I, m4 D* R( Y* s4 W: n
    #reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据6 q; x+ n" F2 t, L4 R
    print("columns:", reframed.columns)+ Y, \2 _! ]! t  Z3 Y8 p/ C! H0 i8 ^
    # drop columns we don't want to predict
    * f* }. H2 i  ]  u' W: Areframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据
    2 f# m! N# s8 D#reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据
    " f( G9 u1 R# z; f, w2 y' E4 l% a8 R. `% Aprint(reframed.head())
    2 {" {: ~8 w1 Sprint("new columns:", reframed.columns)) l) D" ?8 `" r: K* O9 W! Y
    # split into train and test sets- o$ J3 b+ o) N) Z
    values = reframed.values
    ) N5 s* J+ G* o( K0 mn_train_hours = 365 * 24
    2 ~- j: |, C+ Jtrain = values[:n_train_hours, :]0 x! E5 b0 k- d$ J% i; o
    test = values[n_train_hours:, :]$ h, Q; _4 ^; `: e, e8 p, T
    # split into input and outputs( q- C4 b1 B7 ^0 U
    train_X, train_y = train[:, :-1], train[:, -1]
    8 H0 R* f% M" L8 C- n& Ptest_X, test_y = test[:, :-1], test[:, -1]
    , y" ?" r" m3 M. z# reshape input to be 3D [samples, timesteps, features], }  ?8 Q! g7 t6 B3 C2 r  L
    #使用Dense()模型时不用变换
    ) b% ]3 H" k( |# P9 J/ ctrain_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))7 A7 \; C- Q$ Q! ], I' ^
    test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
    6 f$ j8 j  G7 Bprint(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
    % s: b4 T! _* T0 H  J7 Q3 Q! W# design network2 @9 Y" [: y* T+ n/ t
    model = Sequential()$ R" a/ B9 q# Y
    #model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))% ^, Y' s( i; c
    #model.add(Dense(50, activation='relu', input_dim = 8))- i, {" I( q" F+ W
    model.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))$ J2 J% i6 g0 K" _; ]- H2 {
    model.add(Dense(1)). n: M( j$ f0 H' g6 ?
    model.compile(loss='mae', optimizer='adam')
    : O3 |, x. j; M0 `! }; G0 c# fit network
    ) {, ]" F9 U; }' F1 y8 ~5 @history = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)( ]% T/ `7 j0 D  u2 H& b
    # make a prediction& J9 P( @9 K4 \* _; d/ n
    yhat = model.predict(test_X); E' w1 l1 e# M: s: X# Y: Y
    print("yhat shape:", yhat.shape)4 p" A- c, v$ c6 ~0 @( W& I
    '''9 u# [9 O, U0 s, k' f
    计算在测试集上的均方差6 k6 |0 H$ _- v8 X$ N
    test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
    ' y) ?, h* A* C" n/ gprint("test_X shape:", test_X.shape)
    " j7 ]9 \5 p! B8 t' [6 s2 y- o3 j3 M1 N* L3 S6 ?! |/ a
    $ v4 `4 ^0 Q: T  X/ N
    # invert scaling for forecast
    # b3 A4 z8 S, @# C! finv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)7 ]6 C* N' J6 E0 W
    inv_yhat = scaler.inverse_transform(inv_yhat)
    . m3 U' @7 V5 v- k# M( N) x; e0 ]inv_yhat = inv_yhat[:,0]8 Y" m9 v- I9 s1 j0 l# G0 P
    # invert scaling for actual
    2 L. d7 j3 h! j5 P6 C3 ?3 S( F) ctest_y = test_y.reshape((len(test_y), 1))
    : G! z  i' ~* `  Ginv_y = concatenate((test_y, test_X[:, 1:]), axis=1)
    & Y& @& E4 [7 I& v: E, P: pprint("inv_y:", inv_y[:10])
    8 M6 A" [6 u! J# yprint("inv_y shape:", inv_y.shape)0 @+ B# F9 S  ^4 W

    6 }* L+ f' D, B% Q% {2 b8 G

    ) L3 k9 d0 X2 B( E5 U7 L: D# Y5 iinv_y = scaler.inverse_transform(inv_y)
    8 I, N; [4 G! H. @$ v& j9 |$ a1 c$ O5 aprint(inv_y, "*"*30)
    ' U& `, ?2 L9 k1 U! W
    5 b. w. x( ~- w/ u) P0 p1 G5 p

      v9 `0 ?, K( c* f8 t+ Yinv_y = inv_y[:,0]
    + `7 S& x$ \' j" P. n& v& `# calculate RMSE7 ^9 |$ ?% u5 n# ]  Q9 J9 I8 G
    rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
    0 ?& F8 s# t& p$ Z+ {; _print(inv_y[:100], inv_yhat[:100])1 |: {( F0 @0 {- L/ T
    print('Test RMSE: %.3f' % rmse)- F. D  |% K' W" ~3 \3 g8 L* ^
    - u' E) k: H0 T! F" k# |2 s5 C
    ) a2 ^+ U  v. e4 r0 C& t9 [' D
    '''6 p$ H! d7 U9 w9 m* G
    实验结果
    8 a) @- c# T9 v: B6 q3 F4 i4 Z/ L+ n
    实验1:用前一天的天气数据,预测某一天的空气质量# I; {, e1 f3 H$ J$ v, r; m
    使用LSTM模型& j3 B# ^% l; a0 {( j
    结果:& q! k2 n6 W3 a2 \6 ?+ @8 J
    Epoch 49/50& \. s9 B# @& X3 L8 ^! S
    0s - loss: 0.0144 - val_loss: 0.0133
      p$ B' Q7 m: N0 m$ T! o' X$ iEpoch 50/50& y. l; p4 f) c% _) F
    0s - loss: 0.0144 - val_loss: 0.0133, a9 T) s! u1 W1 ~+ \& B+ E
    7 c) W; Q. s2 T3 h7 e9 @! N

    $ h6 b/ G0 m. W% J* S6 \/ x# @实验2:用前3天的天气数据,预测某一天的空气质量
    5 |0 @' ^) F$ y" L4 p: K6 ~使用LSTM模型$ q) @/ e8 E8 A( q; S2 N, U
    * @- u. |* Z/ P4 e4 R
    - R( v. M5 \% P9 w  }
    结果:
      n6 Y0 f( b& W1 A- {9 dEpoch 49/50  s6 ~) {6 O9 {1 r% J
    0s - loss: 0.0147 - val_loss: 0.0149. o, h1 B1 l; Q  p, ]6 S& Y' i
    Epoch 50/50
    3 `; L% Q5 o* K4 l" G$ o* g6 q0s - loss: 0.0147 - val_loss: 0.0150
    ( N' S/ Y  a& d7 q
    2 ^1 M- o3 H( m3 P4 i1 s4 i! d( A: Z, K

    * F1 K9 {3 ^: w  D' Y实验3:用前一天的天气数据,预测某一天的空气质量: e. l- d4 n1 G2 x0 W  D8 k. C
    使用普通的全连接模型 Dense()
    : W( ?& n2 r9 k) g/ B结果:
    4 V5 r$ `  x6 U9 T2 G7 a0 m. I. p; AEpoch 49/50
    % e* s4 q( r5 G1 M0s - loss: 0.0144 - val_loss: 0.0146
    + s2 u/ g) z8 O# R( s; f5 {' ZEpoch 50/50
    ( R5 G1 a1 w( q1 J0s - loss: 0.0148 - val_loss: 0.0151
    - v  X& j: a+ n- ^6 i
    + X& Q" {) e3 e0 R4 p/ t5 y2 H
    # y- i' w: Z5 d; G; O
    实验4:用前三天的天气数据,预测某一天的空气质量2 g$ l: `8 g5 T& J) |7 Z
    使用普通的全连接模型 Dense()3 B* i. u, t! d2 }) Q' @; d" K
    结果:
    9 t: u. h, e/ f0 b3 UEpoch 49/50; _' O  `( H+ V6 \( K* g) O
    0s - loss: 0.0150 - val_loss: 0.0165
    ! O1 W3 n5 F# }" a1 d( P& }Epoch 50/50
    * {9 l8 Q2 Y) X0s - loss: 0.0148 - val_loss: 0.0141' @% V9 b, l0 W& {

    2 K# f& ~* d; i

      V) g- ^/ S" p4 \实验5:用前一天的天气数据,预测某一天的空气质量
    # z( c) a0 h( o使用SimpleRNN% t& v' T/ I  d0 u9 i& N" Y
    Epoch 49/50# ^2 _. t. i8 v' C5 d6 \) a
    0s - loss: 0.0160 - val_loss: 0.01402 P/ K1 ?6 R- Q) N- u. m: n
    Epoch 50/50
    ; R2 X; @0 P7 \; B0s - loss: 0.0147 - val_loss: 0.01500 R3 S/ A. R; O8 {4 e( c

    : V1 E# M0 q5 W! ?: Y

    9 V  j' n' g* v* F' n- A, B实验6:用前三天的天气数据,预测某一天的空气质量
    - `! J5 R' c" c& z' @  s使用SimpleRNN! ]! n  W7 Y0 G; Z
    Epoch 49/50
    " r' Q( P; K. g( T- c0s - loss: 0.0164 - val_loss: 0.0233
    ( s+ [  C8 v( P9 S0 l$ WEpoch 50/50* [) _7 E" d6 E( G
    0s - loss: 0.0166 - val_loss: 0.0227
    + q% }! \) A' P' Y+ s; \( Q' j' X( LRNN和DNN的区别

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

    , ?# I* c! A6 P2 Z8 O. |9 b+ z

    * a& p; m2 v% P& `' t- D3 R
    2 I$ I( G# n: n5 m9 t! t& K- b, A
    RNN和LSTM的区别1 `# w, w. ^( ?2 x8 u3 _: l
    LSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。
    . }; J/ ~6 B0 k% a" E6 k, O6 z" R9 `% \/ R' u! s: ~  m3 Q" F

    & y; j) {1 q' K% Z' N但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。7 J6 \9 {/ U# r

    0 ]+ Q( J: Y/ s$ A9 w' a9 Z7 t5 F$ ]+ T2 s5 a
    请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员

    ; m$ ]* V3 x% q5 D4 c3 m7 C) C4 b: p2 |. F
    . [1 Z6 D7 i1 R4 e: q
    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-4-20 21:19 , Processed in 0.464550 second(s), 57 queries .

    回顶部