我是靠谱客的博主 精明小土豆,最近开发中收集的这篇文章主要介绍深度学习代码部分(1): 用线性回归+adagrad预测PM2.5的值1、数据处理6、 进一步优化模型,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

预测PM 2.5

1、数据处理

每一天有24小时,每一天对应的特征有18个,每个月取前20天作为训练集数据,根据要求,每九个小时形成一个data,一个月有2024=480 hours,所以一共可以取到471个data,故x_train的行数为样本个数,即47112个,列数为18个特征9 hours。
target值取每九个小时的第十个小时,所以target的矩阵应为(471
12,1)

将每个月20天每小时的数据作为每一列,行为特征数量。

month_data={}
for month in range(12):
    sample=np.empty([18,480])
    for day in range(20):
        sample[:,day*24:(day+1)*24]=raw_data[18*(20*month+day):18*(20*month+day+1),:]
    month_data[month]=sample
  • 建立一个字典
  • 遍历12个月
  • 建立一个空的数组,行为18个特征,列为20 days * 24 hours
  • 遍历每一天,对于第一天的遍历,sample中的所有行,以及前24列数据,为原始数据中,第一个月第一天,即原始数据中的第一行至第十八行(十八个特征)的所有24小时的数据。放入sample
  • 遍历20 天, 至此,20天每一个小时对应的特征都在每一列上。
  • 遍历20天结束,将该array放入字典作为value,key为月份

每九个小时形成一个data,data有189列,有24(480-9)行

x=np.empty([12*471,18*9],dtype=float)
y=np.empty([12*471,1],dtype=float)
for month in range(12):
    for day in range(20):
        for hour in range(24):
            if day==19 and hour>14:
                continue
            #对于每个sample的month里,每九个小时一取,取18行所有的feature
            x[month*471+day*24+hour,:]=month_data[month][:,day*24+hour:day*24+hour+9].reshape(1,-1)
            #取每个sample的month里,第10个特征位pm2.5,每九个小时的下一个小时为target值
            y[month * 471 + day * 24 + hour, 0] = month_data[month][9, day * 24 + hour+ 9]

  • 建立一个空的x矩阵
  • 建立一个空的y矩阵,数组类型为float
  • 遍历12个月
  • 遍历20天
  • 遍历24小时
  • 如果到了第20天霍小时大于15,即已经按每九个小时取完的话,就跳过当前循环
  • 对于第一个月,第一天,第一个9个小时的数据,x中第一行所有列的值,为上一个字典中第一个月,取18行所有的特征,取前九个小时的数据,做reshape(1,-1),变成一行的值。下一个第九个小时,行+1,列取第2个小时到地十个小时的数据作为第二组第九个小时的数据。每一列的数量为18*9。
  • 对于y的值,取特征在第十个的pm2.5的值,每九个小时以第十个小时的数据为target. 即y每一行,每一列的数据都是对应字典该月下,第十行的,第十个小时(每次hour内递增延1,每次day递增延后24)

正则化

将x中的每个值减去列平均值再除列的标准差

训练集和验证机的划分

训练集0.8,验证集0.2

2、training

因为常数项的存在还要再x前面加上一个12*471,1的矩阵。

  • 学习率设定为1,
  • 迭代次数为1000
  • 为防止计算梯度下降时,有的值为0,加入eps项

做梯度下降

adagrad=np.zeros([dim,1])
eps=0.000000001
for t in range(iter_time):
    loss=np.sqrt(np.sum(np.power(np.dot(x,w)-y,2))/471/12) #rmse
    if t%100==0:
        print(str(t)+":"+str(loss))
    gradient=2*np.dot(x.transpose(),np.dot(x,w)-y)
    adagrad+=gradient**2
    w=w-learning_rate*gradient/np.sqrt(adagrad+eps)
  • 随机初始化一个w矩阵
  • 一共有18*9+1个weight
  • 遍历迭代次数1000
  • 规定损失函数为rmse,
  • np.power(): 做平方处理
  • 将每个特征的预测值和实际值的平方做加和再除以所有的样本数量471*12
  • 计算梯度
  • 根据梯度下降更新w,使用adagrad,对学习率随着梯度下降做改变
  • 每个特征都有一个w

3、testing

对于测试集x的处理与训练集上差不多,只不过测试集的x上本身的列的数量就是9个小时,只需要把18个features平铺就好了。还需要对训练集加常数项,做归一化

4、预测

拿做完梯度下降的w点乘训练集的x即可

5、完整代码:

import sys
import pandas as pd
import numpy as np
#from google.colab import drive
import math
from sklearn.metrics import mean_squared_error


data=pd.read_csv("./train.csv",encoding="big5")
'''preprocessing'''
#print(data.head())

'''从第四列开始取,取24天的数据'''
data=data.iloc[:,3:]

