博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(神经网络)i7处理器日常裂开的一天:从网络爬虫到数据预测作图,基于LSTM和RNN的温度序列预测
阅读量:3969 次
发布时间:2019-05-24

本文共 7383 字,大约阅读时间需要 24 分钟。

目录

代码已在本人设备上完美的跑过了,如果在一些读者的电脑上有问题,大家可以检查如下东西:1. 代码是否拼接在一起,因为实在jupyter上写的,因此我这里不需要刻意拼接大家可以将代码糅合在一起。2. torch版本和anconda版本的问题,可能有部分函数或者方法不兼容。3. matplotlib版本问题,在之前的某次版本更新后,pyplot的部分方法   改变了。4. 文件的读取形式,我的csv文件的存储形式为ANSI,因此使用UTF-8的   编码可能会报错。

该文章包含了从爬取数据到训练模型预测数据画图的整个过程,莫 白 嫖。。。。。。。。

爬虫部分:爬取数据及分离数据

数据网址:

因为需要大量的数据,所以需要爬取k个网页的数据,因此,包含了几个url,该url只是第一个罢了,具体的情况可以在代码中看到。

#依靠网络爬虫获取数据import requestsfrom bs4 import BeautifulSoupimport csvimport redef get_html(url):    header={
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding':'gzip, deflate', 'Accept-Language':'zh-CN,zh;q=0.9', 'Connection':'keep-alive', 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36', } rep=requests.get(url,headers=header,timeout=random.choice(range(50,80))).coding='utf-8' return rep.textdef get_data(html): bs=BeautifulSoup(html,'html.parser') text_list=[] li=bs.find('ul',class_='thrui').find_all('li') for line in li: text_list.append(line.text.replace('\n','').split(' ')) return text_listdef solve_list(data): data.insert(2,re.compile(r'\d+') .findall(data[2])[0]) data.insert(3,re.compile(r'\d+') .findall(data[3])[1]) data.pop(1) data=data[:3] return datadef write_in_csv(filename,data): with open(filename,"a",newline='') as filewrite: for line in data: csv.writer(filewrite).writerow(line)def __Main__(): data=[] with open('weather.csv','w',newline='') as filewrite: csv.writer(filewrite).writerow(['time','min','max']) for y in range(11,21): for m in range(1,13): if m<10: url='http://lishi.tianqi.com/xian/20'+str(y)+'0'+str(m)+'.html' else: url=url='http://lishi.tianqi.com/xian/20'+str(y)+str(m)+'.html' print(url,'爬取完成') for i in get_data(get_html(url)): data.append(solve_list(i)) write_in_csv('weather.csv',data) print('写入完成')__Main__()
这里将数据爬取和数据处理放在同一个py文件中,是为了到时候,用数据时不需要太多的处理,这里注意我的桌面位置是E盘。

预测部分:训练及建模

最小温度数据预测

