QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4370|回复: 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预测时间序列数据
    / T: |  d, G) `9 H# a
    , K) Z# U8 k; Q2 S; p* S
    + M- ?9 k0 ~$ q, G8 s
    文章目录2 N- `* T2 A7 s5 x0 X2 M
    背景! y! Q8 C3 H: Q% h; [$ W. f0 \3 G
    结论# I. n: m9 H9 A/ D* W
    代码% a, e0 f+ b1 W5 }. ?
    实验结果/ W; Z8 w7 q3 n& ?6 G
    RNN和DNN的区别
    $ ^# S0 T  w. d) x# {7 z2 t$ d: d, KRNN和LSTM的区别
    0 A2 q3 ^$ f% `& f9 {: X! J背景
    4 }2 F; E4 f- d9 h复现 @“使用Keras进行LSTM实战” https://blog.csdn.net/u012735708/article/details/82769711 中的实验
    , H, H$ E  C+ w+ s( M! Q# ?熟悉用LSTM模型训练3 h+ D# w! t$ O6 n
    验证将时序数据 转化为分类问题后,预测是否有效果
    ' B$ g; {. q3 @0 v6 g对比SimpleRNN与LSTM模型 哪个效果最好?) k7 c; Z) I+ ]7 D. p: A
    验证LSTM相比于Dense()模型 是否有提升?# a" m' f; ]% w$ @; O1 X* b
    对比使用前3天的数据 和使用前1天的数据 哪个效果最好?( y& f& ?+ B! I# y
    结论7 e9 V, u# ?# q/ i
    使用前3天的数据预测当天的空气质量的效果 没有 比只用前一天的数据 好$ `! a5 ^8 u5 t! O) u
    使用LSTM的效果优于SimpleRNN; q5 D" X( Y, E6 T
    代码
    ; a2 o$ f# q' [3 Nfrom pandas import read_csv
    0 H- V2 @- W" q3 l( G# b$ Tfrom datetime import datetime
    $ R8 [6 k/ r: V+ B2 H, Z  i5 Pimport pandas as pd  W* |+ x8 f+ ^8 h
    from pandas import DataFrame
      q- I% z/ j# B+ O) c7 Kfrom sklearn.preprocessing import LabelEncoder,MinMaxScaler
    7 I! s# N' T: h8 d5 g1 {5 \, sfrom sklearn.metrics import mean_squared_error
    1 f" x/ q  ^6 k: Nfrom keras.models import Sequential
    , O0 U( Z. L0 q: u' @) |9 l) Pfrom keras.layers import Dense, Dropout
    8 `! {8 P' r0 s$ _8 nfrom keras.layers import LSTM: `" t$ c. f1 `3 D. e  T
    from keras.layers.recurrent import SimpleRNN) U$ j+ b4 E( N0 m; V( Z
    from numpy import concatenate' _" n. @8 H* C, [
    from math import sqrt8 w4 @; y( M7 F' o/ D

    6 C3 J# l8 ~$ n* F) ?2 w

    # j0 L6 B* `3 m  [# O0 d' _, `1 R( V; {
    : v- v1 [: Z8 Z
    # load data' ~6 o5 U6 R3 ]0 M
    def parse(x):
    # E5 F! U2 l$ C/ g1 s* G8 ~        return datetime.strptime(x, '%Y %m %d %H')' ]  F. L3 [7 J" L& r  v8 I5 S* M, H
    - n, Z  v+ ?7 G) V* D& O
    def read_raw():
    5 L5 A7 |$ n5 M% d! ?; r    dataset = pd.read_csv('raw.csv',  parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse), d2 Q2 s! U3 T/ A6 l
        dataset.drop('No', axis=1, inplace=True)
      @" ~9 ?& P: B5 ~. v    # manually specify column names4 @0 v( j- U; z2 e  a% f' r' |
        dataset.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']
    ( {2 f( o6 ?' g3 j3 K. _    dataset.index.name = 'date'9 ^' a  S" H3 h9 r
        # mark all NA values with 03 W8 x; f, N/ U# ^6 U( L
        dataset['pollution'].fillna(0, inplace=True)& W5 G7 n; L; K1 l
        # drop the first 24 hours
    # M* N* t% R$ s) y  A1 U; q    dataset = dataset[24:]$ H' u7 D! [' b3 ~0 t' Z, }& v1 {
        # summarize first 5 rows& Y0 o. {! W' a
        print(dataset.head(5))
    8 v6 Q. v! i! L9 `    # save to file: O/ M/ X1 \8 M5 k6 ]) q4 I# Q
        dataset.to_csv('pollution.csv')2 Y4 v6 r9 }/ K  [0 p

    & A6 p0 c) Q2 F# ]/ u

      M( s# l( X9 x3 G2 R' i
    0 n6 h  f8 B& N1 U) R

    ( i, r$ Q* ?/ f4 F7 \/ O( t3 q# convert series to supervised learning
    . w: R! Y; I' d8 X4 h' p) xdef series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    * G) u' |  @, e8 {4 n( s, f7 d1 J    n_vars = 1 if type(data) is list else data.shape[1]* Y7 T: t; K% o( G6 |2 h% J& n
        df = DataFrame(data)
    2 r" l4 ~  q4 Q( X; s    cols, names = list(), list()( b, E8 \& ^6 j9 Q: e
        # input sequence (t-n, ... t-1)6 D* E4 Z: t: F. r
        for i in range(n_in, 0, -1):
    * r5 }. _$ O& j' B3 o        cols.append(df.shift(i))( X% v1 x! v% T
            names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
    3 }5 e, _+ P0 s% p    # forecast sequence (t, t+1, ... t+n)6 C3 [3 `9 K. T: k1 R4 O/ A2 q
        for i in range(0, n_out):; F" O( f8 y0 ]! N0 e
            cols.append(df.shift(-i))
    3 H$ q! u, f) o9 W0 O# a) b        if i == 0:
    - d9 c, m+ @# D: m7 u" {: [8 y            names += [('var%d(t)' % (j+1)) for j in range(n_vars)]9 N, |2 O4 R8 i9 y8 I
            else:
    - r# D. {  j, C( ]( v4 @            names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
    8 j) w; x% Z2 a8 h" j2 E' }$ `    # put it all together; v; w3 g7 v/ N
        agg = pd.concat(cols, axis=1)
    5 U+ [4 F' u& X% W4 e3 L, `    agg.columns = names
    * u: c5 |* L) V: C    # drop rows with NaN values: `1 J/ e6 u+ Y& k" A
        if dropnan:2 w; Q- e, b2 L8 D# f& B
            agg.dropna(inplace=True)
    8 z1 T7 l& {( |  B    return agg/ a( h6 z# e- L8 ^' z, j; g
    / s, ?7 N  a  N. e
    # load dataset7 c" {* R: p- H9 r
    dataset = read_csv('pollution.csv', header=0, index_col=0). S- H' Y# C  H' f% p
    values = dataset.values
    " W; ~& d/ h& ^7 P% ^
    3 n8 P" e3 A! O" e6 \: L, l4 J
    2 c5 }) y, `, m) X& X$ m
    # integer encode direction
    8 d/ a2 h# `- y+ x. H: d4 M+ h) Hencoder = LabelEncoder()* Z/ k6 z1 l  y9 W: P& [& s
    print(values[:,4])
    / i9 @9 Y, F: [/ o8 Wvalues[:,4] = encoder.fit_transform(values[:,4])
    1 u+ n9 F( Y8 f: M2 j( I1 v# ensure all data is float
    5 W3 D$ Q% k6 Vvalues = values.astype('float32')
    8 h: t1 f1 [  g0 ]3 ?% B$ b# normalize features
    ; E7 W! o, ~, S4 Z2 ^scaler = MinMaxScaler(feature_range=(0, 1))
    2 X' ~& ]6 {/ C0 Rscaled = scaler.fit_transform(values)9 y* q2 ^* k: G- o  y4 C9 C
    # frame as supervised learning2 f5 W. P  l& G- {. z' i
    reframed = series_to_supervised(scaled, 1, 1) * r) N* S% c* \; ]- z; h4 C+ H/ G
    #reframed = series_to_supervised(scaled, 3, 1) #用前3天的数据,预测当天的数据8 Q- W" m* b* }! B4 e6 Q6 n
    print("columns:", reframed.columns)# \' J  b* v2 {3 Y# o1 S9 n
    # drop columns we don't want to predict! |, [6 u7 S! Y' i
    reframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True) #用前1天的数据,预测当天的数据
    $ g/ M0 D: k0 H! U5 Z. p$ \. s#reframed.drop(reframed.columns[[25,26,27,28,29,30,31]], axis=1, inplace=True)#用前3天的数据,预测当天的数据
    4 C9 _3 M+ d$ }8 I: V0 qprint(reframed.head())
    " t7 S7 n( x3 ?9 c* d" jprint("new columns:", reframed.columns). w& r4 i* h; n- N8 b# r
    # split into train and test sets) v1 b0 h+ W# |$ j) F
    values = reframed.values: u' l& R, B% N: U: h) L
    n_train_hours = 365 * 24- }5 z1 T6 k- j$ ~; X
    train = values[:n_train_hours, :]7 U4 R1 x4 s- y0 W
    test = values[n_train_hours:, :]
    . o0 t) N0 c( Q7 Z/ P' P5 N1 }3 e# split into input and outputs
    3 N3 u- {8 J3 a5 p% U8 dtrain_X, train_y = train[:, :-1], train[:, -1]4 p. d' O4 m9 J3 b- k+ b3 ^) I* G3 [
    test_X, test_y = test[:, :-1], test[:, -1]
    6 T; l% \% G; i  \# reshape input to be 3D [samples, timesteps, features]
    - S, s+ w: i3 I! x- i8 ?#使用Dense()模型时不用变换
    : T8 x4 v- ?7 A; R, wtrain_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1])); E$ @  B4 K% M  |/ a6 V' \- t% a
    test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
    ( w: l) @) m+ E/ t2 f/ Vprint(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
    4 D0 P+ w. C: ~4 k1 G$ }# design network# T5 t0 b8 s8 I# Z0 V9 g
    model = Sequential()/ k2 q- q+ C1 z3 I& z" y/ s0 d
    #model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
    ' B) S  x2 D0 i5 O. g* J% U#model.add(Dense(50, activation='relu', input_dim = 8)), V& ^5 p8 o: H: n2 A) q
    model.add(SimpleRNN(50, input_shape=(train_X.shape[1], train_X.shape[2])))
    ) d) m3 X( X5 w1 I5 C4 mmodel.add(Dense(1)), g9 t% e# k/ G/ n! M: R
    model.compile(loss='mae', optimizer='adam')7 g% z3 V6 ?/ C& H( t, F
    # fit network
    5 h6 k1 m0 q# M6 h0 Ihistory = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
    & `! X7 e( _2 o; s' P% M! |# make a prediction" z$ [; X& @" v
    yhat = model.predict(test_X)/ R5 C5 I# |6 j1 l
    print("yhat shape:", yhat.shape)/ B; [) R* }5 y$ S- J
    '''
    ! b8 w0 {8 q2 ^. n计算在测试集上的均方差
    ! V7 x) B" ]( L7 Y6 Z2 i, mtest_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
    9 f% i6 p, E, _! O! n* D$ N# T5 Xprint("test_X shape:", test_X.shape)
    2 g0 ?4 f8 a  o& J0 R8 R
      o( [" i- X/ V. |, U+ i

    1 Z) `: C* F* F" S+ I1 g, F( s# invert scaling for forecast0 \- B( w4 ~# z( U1 U
    inv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)7 a7 P2 z' r0 C6 c8 |3 t
    inv_yhat = scaler.inverse_transform(inv_yhat)
    7 r+ B) r+ W$ A6 F: `& v0 `7 b0 zinv_yhat = inv_yhat[:,0]7 F! S# l0 m/ G' f8 L: }
    # invert scaling for actual0 e- r, O+ E7 J/ z
    test_y = test_y.reshape((len(test_y), 1))
    . _* ]% `9 y/ e4 v7 n0 C+ b* Oinv_y = concatenate((test_y, test_X[:, 1:]), axis=1)
    7 z$ u# z/ G* i% Sprint("inv_y:", inv_y[:10])
    6 r1 m/ b7 }9 }. tprint("inv_y shape:", inv_y.shape)
    4 ~4 g4 Y- W# M2 Z
    & b) t4 U7 d/ ~
    ' U4 y" r- ]7 h
    inv_y = scaler.inverse_transform(inv_y)
    6 G! Y/ T6 i# Y! cprint(inv_y, "*"*30)
    2 H" d* b! ]' ?& y& J3 s! Q* g5 G5 H+ ?& S
    8 P, I; S$ Y9 s: r  U# ~2 {6 C1 C# Z( M
    inv_y = inv_y[:,0]
    2 K# C5 D$ {  e9 P' v6 Q* }# calculate RMSE5 F+ v1 k; q; Q- T% E; O
    rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
    5 H2 Y9 S! e5 |) A) n, bprint(inv_y[:100], inv_yhat[:100])+ w: s) g( k& p5 }( r
    print('Test RMSE: %.3f' % rmse)! W8 V, h% n! s
    3 O/ S5 t1 b( G) F) [9 K
    : o/ r' ~$ q' i) c& P
    '''6 x# \; A2 w! R' t  R  ~9 {
    实验结果
    . Q9 w' ]+ G1 @- f; K
    实验1:用前一天的天气数据,预测某一天的空气质量
    " E7 ]3 T: o$ n- E) H6 r8 B) {使用LSTM模型6 j2 W) f  w& |3 o( g. Q" Q
    结果:3 L6 E' Q; M' r( {
    Epoch 49/50$ b! F: T5 T8 a2 e* t( u% ?% h  u
    0s - loss: 0.0144 - val_loss: 0.01332 C( Q4 p/ S  O' G
    Epoch 50/504 w, C0 y& n2 s; f8 s5 F" l
    0s - loss: 0.0144 - val_loss: 0.0133& j! ~9 E6 ?$ P% a8 `2 ^

    , a) I+ o) [' k! M) O" V

    ! `$ O) C& [/ M实验2:用前3天的天气数据,预测某一天的空气质量
    4 @0 }( m2 Q9 E; R* s7 H0 O% m使用LSTM模型  T  k* d* T/ i" q8 k# Y' e
    5 Z: n( [. g. L0 A3 Y: k  P" t
    ! S1 p: B; ~  H) w4 E
    结果:  `3 m4 `( u3 l4 I& e
    Epoch 49/50
    % L& R1 k, S- P  m3 Q! G9 G0s - loss: 0.0147 - val_loss: 0.01499 w1 y2 ]; k- @
    Epoch 50/50
    3 P: y8 W4 s6 M! [5 a+ v1 a. b0s - loss: 0.0147 - val_loss: 0.0150
    1 R$ e8 a# Z( u8 g
    1 z. q2 C7 d3 t4 B6 M: T( ]

    * e. r4 R/ ?$ Q2 E8 M1 d实验3:用前一天的天气数据,预测某一天的空气质量0 G4 G$ }: p; \; i: w
    使用普通的全连接模型 Dense()
    # }, |, f6 \! g结果:, S5 U- Z) E1 o" c" h0 p5 L
    Epoch 49/50
    / A# \4 m3 I* j0s - loss: 0.0144 - val_loss: 0.0146
    " V( P) Y. @: ^' ~% X' H+ mEpoch 50/509 ~* i$ i; E2 `* u: a' h% c
    0s - loss: 0.0148 - val_loss: 0.0151- a/ k  t3 x$ Q* f& g$ C

    ' x/ ^# p9 k3 z! d- ?0 C& p
    % X4 L* f4 ]5 d$ _
    实验4:用前三天的天气数据,预测某一天的空气质量6 A" y$ Z( \; e; l& o
    使用普通的全连接模型 Dense()& |9 Q% O. F) x, _
    结果:3 B: G0 [3 Z, [- B
    Epoch 49/50
    4 [3 e2 W$ H9 e6 O0s - loss: 0.0150 - val_loss: 0.01658 T2 m+ A# d" w& h6 _6 a6 c( u
    Epoch 50/50
    6 i, `* _8 O! W+ j, B3 I8 z6 R0s - loss: 0.0148 - val_loss: 0.0141
    8 |* N, Z4 ]3 `' t  h8 T& b' P  S+ }/ U
    # O8 y! i. K0 f; e* h  z* m/ S
    ( F: U7 b  z( t
    实验5:用前一天的天气数据,预测某一天的空气质量5 J  f- B/ S1 U: I9 l
    使用SimpleRNN
      H' U- n3 f6 T1 y$ A$ [6 |Epoch 49/508 c) p, A& v9 D7 k" t+ G# {: F
    0s - loss: 0.0160 - val_loss: 0.01404 l0 U# c9 y* C0 s
    Epoch 50/50( d+ R* u1 f% y6 m/ C& ^
    0s - loss: 0.0147 - val_loss: 0.0150* r7 g: @3 U- D
    & k  _3 \8 W, z/ ]5 k
    0 ~5 {# t+ x: D6 a4 H7 ~
    实验6:用前三天的天气数据,预测某一天的空气质量
    # \( U3 v8 J! e1 W6 e9 m使用SimpleRNN
    3 W! W5 c3 Q: E- m# P- s6 k* rEpoch 49/50' s- t- E- s3 w" H- W
    0s - loss: 0.0164 - val_loss: 0.0233
    7 x! k- ?/ {. {7 K0 F3 EEpoch 50/50
    ) o9 B6 Y* Y! M* a0s - loss: 0.0166 - val_loss: 0.0227
    + T+ J, W9 @6 y% u/ A; g* `; s: y8 y3 YRNN和DNN的区别

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

    / s; W1 n, o) p; I; L- e
    : v7 N8 D1 i5 \: l1 I
    - y& r. `. F2 P; H$ C, q
    RNN和LSTM的区别6 E% f- \' I& a5 U% d5 o- ~; P
    LSTM的内部结构通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样只能够“呆萌”地仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。" K- Y" X$ G; S6 G9 |

    2 Z$ {4 _, T& u
    2 _8 N# I6 ^' j( V) o* x6 x! q# w
    但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。因此很多时候我们往往会使用效果和LSTM相当但参数更少的GRU来构建大训练量的模型。
    6 a9 Z0 E& j2 C( g3 f, H+ f2 w
    1 g  ?" b+ E, X5 u( D! I* K  ~8 o% P" I: l* L" [
    请关注数学中国微博和数学中国公众号,如有疑问联系数学中国工作人员

    8 A. {1 X' ^0 g/ P; ?* @" p  _/ q
    1 W- c0 Y8 _, v; @2 i: l
    / l, ]6 X3 ?: R3 k+ a; ?
    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-13 08:24 , Processed in 0.596361 second(s), 55 queries .

    回顶部