我是靠谱客的博主 精明小土豆,最近开发中收集的这篇文章主要介绍深度学习代码部分(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的矩阵应为(47112,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、 进一步优化模型所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复