【LSTM】北京pm2.5 天气预测--pytorch版本,有代码可以跑通-LSTM回归问题,工程落地一网打尽

文章目录

  • 前言
  • 1. 知识理解
    • 1.1 核心理解
    • 1.2 原理
      • 1.2.1 图解LSTM
      • 1.2.1 分词
      • 1.2.1 英语的词表示
      • 1.2.2 中文的词表示
      • 1.2.3 构建词表
  • 2. 工程代码
    • 2.1 数据预处理
    • 2.2 数据集&模型构建
    • 2.3 模型训练
    • 2.4 保持模型&加载模型&预测


前言

LSTM 少分析原理,更强调工程落地,今年年初有两篇LSTM的回归文章,是keras实现的。
《【LSTM】LSTM预测股票价格–单因素、多步、输出单步回归特征 -keras 1》https://blog.csdn.net/weixin_40293999/article/details/128635150
《【LSTM】多因素单步骤预测-keras 2》http://t.csdnimg.cn/vRmMe


LSTM:做回归预测的几个应用。

1. 知识理解

1.1 核心理解

核心点:m个步长,n个因素,预测p个步长q个因素。
用前一天的日均温,预测当前天的日均温度—>1 步长 1 因素 预测 1步长 1因素
用前一天的日均温、光照时长、风速、湿度预测当前天的日均温–>1 步长 4因素 预测 1步长 1因素
用前一天的 光照时长、风速、湿度预测当前天的日均温–>1 步长 3因素 预测 1步长 1因素
用前7天的 光照时长、风速、湿度预测后三天的日均温–> 7步长 3因素 预测 3步长 1因素
用前7天的 光照时长、风速、湿度预测后三天的日均温、光照时长、风速、湿度–> 7步长 3因素 预测 3步长 4因素
通过以上的例子,相信你就能明白lstm做回归任务,能做什么。

关于其原理,自行搜索下其它人的讲解即可。本篇主要讲落地细节。

1.2 原理

1.2.1 图解LSTM

原理 ref: https://colah.github.io/posts/2015-08-Understanding-LSTMs/
RNN:
在这里插入图片描述
在这里插入图片描述
LSTM:
在这里插入图片描述
这张图挺好理解的:这个简洁来说就像个全加器一样,输出和进位都靠上一位的进位和本位的输入,挺好理解的

问题:特征 x1, x2,…xt 这t个x 对应的是什么?
就是一组特征向量,比如可以使7天的温度【一维向量 7】,也可以是7天的多维向量温度、湿度【二维向量 7X2】

1.2.1 分词

温度/湿度本身就是数字,但是若是影评数据呢?比如 当幸福来敲门的台词:
You got a dream, you gotta protect it. Dont ever let somebody tell you, you can’t do something. Not even me. People can’t do something themselves, they wanna tell you,you can’t do it.
1)去标点 2)转成全小写 3)按 “ ”【空格】分词

s = "You got a dream, you gotta protect it. Dont ever let somebody tell you, you can't  do something. Not even me. People can't do something themselves, they wanna tell you,you can't do it."
import string
print("punctuation::",string.punctuation)
for c in string.punctuation:s = s.replace(c,' ').lower()
print("after deal with punctuation::",s)
punctuation:: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
after deal with punctuation:: you got a dream  you gotta protect it  dont ever let somebody tell you  you can t  do something  not even me  people can t do something themselves  they wanna tell you you can t do it 
np.unique(s.split())
array(['a', 'can', 'do', 'dont', 'dream', 'even', 'ever', 'got', 'gotta','it', 'let', 'me', 'not', 'people', 'protect', 'somebody','something', 't', 'tell', 'themselves', 'they', 'wanna', 'you'],dtype='<U10')

然后把这些词挨个变成映射【字典】,再用100维的张量表示每一个单词即可。

1.2.1 英语的词表示

