李宏毅机器学习作业1:预测PM2.5(含训练数据)

李宏毅机器学习作业1:预测PM2.5(含训练数据
1.要求
给定训练集train.csv,要求根据前9个⼩时的空⽓监测情况预测第10个⼩时的PM2.5含量。
训练集介绍:
CSV⽂件,包含台湾丰原地区240天的⽓象观测资料(取每个⽉前20天的数据做训练集,12⽉X20天=240天,每⽉后10天数据⽤于测试)
每天的监测时间点为0时,1时…到23时,共24个时间节点;
每天的检测指标包括CO、NO、PM2.5、PM10等⽓体浓度,是否降⾬、刮风等⽓象信息,共计18项;
数据集地址:/s/1o2Yx42dZBJZFZqCa5y3WzQ,提取码:qgtm。
2. 思路分析
前注:下⽂中提到的“数据帧”并⾮指pandas库中的数据结构DataFrame,⽽是指⼀个⼆维的数据包。
游梁式抽油机
2.1 数据预处理辟谷丹
训练集中数据排列形式符合⼈类观察数据的习惯,但并不能直接拿来喂给模型进⾏训练,因此需要对数据进⾏预处理。
浏览数据可知,数据中存在⼀定量的空数据NR,且多存在于RAINFALL⼀项。对于空数据,常规的处理⽅法⽆⾮就是删除法和补全法两种。查阅资料后发现,RAINFALL表⽰当天对应时间点是否降⾬,有降⾬值为1,⽆降⾬值为NR,类似于布尔变量。因此可以采⽤补全法处理空数据:将空数据NR全部补为0即可。
根据作业要求可知,需要⽤到连续9个时间点的⽓象观测数据,来预测第10个时间点的PM2.5含量。针对每⼀天来说,其包含的信息维度为(18,24)(18项指标,24个时间节点)。可以将0到8时的数据截取出来,形成⼀个维度为(18,9)的数据帧,作为训练数据,将9时的
PM2.5含量取出来,作为该训练数据对应的label;同理可取1到9时的数据作为训练⽤的数据帧,10时的PM2.5含量作为label…以此分割,可将每天的信息分割为15个shape为(18,9)的数据帧和与之对应的15个label。
训练集中共包含240天的数据,因此共可获得240X15=3600个数据帧和与之对应的3600个label
# 数据预处理
def  dataProcess (df ):
x_list , y_list = [], []
# df 替换指定元素,将空数据填充为0
df = df .replace (['NR'], [0.0])
array = np .array (df ).astype (float )
#astype 就是转换numpy 数组的数据类型为float 型
# 将数据集拆分为多个数据帧
for  i in  range (0, 4320, 18):
for  j in  range (24 - 9):
mat = array [i :i + 18, j :j + 9]
label = array [i + 9, j + 9]  # 第10⾏是PM2.5
x_list .append (mat )
y_list .append (label )
x = np .array (x_list )
y = np .array (y_list )
return  x , y , array
x .shape :(3600,18,9)
y .shape :(3600,)
2.2 模型建⽴
2.2.1 回归模型
采⽤最普通的线性回归模型,并没有⽤上训练集中所有的数据,只⽤到了每个数据帧样本中的9个PM2.5含量值:
为对应数据帧中第i个PM2.5含量,为其对应的权重值,为偏置项,为该数据帧样本的预测结果。
2.2.2 损失函数
⽤预测值与label之间的平均欧式距离来衡量预测的准确程度,并充当损失函数(这⾥的损失指的是平均损失;乘1/2是为了在后续求梯度过程中保证梯度项系数为1,⽅便计算):
为第n个label,为第n个数据帧的预测结果,为参加训练的数据帧样本个数。
为了防⽌过拟合,加⼊正则项:
y =w x +i =0∑8i i b
x i w i b y Loss =hocl −y 2 num 1n =0∑num −1
(y ^n n )2y ^n y n num Loss =regula riza tion w 21i =0∑8
i 2Loss =Loss +la bel β⋅Loss =regula riza tion −y +βw 21[mum 1n =0∑num −1(y ^n n )2i =0∑8
i 2]
为正则项系数。
2.2.3 梯度更新
梯度计算:需明确此时的⽬标是使Loss最⼩,⽽可优化的参数为权重w和偏置值b,因此需要求Loss在w上的偏微分和Loss在b上的偏微分。
计算出梯度后,通过梯度下降法实现参数更新。
为权重w更新时的学习率,为偏置b更新时的学习率。
2.2.3 学习率更新
为了在不影响模型效果的前提下提⾼学习速度,可以对学习率进⾏实时更新:即让学习率的值在学习初期较⼤,之后逐渐减⼩。这⾥采⽤⽐较经典的adagrad算法来更新学习率。
为更新后的学习率,为更新前的学习率。为在此之前所有梯度平⽅和的⼆次根。
β=+=−w x −b ⋅−x +β⋅w ∂w i
∂Loss ∂y ∂Loss labe l ∂w i ∂y ∂w i ∂Loss re gularization mum 1∑n =0num −1(y ^n ∑i =08i i )(i )∑i =08
i =+=−w x −b ⋅(−1)∂b ∂Loss ∂y ∂Loss labe l ∂b ∂y ∂b ∂Loss re gularization mum 1∑n =0num −1(y ^n ∑i =08i i )w =newi w −i η,b =w ∂w i ∂Loss new b −ηb ∂b
∂Loss
ηw ηb η=n grad ∑i =1n −1i
2ηn −1ηn ηn −1grad ∑i =1n −1i 2
# 更新参数,训练模型
def train(x_train, y_train, epoch):
bias =0# 偏置值初始化
weights = np.ones(9)# 权重初始化
learning_rate =1# 初始学习率
reg_rate =0.001# 正则项系数
bg2_sum =0# ⽤于存放偏置值的梯度平⽅和
wg2_sum = np.zeros(9)# ⽤于存放权重的梯度平⽅和
for i in range(epoch):
b_g =0
w_g = np.zeros(9)
装备偏移
# 在所有数据上计算Loss_label的梯度
#Loss在w上的偏微分和Loss在b上的偏微分
#参加训练的数据帧样本个数num采⽤了3200,0~3200是训练集,3200~3600是验证集for j in range(3200):
b_g +=(y_train[j]- weights.dot(x_train[j,9,:])- bias)*(-1)
for k in range(9):
w_g[k]+=(y_train[j]- weights.dot(x_train[j,9,:])- bias)*(-x_train[j,9, k]) # 求平均,除以num
b_g /=3200
w_g /=3200
#  加上Loss_regularization在w上的梯度
for m in range(9):
w_g[m]+= reg_rate * weights[m]
# adagrad,相当于grad**2的加权和,adagrad算法来更新学习率
bg2_sum += b_g **2
wg2_sum += w_g **2
# 更新权重和偏置
bias -= learning_rate / bg2_sum **0.5* b_g
weights -= learning_rate / wg2_sum **0.5* w_g
# 每训练200轮,输出⼀次在训练集上的损失
if i %200==0:
loss =0
for j in range(3200):
loss +=(y_train[j]- weights.dot(x_train[j,9,:])- bias)**2
调料盒print('after {} epochs, the loss on train data is:'.format(i), loss /3200)
return weights, bias
3.完整代码与结果分析
cd架3.1 testPM2.5.py
import pandas as pd
import numpy as np
# 数据预处理
def dataProcess(df):
x_list, y_list =[],[]
# df替换指定元素,将空数据填充为0
df = df.replace(['NR'],[0.0])
array = np.array(df).astype(float)
#astype就是转换numpy数组的数据类型为float型
# 将数据集拆分为多个数据帧
for i in range(0,4320,18):
for j in range(24-9):
led显示屏单元板mat = array[i:i +18, j:j +9]
label = array[i +9, j +9]# 第10⾏是PM2.5
x_list.append(mat)
y_list.append(label)
y_list.append(label)
x = np.array(x_list)
y = np.array(y_list)
return x, y, array
# 更新参数,训练模型
def train(x_train, y_train, epoch):
bias =0# 偏置值初始化
weights = np.ones(9)# 权重初始化
learning_rate =1# 初始学习率
reg_rate =0.001# 正则项系数
bg2_sum =0# ⽤于存放偏置值的梯度平⽅和
wg2_sum = np.zeros(9)# ⽤于存放权重的梯度平⽅和
for i in range(epoch):
b_g =0
w_g = np.zeros(9)
# 在所有数据上计算Loss_label的梯度
#Loss在w上的偏微分和Loss在b上的偏微分
#参加训练的数据帧样本个数num采⽤了3200,0~3200是训练集,3200~3600是验证集for j in range(3200):
b_g +=(y_train[j]- weights.dot(x_train[j,9,:])- bias)*(-1)
for k in range(9):
w_g[k]+=(y_train[j]- weights.dot(x_train[j,9,:])- bias)*(-x_train[j,9, k]) # 求平均,除以num
b_g /=3200
w_g /=3200
#  加上Loss_regularization在w上的梯度
for m in range(9):
w_g[m]+= reg_rate * weights[m]
# adagrad,相当于grad**2的加权和,adagrad算法来更新学习率
bg2_sum += b_g **2
wg2_sum += w_g **2
# 更新权重和偏置
bias -= learning_rate / bg2_sum **0.5* b_g
weights -= learning_rate / wg2_sum **0.5* w_g
# 每训练200轮,输出⼀次在训练集上的损失
if i %200==0:
loss =0
for j in range(3200):
loss +=(y_train[j]- weights.dot(x_train[j,9,:])- bias)**2
print('after {} epochs, the loss on train data is:'.format(i), loss /3200)
return weights, bias
# 验证模型效果
#验证集3400~3600
def validate(x_val, y_val, weights, bias):
loss =0
for i in range(400):
loss +=(y_val[i]- weights.dot(x_val[i,9,:])- bias)**2
return loss /400
def main():
# 从csv中读取有⽤的信息
# 由于⼤家获取数据集的渠道不同,所以数可据集的编码格式能不同
# 若读取失败,可在参数栏中加⼊encoding = 'gb18030'
df = pd.read_csv('train.csv', usecols=range(3,27))
x, y, _ = dataProcess(df)

本文发布于:2024-09-22 23:18:44,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/100073.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   训练   梯度
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议