'''将rainfall栏位补0,即显示NR的都为0,使用pandas处理'''
data[data=="NR"]=0
raw_data=data.to_numpy()

'''将原本4320*18的资料按照每个月份组成12个18features*480hours'''
'''将每一个月每个时间作为一列数据,每一个月就有20*24=480hours的数据'''
month_data={}
for month in range(12):
    sample=np.empty([18,480])
    for day in range(20):
        sample[:,day*24:(day+1)*24]=raw_data[18*(20*month+day):18*(20*month+day+1),:]
    month_data[month]=sample

'''每个月有480hours,每九个小时形成一个data,每个月有471个data。故总资料数位471*12'''
'''每笔data有9hours*18的feature'''
'''对应的target则有471*12个'''
x=np.empty([12*471,18*9],dtype=float)
y=np.empty([12*471,1],dtype=float)
for month in range(12):
    for day in range(20):
        for hour in range(24):
            if day==19 and hour>14:
                continue
            #对于每个sample的month里,每九个小时一取,取18行所有的feature
            x[month*471+day*24+hour,:]=month_data[month][:,day*24+hour:day*24+hour+9].reshape(1,-1)
            #取每个sample的month里,第10个特征位pm2.5,每九个小时的下一个小时为target值
            y[month * 471 + day * 24 + hour, 0] = month_data[month][9, day * 24 + hour+ 9]

print(x.shape)
print(y.shape)

'''Normalize'''
mean_x=np.mean(x,axis=0) #18*9 axis=0,跨行
std_x=np.std(x,axis=0) #18*9
for i in range(len(x)): #12*471
    for j in range(len(x[0])): #18*9
        if std_x[j]!=0:
            x[i][j]=(x[i][j]-mean_x[j])/std_x[j]

'''训练集和验证集的划分'''
x_train_set = x[: math.floor(len(x) * 0.8), :]
y_train_set = y[: math.floor(len(y) * 0.8), :]
x_validation = x[math.floor(len(x) * 0.8): , :]
y_validation = y[math.floor(len(y) * 0.8): , :]

'''Training'''
'''因为常数项的存在,所以dim要多加一栏;eps项是避免adagrad的分母为0而加的'''
dim=18*9+1
w=np.zeros([dim,1])
x=np.concatenate((np.ones([12*471,1]),x),axis=1).astype(float)
learning_rate=100
iter_time=1000
adagrad=np.zeros([dim,1])
eps=0.000000001
for t in range(iter_time):
    loss=np.sqrt(np.sum(np.power(np.dot(x,w)-y,2))/471/12) #rmse

    if t%100==0:
        print(str(t)+":"+str(loss))
    gradient=2*np.dot(x.transpose(),np.dot(x,w)-y)
    adagrad+=gradient**2
    w=w-learning_rate*gradient/np.sqrt(adagrad+eps)
np.save("weight.npy",w)
print(w.shape)


'''testing'''
testdata=pd.read_csv("test.csv",header=None,encoding="big5")
testdata=testdata.iloc[:,2:]
testdata[testdata=="NR"]=0
testdata=testdata.to_numpy()
test_x=np.empty([240,18*9],dtype=float)
for i in range(240):
    test_x[i,:]=testdata[18*i:18*(i+1),:].reshape(1,-1)

for i in range(len(test_x)):
    for j in range(len(test_x[0])):
        if std_x[j]!=0:
            test_x[i][j]=(test_x[i][j]-mean_x[j])/std_x[j]
test_x=np.concatenate((np.ones([240,1]),test_x),axis=1).astype(float)
print(test_x)

'''prediction'''
ans_y=np.dot(test_x,w)
print(ans_y)


import csv
with open('submit.csv', mode='w', newline='') as submit_file:
    csv_writer = csv.writer(submit_file)
    header = ['id', 'value']
    print(header)
    csv_writer.writerow(header)
    for i in range(240):
        row = ['id_' + str(i), ans_y[i][0]]
        csv_writer.writerow(row)
        print(row)

6、 进一步优化模型

  • 1、学习率可以调小,代码中采用100
  • 2、迭代次数可以更多,1000次迭代的loss值为7,但可能会过拟合
  • 3、为防止过拟合,可以使用正则项
  • 4、可以使用adam作为梯度下降的算法
  • 5、可以根据查看weight,将weight较低的feature删除
  • 6、可以对比训练集和测试集,将分布不均匀的数据删除

最后

以上就是精明小土豆为你收集整理的深度学习代码部分(1): 用线性回归+adagrad预测PM2.5的值1、数据处理6、 进一步优化模型的全部内容,希望文章能够帮你解决深度学习代码部分(1): 用线性回归+adagrad预测PM2.5的值1、数据处理6、 进一步优化模型所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(34)

评论列表共有 0 条评论

立即
投稿
返回
顶部