这里说的特征就是数字类的,而不是文本类的比如影评、商品评价、外卖评价等等。
多啰嗦一句,其实一个英文影评(同步类比外卖、商品评价)的单词数量,就是 x1,x2,…xt, 对应的是t个单词。但是torch只能计算,只能存储float,int…等数字类型的tensor,你这个文本算个啥,所以需要将英语表示为【数字】特征,也就是词表示【word representation】,通常使用词嵌入【word embedding】的方式。每个单词可以表示为n维度,比如200,这个可以自定义,也可以用预训练的。

1.2.2 中文的词表示

1.2.1 说清楚了英文的词表示,那么中文呢,中文和英语其实极为相似,但是最大的不同是,英语很好分词,因为天然的空格存在,按空格分词【token】,再词表示就可以,中文没空咋给一句话【一段话】分词呢?用个插件jieba即可。
例子:

jieba.lcut("你说过两天来看我,转眼就是一年多!")
['你', '说', '过', '两天', '来看', '我', ',', '转眼', '就是', '一年', '多', '!']

1.2.3 构建词表

所以无论中英文,都需要构建词表,也就是分好词的所有词的list,比如所用影评分好词后的unique词是3W个,那么我们实际上就有一个len=3W的词表,
但通常还需要另外的两个词和。因为数据对齐的问题,比如我们就想让一条评论是200【多少的长度是自己定的】个单词。 那多了,就截断了,少的就用填充。
另外,还需要一个注意点,就是从set【集合】的角度看,词表有3W个,但里面可能有只出现过1次的,他们可能是生僻词,或者拼写错误的,没啥具体含义。所以,做映射的时候,可能制取词频>=10的。那么没取到的,就被映射为unknow了。
然后,再用1.2的词表示。 这样,一条评论。最终就是 200个单词, 每个单词用100维的向量【数字】来表示。这样就和1.1的原理完全对上了。

2. 工程代码

2.1 数据预处理

在这里插入图片描述
pandas 读取数据,并完成预处理
No year month day hour pm2.5 DEWP TEMP PRES cbwd Iws Is Ir
0 1 2010 1 1 0 NaN -21 -11.0 1021.0 NW 1.79 0 0
1 2 2010 1 1 1 NaN -21 -12.0 1020.0 NW 4.92 0 0
2 3 2010 1 1 2 NaN -21 -11.0 1019.0 NW 6.71 0 0
3 4 2010 1 1 3 NaN -21 -14.0 1019.0 NW 9.84 0 0
4 5 2010 1 1 4 NaN -20 -12.0 1018.0 NW 12.97 0 0

数据处理:把PM2.5 为null的数据都用相邻的数据填充,我们取2010年1月2日以后的数据。

data = data.iloc[24:].bfill()
print(data[0:5])

在这里插入图片描述
把年,月,日 和小时 合并为一列。

import datetime
data['time'] = data.apply(lambda x: datetime.datetime(year=x['year'],month =x['month'],day = x['day'],hour = x['hour']),axis = 1)
    No  year  month  day  hour  pm2.5  DEWP  TEMP    PRES cbwd   Iws  Is  Ir                time
24  25  2010      1    2     0  129.0   -16  -4.0  1020.0   SE  1.79   0   0 2010-01-02 00:00:00
25  26  2010      1    2     1  148.0   -15  -4.0  1020.0   SE  2.68   0   0 2010-01-02 01:00:00
26  27  2010      1    2     2  159.0   -11  -5.0  1021.0   SE  3.57   0   0 2010-01-02 02:00:00
27  28  2010      1    2     3  181.0    -7  -5.0  1022.0   SE  5.36   1   0 2010-01-02 03:00:00
28  29  2010      1    2     4  138.0    -7  -5.0  1022.0   SE  6.25   2   0 2010-01-02 04:00:

去掉 年,月,日 和小时,并且把 时间列 作为索引index

data.drop(columns=['No','year','month','day','hour'],inplace = True)
data = data.set_index('time')
                     pm2.5  DEWP  TEMP    PRES cbwd   Iws  Is  Ir
time
2010-01-02 00:00:00  129.0   -16  -4.0  1020.0   SE  1.79   0   0
2010-01-02 01:00:00  148.0   -15  -4.0  1020.0   SE  2.68   0   0
2010-01-02 02:00:00  159.0   -11  -5.0  1021.0   SE  3.57   0   0
2010-01-02 03:00:00  181.0    -7  -5.0  1022.0   SE  5.36   1   0
2010-01-02 04:00:00  138.0    -7  -5.0  1022.0   SE  6.25   2   0