# -*- coding: utf-8 -*-import numpy as npimport pandas as pd import matplotlib.pyplot as pltimport timeimport torchfrom torch.autograd import Variableimport torch.nn as nnimport datetimedef get_dataset(dataset,look_back):    data_x=data_y= []    for i in range(len(dataset)-look_back):          data_x.append(dataset[i:i+look_back])          data_y.append(dataset[i+look_back])    return np.asarray(data_x), np.asarray(data_y) #转为ndarray数据class RNN(nn.Module):    def __init__(self):        super(RNN,self).__init__() #面向对象        self.lstm = nn.LSTM(2,6,2) #输入:2个特征6个隐藏层,2个LSTM串联        self.out = nn.Linear(6,1) #接受6维,输出1维,承接上面一行代码    def forward(self,x):        x1,_ = self.lstm(x)        a,b,c = x1.shape        out = self.out(x1.view(-1,c))         out1 = out.view(a,b,-1)        return out1#实例化一个RNNrnn = RNN()#加载数据file='E:\\桌面\\jupyter_notebook\\weather.csv'data=pd.read_csv(file,encoding='ANSI')#检查数据print('数据维度:', data.shape)datas_min=data['min'].valuesdatas_min=np.array([[m] for m in data['min']])max_datas_min,min_datas_min=np.max(datas_min),np.min(datas_min)#这里归一化并没有必要,当然这里归一化可以处理的更快,但是会丢失一些精度,在本身就丢失了一些精度的训练情况下,我想尽可能的提高精度。#datas_min=list(map(lambda x:(x-min_datas_min)/(max_datas_min-min_datas_min),datas_min))data_min_X,data_min_Y=creat_dataset(datas_min,2)x_min_train=torch.from_numpy(data_min_X[:2500].reshape(-1, 1, 2))#这里通过reshape转化维度,成为我们可以利用的数据y_min_train=torch.from_numpy(data_min_Y[:2500] .reshape(-1, 1, 1) )#optim优化算法 构造一个优化器 指定优化对象optimizer=torch.optim.Adam(rnn.parameters(),lr = 0.02)#这里选择训练一千轮是因为我发现在九百到一千轮的,损失已经很难在降低了。for i in range(1000):    var_x=Variable(x_min_train).type(torch.FloatTensor)    var_y=Variable(y_min_train).type(torch.FloatTensor)    out =rnn(var_x)    loss=nn.MSELoss()(out,var_y)    optimizer.zero_grad()    loss.backward()    optimizer.step()    if (i+1)%100==0:        print('次数:{}, 损失:{:.5f}'.format(i+1, loss.item()))#获取测试集数据 并转化类型var_dataX=Variable(torch.from_numpy(data_min_X.reshape(-1,1,2))).type(torch.FloatTensor)#训练模型pred=rnn(var_dataX)print(pred)
  1. 在利用到代码的时候,一定一定要注意维度的问题,网路的输出维度和输入维度并不同,但是我们要求输出的数据维度为1。维度为啥是多隐层呢?其实网络的每一个隐层就是一个二分类问题,我们可以通过决策树去想,而且,本质上来说,一个多分类问题就是一个有限的二分类问题的集合。虽然多隐层可能会导致很明显的过拟合,但是实际上空中有限的次数,我们就能得到一个很好的模型。
  2. 因为是初学pytorch,因此很多类和方法理解并不好,所以不得不去网上查了很多的博客和资料,因此可能部分代码会出现相似度很高的情况。
  3. 本身是想按面向对象的标准写法去写,但是今天实在是太累了,就不改了。
  4. 在跑网络的时候一定要注意损失的问题,当你发现损失已经明显不在降低了,那就没必要在设置更多的训练次数了。
    既然最小数据的预测已经在那了,那么最大数据的预测就很容易写(实际上只需要读取文件的列就可以了)
    代码:
