pytorch气温预测实战

1.导包

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import torch
import torch.optim as optim
%matplotlib inline
import datetime
import torch.nn as nn

2.导入数据

features = pd.read_csv("./data/temps.csv")
features.shape

在这里插入图片描述
此处可以看到,样本数量348,一共9列,其中年月日占三列

3.处理数据

  1. 将年月日整理为一个字段
years = features['year']
months=features['month']
days = features['day']
dates = []
# 此处两种写法, 1、for循环 append的方式写入数组
for y,m,d in zip(years,months,days):
    dates.append(str(y)+'-'+str(m)+'-'+str(d))
# 2.[A for B in C] 这个写法,遍历C中的B,把满足条件A的放到数组里
##举例[a for b in c] 一个例子 Y = [ [ int(x1+x2 < 1) ] for (x1, x2) in X ] 对X中的每一组元素(x1, x2)遍历一遍,当满足(x1+x2 < 1)时,就把这个布尔值[True]/[False]转换成int型(1或0),存放在[ ]里,作为Y的一个元素。

dates = [datetime.datetime.strptime(date,"%Y-%m-%d") for date in dates]
dates[:5]

在这里插入图片描述
tip:循环遍历的写法

  1. 把日期放到原数据后
# 使用date命名,将数组dates作为列内容,创建为dataframe
dates_df = pd.DataFrame(data = {'date': dates})
# 使用concat链接,需要将两个dataframe连接起来,axis表示是横向追加还是纵向追加,横向是加样本,纵向是加列
features=pd.concat([features, dates_df], axis=1)
features

在这里插入图片描述
3. week字段属于离散值类型,对这种类型的数据进行独热编码处理(onehot)

# 独热编码,两个方式,getdummies
features = pd.get_dummies(features,columns=['week'])
features.head(5)

处理完成后,结果会在原来的dataframe上追加列
在这里插入图片描述
独热编码原理:
1、获取当前列的所有值,有几个算几个
2、将值进行排序,数字或字母大小写
3、按顺序编码,比如 男、女,男10,女01

通过oneHotEncoder处理的方式,这个是sklearn中的包,缺点,没有那么智能,可以自动加列,onehotEncoder处理完的列名用0,1,2,3这种顺序编码

独热编码的问题:如果训练集中没有,但是测试集中有,那么会缺失编码值。

# 独热编码,两个方式,OneHotEncoder
# 取当前列所有的值进行扩展,按照原始数据的大小排序,排序后进行编码,和getDummies产出数据一样

 from sklearn import preprocessing  
 enc = preprocessing.OneHotEncoder()
 weekcol = pd.DataFrame(enc.fit_transform(features[['week']]).toarray())
 features=pd.concat([features, weekcol], axis=1)
 features.drop(['week'],axis=1)

4、删除无用数据,并将真实值单独存储

# 真实值标签
labels = np.array(features['actual'])
#真实值和date对应关系,便于后续绘图
true_data=pd.DataFrame(data={'date':dates,'actual':labels})

# 在特征中去掉标签
features= features.drop(labels={'actual','year','month','day'}, axis = 1)

5、处理数据标准化

# 转化为标准的正态分布
#fit  需要先执行fit,适配 
#transform  执行具体操作
from sklearn import preprocessing
input_features = preprocessing.StandardScaler().fit_transform(features)
input_features.shape

4. 定义模型

class TempModel(nn.Module):
    def __init__(self,inputSize,outputSize):
    #需要调super,否则有报错
        super(TempModel,self).__init__()
        self.inputSize=inputSize
        self.outputSize=outputSize
        #定义隐藏128
        #该网络一个全连接,激活函数sigmoid,一个隐藏层128个神经元,输出一个结果
        self.net=nn.Sequential(
            nn.Linear(inputSize,128),
            nn.Sigmoid(),
            nn.Linear(128,outputSize)
        )
    def forward(self,inputData):
        return self.net(inputData)
def trainMode(batchSize,opti,inputData,model,labels,loss,device):
    batch_loss = []
    #模型训练
    model.train()   
    #按批次取
    for start in range(0,len(inputData),batchSize):
        end = min(len(inputData),start+batchSize)
        #需要将数据&model都放到一个device中,尤其是gpu跑数据
        x=torch.tensor(inputData[start:end],dtype=torch.float,requires_grad=True).to(device)
        y=torch.tensor(labels[start:end],dtype=torch.float,requires_grad=True).to(device)
        pred = model(x)
        #计算损失
        loss_v=loss(pred,y)
        #优化梯度清零
        opti.zero_grad()
        #反向传播
        loss_v.backward(retain_graph=True)
        #执行优化器
        opti.step()
        #将损失返回,计算时需要传递到cpu计算,否则有报错
        batch_loss.append(loss_v.to('cpu').data.numpy())
    return batch_loss
def testMode(batchSize,opti,inputData,model,labels,loss,device):
    batch_loss = []
    batch_pred = []
    model.eval()   
    for start in range(0,len(inputData),batchSize):
        end = min(len(inputData),start+batchSize)
        x=torch.tensor(inputData[start:end],dtype=torch.float,requires_grad=True).to(device)
        y=torch.tensor(labels[start:end],dtype=torch.float,requires_grad=True).to(device)
        pred = model(x)
        loss_v=loss(pred,y)
        opti.zero_grad()
        loss_v.backward(retain_graph=True)
        opti.step()
        batch_loss.append(loss_v.to('cpu').data.numpy())
        batch_pred.extend(pred.squeeze().cpu().detach().numpy())
    return batch_loss,batch_pred

5.训练

cost = nn.MSELoss(reduction='mean')
inputsize=input_features.shape[1]
model_temp=TempModel(inputsize,1)
device='cuda:0'
model_temp = model_temp.to(device)
optimizer=optim.Adam(model_temp.parameters(),lr=0.003)
epoch=1000
batchsize=16
losses_t = []
for i in range(epoch):
    batchloss=trainMode(batchsize,optimizer,input_features,model_temp,labels,cost,device)
    if i%100==0:
        losses_t.append(np.mean(batchloss))
        print(i,np.mean(batchloss))
_,pred_t=testMode(batchsize,optimizer,input_features,model_temp,labels,cost,device)


6、绘图

r=np.array(pred_t)
r.reshape(-1)
r.shape
pre_data =pd.DataFrame(data = {'date': dates, 'prediction': r}) 
# 真实值
plt.plot(true_data['date'], true_data['actual'], 'b-', label = 'actual')

# 预测值
plt.plot(pre_data['date'], pre_data['prediction'], 'ro', label = 'prediction')
plt.xticks(rotation = '60'); 
plt.legend()

# 图名
plt.xlabel('Date'); plt.ylabel('Maximum Temperature (F)'); plt.title('Actual and Predicted Values');

在这里插入图片描述

总结

1、dataframe和array的转换
2、数组多维的时候,append 会在数组里放数组或者元素,维度会加1;extend是追加,维度不变
3、onehot编码
4、gpu运行和cpu运行需要注意,指定到对应的device,数据和模型都要到一个环境里
6、整个代码没有考虑测试集验证集训练集

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值