One-hot 编码 风向序列

data = data.join(pd.get_dummies(data.cbwd))
del data['cbwd']
                     pm2.5  DEWP  TEMP    PRES   Iws  Is  Ir     NE     NW    SE     cv
time
2010-01-02 00:00:00  129.0   -16  -4.0  1020.0  1.79   0   0  False  False  True  False
2010-01-02 01:00:00  148.0   -15  -4.0  1020.0  2.68   0   0  False  False  True  False
2010-01-02 02:00:00  159.0   -11  -5.0  1021.0  3.57   0   0  False  False  True  False
2010-01-02 03:00:00  181.0    -7  -5.0  1022.0  5.36   1   0  False  False  True  False
2010-01-02 04:00:00  138.0    -7  -5.0  1022.0  6.25   2   0  False  False  True  False

查看2012年到2014年的数据

data['pm2.5'][-365*24:].plot()
data['pm2.5'][-365*24*2:-365*24].plot()
data['pm2.5'][-365*24*3:-365*24*2].plot()

在这里插入图片描述
用前6天的数据预测第7天的大气PM2.5

sequence_length = 6*24
delay = 24
data_ = []
for i in range(len(data) - sequence_length - delay):data_.append(data.iloc[i: i + sequence_length + delay])
data_ = np.array([df.values for df in data_])
np.random.shuffle(data_)
x = data_[:, :-delay, :]
y = data_[:, -1, 0]

把数据的80%分成训练集合,20%分为测试集合。

split_boundary = int(data_.shape[0] * 0.8)
train_x = x[: split_boundary]
test_x = x[split_boundary:]train_y = y[: split_boundary]
test_y = y[split_boundary:]

对数据标准化

mean = train_x.mean(axis=0) #均值
std = train_x.std(axis=0) #标准差
train_x = (train_x - mean)/std
test_x = (test_x - mean)/std

2.2 数据集&模型构建


class Mydataset(torch.utils.data.Dataset):def __init__(self, features, labels):self.features = featuresself.labels = labelsdef __getitem__(self, index):feature = self.features[index]label = self.labels[index]return feature, labeldef __len__(self):return len(self.features)
train_ds = Mydataset(train_x, train_y)
test_ds = Mydataset(test_x, test_y)
BTACH_SIZE = 128
train_dl = torch.utils.data.DataLoader(train_ds,batch_size=BTACH_SIZE,shuffle=True
)
test_dl = torch.utils.data.DataLoader(test_ds,batch_size=BTACH_SIZE
)

构建模型

hidden_size = 64
class Net(nn.Module):def __init__(self, hidden_size):super(Net, self).__init__()self.rnn = nn.LSTM(train_x.shape[-1], hidden_size, batch_first=True)self.fc1 = nn.Linear(hidden_size, 128)self.fc2 = nn.Linear(128, 1)def forward(self, inputs):_, s_o = self.rnn(inputs)s_o = s_o[-1]x = F.dropout(F.relu(self.fc1(s_o)))x = self.fc2(x)return torch.squeeze(x)
model = Net(hidden_size)
if torch.cuda.is_available():model.to('cuda')

构建损失和优化函数


loss_fn = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

2.3 模型训练

训练过程

def fit(epoch, model, trainloader, testloader):total = 0running_loss = 0model.train()for x, y in trainloader:if torch.cuda.is_available():x, y = x.to('cuda'), y.to('cuda')y_pred = model(x)loss = loss_fn(y_pred, y)optimizer.zero_grad()loss.backward()optimizer.step()with torch.no_grad():total += y.size(0)running_loss += loss.item()
#    exp_lr_scheduler.step()epoch_loss = running_loss / len(trainloader.dataset)test_total = 0test_running_loss = 0 model.eval()with torch.no_grad():for x, y in testloader:if torch.cuda.is_available():x, y = x.to('cuda'), y.to('cuda')y_pred = model(x)loss = loss_fn(y_pred, y)test_total += y.size(0)test_running_loss += loss.item()epoch_test_loss = test_running_loss / len(testloader.dataset)print('epoch: ', epoch, 'loss: ', round(epoch_loss, 3),'test_loss: ', round(epoch_test_loss, 3),)return epoch_loss, epoch_test_loss
epochs = 100
train_loss = []
test_loss = []for epoch in range(epochs):epoch_loss, epoch_test_loss = fit(epoch,model,train_dl,test_dl)train_loss.append(epoch_loss)test_loss.append(epoch_test_loss)