# -*- coding: utf-8 -*-import numpy as npimport pandas as pd import matplotlib.pyplot as pltimport timeimport torchfrom torch.autograd import Variableimport torch.nn as nnimport datetimedef creat_dataset(dataset,look_back):    data_x = []    data_y = []    for i in range(len(dataset)-look_back):          data_x.append(dataset[i:i+look_back])          data_y.append(dataset[i+look_back])    return np.asarray(data_x), np.asarray(data_y) #转为ndarray数据class RNN(nn.Module):    def __init__(self):        super(RNN,self).__init__() #面向对象中的继承        self.lstm = nn.LSTM(2,6,2) #输入数据2个特征维度,5个隐藏层维度,2个LSTM串联,第二个LSTM接收第一个的计算结果        self.out = nn.Linear(6,1) #线性拟合,接收数据的维度为6,输出数据的维度为1    def forward(self,x):        x1,_ = self.lstm(x)        a,b,c = x1.shape        out = self.out(x1.view(-1,c)) #因为线性层输入的是个二维数据,所以此处应该将lstm输出的三维数据x1调整成二维数据,最后的特征维度不能变        out1 = out.view(a,b,-1) #因为是循环神经网络,最后的时候要把二维的out调整成三维数据,下一次循环使用        return out1#加载数据file='E:\\桌面\\jupyter_notebook\\weather.csv'data=pd.read_csv(file,encoding='ANSI')#检查数据print('数据维度:', data.shape)datas_min=data['max'].valuesdatas_min=np.array([[m] for m in data['max']])max_datas_min,min_datas_min=np.max(datas_min),np.min(datas_min)#做归一化处理#datas_min=list(map(lambda x:(x-min_datas_min)/(max_datas_min-min_datas_min),datas_min))#print(datas_min)data_min_X,data_min_Y=creat_dataset(datas_min,2)x_min_train=data_min_X[:2500]y_min_train=data_min_Y[:2500] x_min_train=x_min_train.reshape(-1, 1, 2) y_min_train=y_min_train.reshape(-1, 1, 1) x_min_train=torch.from_numpy(x_min_train)y_min_train=torch.from_numpy(y_min_train)rnn = RNN()#计算损失函数optimizer = torch.optim.Adam(rnn.parameters(),lr = 0.02)loss_func = nn.MSELoss()for i in range(1000):    var_x = Variable(x_min_train).type(torch.FloatTensor)    var_y = Variable(y_min_train).type(torch.FloatTensor)    out = rnn(var_x)    loss = loss_func(out,var_y)    optimizer.zero_grad()    loss.backward()    optimizer.step()    if (i+1)%100==0:        print('次数:{}, 损失:{:.5f}'.format(i+1, loss.item()))data_min_X1=data_min_X.reshape(-1,1,2)data_min_X2=torch.from_numpy(data_min_X1)var_dataX=Variable(data_min_X2).type(torch.FloatTensor)pred=rnn(var_dataX)print(pred)
代码所预测的是每日的最高温和最低温,平均温度的问题很好解决。这里不多做赘述。

绘图

利用matplotlib绘图

绘图的代码给个最低温就可以了,最低温只需要改几个词就可以了。
import matplotlib.dates as mdatespred_test=pred.view(-1).data.numpy()data_times=[datetime.datetime.strptime(time,'%Y-%m-%d') for time in data['time'] ]#data_min_Y为实值 预测值为pred[:-2] 时间为plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签plt.rcParams['axes.unicode_minus']=False #用来正常显示负号plt.figure(figsize=(30,30))plt.xlabel('日期')plt.ylabel('温度/℃')plt.title('西安市日最低温度预测曲线')plt.plot(data_times[:-2],pred.view(-1).data.numpy(), 'r',color='red', label='预测')plt.plot(data_times[:-2],data_min_Y, 'b',color='yellow', label='实值')#添加标签plt.legend(loc='best')

结果:

在这里插入图片描述

转载地址:http://gzcki.baihongyu.com/

你可能感兴趣的文章
设备标识及驱动程序所支持的设备(…
查看>>
EXPORT_SYMBOL()
查看>>
EXPORT_SYMBOL()
查看>>
在fedora9中编译linux设备驱动程序…
查看>>
在fedora9中编译linux设备驱动程序…
查看>>
LDDR3中scull编译问题
查看>>
LDDR3中scull编译问题
查看>>
内核模块转
查看>>
内核模块转
查看>>
ARM中断原理,&nbsp;中断嵌套的误区,中…
查看>>
ARM中断原理,&nbsp;中断嵌套的误区,中…
查看>>
struct&nbsp;device&nbsp;中的dev_id哪里去了…
查看>>
struct&nbsp;device&nbsp;中的dev_id哪里去了…
查看>>
Platform总线
查看>>
Platform总线
查看>>
Linux驱动程序中的platform总线详…
查看>>
Linux驱动程序中的platform总线详…
查看>>
按键驱动--platform设备的例子
查看>>
按键驱动--platform设备的例子
查看>>
mini2440按键驱动及详细解释(转)
查看>>