训练过程loss


epoch:  0 loss:  23.613 test_loss:  25.115
epoch:  1 loss:  23.081 test_loss:  24.546
epoch:  2 loss:  22.261 test_loss:  23.605
epoch:  3 loss:  21.603 test_loss:  23.745
epoch:  4 loss:  21.623 test_loss:  24.013
epoch:  5 loss:  21.449 test_loss:  24.356
epoch:  6 loss:  21.052 test_loss:  22.461
epoch:  7 loss:  21.267 test_loss:  24.883
epoch:  8 loss:  21.083 test_loss:  21.641
epoch:  9 loss:  20.027 test_loss:  24.942
epoch:  10 loss:  19.944 test_loss:  20.995
epoch:  11 loss:  20.05 test_loss:  23.553
epoch:  12 loss:  30.013 test_loss:  29.03
epoch:  13 loss:  23.522 test_loss:  22.274
epoch:  14 loss:  20.181 test_loss:  21.099
epoch:  15 loss:  19.553 test_loss:  20.401
epoch:  16 loss:  18.925 test_loss:  21.033
epoch:  17 loss:  18.798 test_loss:  19.627
epoch:  18 loss:  19.772 test_loss:  20.952
epoch:  19 loss:  19.922 test_loss:  20.91
epoch:  20 loss:  19.068 test_loss:  20.825
epoch:  21 loss:  18.103 test_loss:  19.203
epoch:  22 loss:  19.176 test_loss:  20.891
epoch:  23 loss:  17.713 test_loss:  19.167
epoch:  24 loss:  17.063 test_loss:  18.672
epoch:  25 loss:  19.715 test_loss:  23.334
epoch:  26 loss:  21.586 test_loss:  20.307
epoch:  27 loss:  18.127 test_loss:  19.236
epoch:  28 loss:  16.943 test_loss:  18.996
epoch:  29 loss:  17.403 test_loss:  19.15
epoch:  30 loss:  16.35 test_loss:  18.142
epoch:  31 loss:  16.166 test_loss:  18.056
epoch:  32 loss:  16.363 test_loss:  20.465
epoch:  33 loss:  16.122 test_loss:  17.937
epoch:  34 loss:  15.48 test_loss:  17.128
epoch:  35 loss:  17.159 test_loss:  19.565
epoch:  36 loss:  18.402 test_loss:  22.737
epoch:  37 loss:  17.671 test_loss:  19.016
epoch:  38 loss:  16.368 test_loss:  17.944
epoch:  39 loss:  15.901 test_loss:  18.256
epoch:  40 loss:  15.695 test_loss:  18.299
epoch:  41 loss:  15.447 test_loss:  16.485
epoch:  42 loss:  14.995 test_loss:  16.351
epoch:  43 loss:  14.906 test_loss:  17.371
epoch:  44 loss:  14.784 test_loss:  16.312
epoch:  45 loss:  15.204 test_loss:  17.165
epoch:  46 loss:  15.076 test_loss:  16.702
epoch:  47 loss:  14.528 test_loss:  15.929
epoch:  48 loss:  14.185 test_loss:  31.667
epoch:  49 loss:  22.848 test_loss:  20.964

2.4 保持模型&加载模型&预测

# 模型参数保存
torch.save(model.state_dict(), 'model_param.pt')
# 模型参数加载
model = Net(...)
model.load_state_dict(torch.load('model_param.pt'))
data_test = data[-24*6:]
data_test = (data_test - mean)/std
data_test = data_test.to_numpy()
data_test = np.expand_dims(data_test,0)
pm = model(torch.from_numpy(data_test).float().cuda())

在这里插入图片描述
在这里插入图片描述

ref: https://www.aqistudy.cn/historydata/daydata.php?city=%E5%8C%97%E4%BA%AC&month=2015-01

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/152525.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络渗透测试(TCP/IP)理论篇

TCP/IP体系 垂直服务&#xff1a;底层为高层服务 TCP/IP体系结构是一个分层的协议体系&#xff0c;由多个层次组成&#xff0c;每个层次都负责不同的功能。以下是TCP/IP体系结构的主要层次&#xff1a; 物理层&#xff08;Physical Layer&#xff09;&#xff1a;该层负责传输…

Debian系列的Linux发行版上部署wvp

Debian系列的Linux发行版上部署wvp 环境搭建1.Debian系列的Linux发行版上安装nginx2.安装mysql设置mysql密码修改权限sudo mysql ERROR 1045 (28000): Access denied for user root@localhost (using password: NO)配置相关navicat 连接不上 报错 10061navicat 连接报错 1130 -…

grafana面板介绍

grafana 快速使用 背景 随着公司业务的不断发展&#xff0c;紧接来的是业务种类的增加、服务器数量的增长、网络环境的越发复杂以及发布更加频繁&#xff0c;从而不可避免地带来了线上事故的增多&#xff0c;因此需要对服务器到应用的全方位监控&#xff0c;提前预警&#xf…

MATLAB | 官方举办的动图绘制大赛 | 第二周赛情回顾

今天带来一下MATHWORKS官方举办的迷你黑客大赛第三期(MATLAB Flipbook Mini Hack)的最新进展&#xff01;&#xff01;目前比赛已经进行了两周非常荣幸能够成为第一周的阶段性获奖者&#xff1a; 本来并不打算每周进行一次赛况讲解&#xff0c;但是由于字符限制改成了2000&…

Linux系统编程 day02 vim、gcc、库的制作与使用

Linux系统编程 day02 vim、gcc、库的制作与使用 01. vim0101. 命令模式下的操作0102. 切换到文本输入模式0103. 末行模式下的操作0104. vim的配置文件 02. gcc03. 库的制作与使用0301. 静态库的制作与使用0302. 动态库(共享库)的制作与使用 01. vim vim是一个编辑器&#xff0…

Run Legends将健身运动游戏化,使用户保持健康并了解Web3游戏

最近&#xff0c;我们有机会采访Talofa Games的首席执行官兼创始人Jenny Xu&#xff0c;一起讨论游戏开发&#xff0c;Talofa Games是Run Legends这款健身游戏的开发工作室。她已经创作了超过一百款游戏&#xff0c;对于推动游戏的可能性并将她的创造力和叙事技巧带入她最喜爱的…

leetcode数据结构与算法刷题(三)

目录 第一题 交叉链表 思想&#xff1a; 注意点 第一步先求两个链表的长度 第二步 让长的先走&#xff0c;当长短一样时一起走。 犯错点 第二题 判断是有环 思想&#xff1a; 注意 错误分享 第三题&#xff08;重点面试题&#xff09; 思路&#xff1a; 这题面试问题&a…

电子学会C/C++编程等级考试2022年06月(一级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:倒序输出 依次输入4个整数a、b、c、d,将他们倒序输出,即依次输出d、c、b、a这4个数。 时间限制:1000 内存限制:65536输入 一行4个整数a、b、c、d,以空格分隔。 0 < a,b,c,d < 108输出 一行4个整数d、c、b、a,整数之…

解决证书加密问题:OpenSSL与urllib3的兼容性与优化

在使用客户端证书进行加密通信时&#xff0c;用户可能会遇到一些问题。特别是当客户端证书被加密并需要密码保护时&#xff0c;OpenSSL会要求用户输入密码。这对于包含多个调用的大型会话来说并不方便&#xff0c;因为密码无法在连接的多个调用之间进行缓存和重复使用。用户希望…

飞翔的小鸟

运行游戏如下&#xff1a; 碰到柱子就结束游戏 App GameApp类 package App;import main.GameFrame;public class GameApp {public static void main(String[] args) {//游戏的入口new GameFrame();} } main Barrier 类 package main;import util.Constant; import util.Ga…

基于AVR单片机的便携式心电监测设备设计与实现

基于AVR单片机的便携式心电监测设备是一种常用的医疗设备&#xff0c;用于随时监测和记录人体的心电信号。本文将介绍便携式心电监测设备的设计原理和实现步骤&#xff0c;并提供相应的代码示例。 1. 设计概述 便携式心电监测设备是一种小巧、方便携带的设备&#xff0c;能够…

【前端学java】java 中的数组(9)

往期回顾&#xff1a; 【前端学java】JAVA开发的依赖安装与环境配置 &#xff08;0&#xff09;【前端学 java】java的基础语法&#xff08;1&#xff09;【前端学java】JAVA中的packge与import&#xff08;2&#xff09;【前端学java】面向对象编程基础-类的使用 &#xff08…

测试Bard和ChatGPT关于双休的法规和推理

Bard是试验品&#xff0c;chatgpt是3.5版的。 首先带着问题&#xff0c;借助网络搜索&#xff0c;从政府官方网站等权威网站进行确认&#xff0c;已知正确答案的情况下&#xff0c;再来印证两个大语言模型的优劣。 想要了解的问题是&#xff0c;在中国&#xff0c;跟法定工作…

论文笔记:The Impact of AI on Developer Productivity:Evidence from GitHub Copilot

0 abstract 本文介绍了一项对GitHub Copilot&#xff08;一种人工智能编程助手&#xff09;的控制实验结果。研究人员招募了软件开发人员&#xff0c;要求他们尽可能快地用JavaScript实现一个HTTP服务器。实验组可以访问人工智能编程助手&#xff0c;比对照组完成任务的速度快…

SpringCloud 微服务全栈体系(十四)

第十一章 分布式搜索引擎 elasticsearch 四、RestAPI ES 官方提供了各种不同语言的客户端&#xff0c;用来操作 ES。这些客户端的本质就是组装 DSL 语句&#xff0c;通过 http 请求发送给 ES。官方文档地址&#xff1a;https://www.elastic.co/guide/en/elasticsearch/client/…

【Windows 常用工具系列 11 -- 福昕PDF搜索高亮过的文本】

文章目录 福昕 PDF 搜索高亮过的文本 福昕 PDF 搜索高亮过的文本 在 pdf 文档阅读过程中&#xff0c;我们需要经常高亮一些文本&#xff0c;以方便下次阅读时找到重点。我这边使用的是 福昕PDF 阅读器&#xff0c;下面就介绍下如何在福昕阅读器中搜索已经高亮过的文本。

音视频同步笔记 - 以音频时间为基

音视频同步 - 以音频时间为基 上图介绍&#xff1a; 该图是以音频的时间为基&#xff0c;对视频播放时间的延迟控制方案&#xff0c;只调整视频的播放延时。delayTime是视频播放的延迟时间&#xff0c;初始值是1 / FPS * 1000 (ms)&#xff0c;如果FPS为25帧率&#xff0c;初始…

nodejs微信小程序 +python+PHP+图书销售管理系统的设计与实现-网上书店-图书商城-计算机毕业设计

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

桥接模式学习

目录 背景过程总结 背景 现在要解决源码阶段的继承关系&#xff0c;无法在运行时改变从父类继承的实现。这里用的是手机品牌还有手机中的app&#xff0c;这种问题如何进行解决呢。这就要引入一个模式&#xff1a;桥接模式 过程 1、原则&#xff1a;合成/复用原则 &#xff1…

PPT幻灯片里的图片,批量提取

之前分享过如何将PPT文件导出成图片&#xff0c;今天继续分享PPT技巧&#xff0c;如何提取出PPT文件里面的图片。 首先&#xff0c;我们将PPT文件的后缀名&#xff0c;修改为rar&#xff0c;将文件改为压缩包文件 然后我们将压缩包文件进行解压 最好是以文件夹的形式解压出来…