【机器学习】李宏毅-预测PM2.5

news2024/12/27 11:17:39

李宏毅-预测PM2.5


1 实验目的

巩固课堂所学知识,学习使用Linear Regression中梯度下降预测模型,并将所学运用至实践,根据从空气质量监测网下载的观测数据,使用Linear Regression 预测出空气污染指数(即PM2.5) 的数值。


2 实验要求

•不可以使用numpy.linalg.lstsq

•可以使用pandas库读取csv文件数据信息(其他库亦可)

•必须使用线性回归,方法必须使用梯度下降法

•可以使用多种高阶的梯度下降技术(如Adam、Adagrad等)

•程序运行时间不得大于3分钟


3 实验环境

3.1 硬件环境

笔记本电脑、Intel Core i5

3.2 软件环境

windows10操作系统、Python 3.8 64-bit、Visual Studio Code


4 实验原理

4.1 z-score标准化

σ = 1   N ∑ i = 1 N ( x i − μ ) 2 z i = x i − μ σ \sigma=\sqrt{\frac{1}{\mathrm{~N}} \sum_{i=1}^{\mathrm{N}}\left(\mathrm{x}_{\mathrm{i}}-\mu\right)^{2}}\\ \mathrm{z}_{\mathrm{i}}=\frac{\mathrm{x}_{\mathrm{i}}-\mu}{\sigma} σ= N1i=1N(xiμ)2 zi=σxiμ

4.2 损失函数

L = 1 n ∑ i = 0 n − 1 ( y n − ∑ j = 0 k w j x j − b ) 2 L=\frac{1}{n} \sum_{i=0}^{n-1}\left(y^{n}-\sum_{j=0}^{k} w_{j} x_{j}-b\right)^{2} L=n1i=0n1(ynj=0kwjxjb)2

4.3 偏微分

∂ L ∂ w j = 1 n ∑ i n − 1 ( y i − ∑ j = 0 k w j x j − b ) ( − x j ) ∂ L ∂ b = 1 n ∑ i = 0 n − 1 ( y i − ∑ j = 0 k w j x j − b ) ∗ ( − 1 ) \frac{\partial \mathrm{L}}{\partial \mathrm{w}_{j}}=\frac{1}{n} \sum_{i}^{n-1}\left(y^{i}-\sum_{j=0}^{k} w_{j} x_{j}-b\right)\left(-x_{j}\right)\\ \frac{\partial \mathrm{L}}{\partial \mathrm{b}}=\frac{1}{n} \sum_{i=0}^{n-1}\left(y^{i}-\sum_{j=0}^{k} w_{j} x_{j}-b\right)^{*}(-1) wjL=n1in1(yij=0kwjxjb)(xj)bL=n1i=0n1(yij=0kwjxjb)(1)

4.4 参数迭代

w newi  = w i − η w ∂ L ∂ w i b new  = b − η b ∂ L ∂ b i f ( d L d w ∣ w = w i = = 0 )  then stop;  \begin{array}{l} w_{\text {newi }}=w_{i}-\eta_{w} \frac{\partial L}{\partial w_{i}} \\ b_{\text {new }}=b-\eta_{b} \frac{\partial L}{\partial b} \end{array}\\ \begin{array}{l}{ if }\left(\left.\frac{d L}{d w}\right|_{w=w^{i}}==0\right) \text { then stop; }\end{array} wnewi =wiηwwiLbnew =bηbbLif(dwdL w=wi==0) then stop; 

4.5 Adagrad梯度更新优化算法

η n = η ∑ i = 1 n − 1 g i 2 \eta_{n}=\frac{\eta}{\sqrt{\sum_{i=1}^{n-1} g^{\mathrm{i}^{2}}}} ηn=i=1n1gi2 η


5 数据处理

5.1 读取训练数据.csv文件

这一步我们使用pandas库提供的函数提取训练数据,并对数据作初步处理,将一些无用指标剔除,以及将字符串数据转换为整数,方便之后的数学运算。

#读取数据csv文件,data类型为矩阵
data = pd.read_csv("train.csv")
#数据切片,去掉前三列无用且不方便数据处理的信息(日期、站点和测项)
data = data.iloc[:, 3:]
#为了数学运算方便,将FAINFULL为NR的值转换为0
data=data.replace(["NR",[0]])
#将data转换为numpy矩阵,规模为12(months)*20(days)*18行×24列
arr_data = data.to_numpy()

最后还需要将数据转为numpy库的矩阵类型,方便之后进一步的处理和更快的数学运算。

打印切片提取出的所有数据构成的array,确定处理无误:

在这里插入图片描述

5.2 整理训练数据

由于.csv中的数据是按照每天分散开的,题目要求给出连续9小时的数据预测第10小时的PM2.5数据,为了增大训练集的规模,拥有更多的训练数据,达到更好的训练效果,我们把同一个月的每一天数据连接起来:

#创建字典以月份为索引将同一个月的0-24小时数据连接起来
#大大增加了训练集的规模,模型可以更好地达到训练效果
month_data = {}
for month in range(12):
    #创建一个空的矩阵存放特征值
    #20天0-24时的数据共20*24行,18个特征共18列
    sample = np.empty([20*24,18])
    for day in range(20):
        #使用transpose()转置数据矩阵
        sample[(day*24):(day+1)*24,:] = arr_data[18 * (month*20 + day) : 18 * (month*20 + day + 1), :].transpose()
    #将整理好的数据集对应到字典中的月份索引
    month_data[month] = sample

5.3 划分模型输入和输出

矩阵x作为输入,在不同模型下有不同的规模(以模型A为例),矩阵y作为输出,即第10小时的PM2.5数值:

#创建一个空的矩阵用于存放训练集的输入,每连续9个小时为一组训练数据
#每个月有471组10小时训练数据,共12*471行
#每行是一组9个小时训练数据,1个小时有18个特征,矩阵共9*18列
#矩阵的元素类型为float
x = np.empty([12*471,9],dtype=float)
#训练集的输出矩阵,同样共12*471行,但不包含特征值,只有1列第10个小时的PM2.5的数据
#矩阵的元素类型为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
            #对训练集x和y进行赋值,reshape将数据转变为一行
            x[month*471 + day*24 + hour, :] = month_data[month][day*24 + hour : day * 24 + hour + 9,9].reshape(1, -1)  
            y[month*471 + day*24 + hour, 0] = month_data[month][day*24 + hour + 9, 9]

5.4 z-score标准化

Z-Score通过(x-μ)/σ将两组或多组数据转化为无单位的Z-Score分值,使得数据标准统一化,提高了数据可比性,削弱了数据解释性:

#每一个特征的平均值
mean_x = np.mean(x, axis=0)
#每一个特征的标准差
std_x = np.std(x, axis=0)
#z-score标准化
for i in range(len(x)):
    for j in range(len(x[0])):
        if std_x[j] != 0:
            x[i][j] = (x[i][j] - mean_x[j]) / std_x[j]

5.5 读取测试数据.csv文件

训练数据和测试数据文件均为.csv且格式类似,方法类比读取训练数据即可:

#读取数据csv文件,data类型为矩阵
data = pd.read_csv("test.csv")
#数据切片
data = data.iloc[:, 2:]
#为了数学运算方便,将FAINFULL为NR的值转换为0
data=data.replace(["NR",[0]])
#将data转换为numpy矩阵
arr_data = data.to_numpy()

5.6 整理测试数据

sample = np.empty([9*240,18])
for id in range(240):
    #使用transpose()转置数据矩阵
    sample[(id*9):(id+1)*9,:] = arr_data[18 * id : 18 * (id + 1), :].transpose()
#输入矩阵
x = np.empty([240,9],dtype=float)
#输出矩阵
y = np.empty([240,1],dtype=float)
#赋值
for i in range(240):
            #reshape将数据转变为一行
            x[i,:] = sample[(i*9):(i+1)*9,9].reshape(1, -1)
#每一个特征的平均值
mean_x = np.mean(x, axis=0)
#每一个特征的标准差
std_x = np.std(x, axis=0)
#z-score标准化
for i in range(len(x)):
    for j in range(len(x[0])):
        if std_x[j] != 0:
            x[i][j] = (x[i][j] - mean_x[j]) / std_x[j]

5.7 计算预测值并输出

y矩阵就是我们的预测值,但是实验要求了输出.csv文件的格式要求,所以我们要为其增加表头并标明id的顺序:

#求出预测值
y=np.dot(x,w)+b
#整理输出内容
headers=['id','value']
data=[]
for i in range(240):
    row=[]
    row.append('id_'+str(i))
    if y[i][0]>=0:
        row.append(y[i][0])
    else:
        row.append(0)
    data.append(row)
#写入
with open ('model_B_output.csv','w',encoding='utf-8',newline='') as fp:
    #写
    writer =csv.writer(fp)
    #设置第一行标题头
    writer.writerow(headers)
    #将数据写入
    writer.writerows(data)

6 模型设计

6.1 模型A:单独考虑PM2.5一个特征

为了对比不同学习率下的拟合过程以及后续作图比较,我们定义一个learning_rate列表设置不同的学习率,为了更好地比较,共设置6个不同的学习率:

#学习率
learning_rate = [0.001,0.005,0.01,0.05,0.1,0.5,1]
#图表颜色
color_list=['red','green','blue','yellow','black','pink','purple']

另外我们需要提前定义好迭代次数和#adagrad初始系数,以及数据集的大小方便平均数的计算,加快程序运行时间:

#迭代次数
iter_time = 10000
#adagrad系数
eps = 0.0000001
#记下x的长度
x_len=len(x)

每一个学习率对应一次迭代过程,每一次新的迭代都需要初始化w和b,以及记录迭代次数的列表iter和记录损失函数值随迭代次数变化的列表loss_list。

迭代过程中会计算损失函数的微分,并采用梯度下降法修改b和w的值:

for k in range(len(learning_rate)):
    #记录开始时间
    start=time.time()
    #列表用于记录损失函数值随迭代次数变化过程
    iter=[]
    loss_list=[]
    #初始化权重w和偏移b  
    w = np.empty([9,1])
    for i in range(len(w)):
        w[i]=[1]
    b = 0
    #初始化adagrad参数
    w_adagrad = 0
    b_adagrad = 0
    #梯度下降法迭代
    for i in range(iter_time):
        #这里是loss function
        loss = np.sum(np.power(np.dot(x,w)+b-y,2))/(x_len)
        #每10次迭代存一次值
        if i % 10 == 0:
            iter.append(i)
            loss_list.append(loss)
        #求w梯度
        w_gradient= 2*np.dot(x.transpose(), np.dot(x,w)+b-y)/x_len
        w_adagrad += np.mean(w_gradient) ** 2
        #求b梯度
        b_gradient= 2*np.sum(np.dot(x,w)+b-y)/x_len
        b_adagrad += b_gradient ** 2
        #更新w
        w = w - learning_rate[k] * w_gradient / np.sqrt(w_adagrad + eps)
        #更新b
        b = b - learning_rate[k] * b_gradient / np.sqrt(b_adagrad + eps)
    print("when learning rate = ",learning_rate[k],", loss = ",loss)
    print("when learning rate = ",learning_rate[k],", time used = ",time.time()-start," s")
    plt.plot(iter, loss_list, c=color_list[k],label='learning_rate = '+str(learning_rate[k]))

最后我们用图表来展示整个训练过程,loss随迭代次数的增加呈现出的变化过程:

#图表展示
plt.xlabel('iteration_times')
plt.ylabel('Loss')
plt.title('Loss-iteration_times')
plt.legend(loc='best')
plt.show()

6.2 模型B:考虑对PM2.5影响较大的七个特征

模型B不仅考虑pm2.5本身这个特征,额外考虑了几个对PM2.5影响较大的特征:NO2、NOx、O3、PM10、降雨情况、RH。

因此模型的输入规模变化为12×471行/9×7列,数据提取时需要提取更多数据。

另外存储权重w的数组规模也随之变化为9×7行/1列。

其他的代码与模型A大同小异,具体详见附件中的源代码。

6.3 模型C:考虑数据集提供的所有十八个特征

模型C在模型B的基础上进一步发挥,综合全面运用所给的所有数据,考虑提供的所有特征值。

因此模型的输入规模变化为12×471行/9×18列,数据提取时需要提取更多数据。

另外存储权重w的数组规模也随之变化为9×18行/1列。

其他的代码与模型A大同小异,具体详见附件中的源代码。


7 实验结果

7.1 模型A:单独考虑PM2.5一个特征

7.1.1 loss值和运行时间

在这里插入图片描述

7.1.2 不同学习率下loss随迭代次数的变化情况

在这里插入图片描述

7.2 模型B:考虑对PM2.5影响较大的七个特征

7.2.1 loss值和运行时间

在这里插入图片描述

7.2.2 不同学习率下loss随迭代次数的变化情况

在这里插入图片描述

7.3 模型C:考虑数据集提供的所有十八个特征

7.3.1 loss值和运行时间

在这里插入图片描述

7.3.2 不同学习率下loss随迭代次数的变化情况

7.4 测试集的预测结果

使用三个模型分别预测了240笔testing data中的PM2.5值,见附件中的output.csv文件。


8 分析评估

8.1 不同模型对学习过程的影响

首先,比较三个模型的程序运行时间,模型A<模型B<模型C,原因显然是考虑的因素越多使用的资源就越多即运行时间越长,其中模型C的运行时间几乎是模型A和模型B的三倍之多。

其次比较三个模型在训练集上的表现,模型B和模型C比模型A略好,loss可以降得更低,但是差距不大,计算需要的时间稍长一点。

另外比较三个模型在测试集上的表现,模型B和模型C相比模型A同样更加出色,参见附件中的output文件,模型B和模型C在测试集上的输出更加合理,相比模型A的loss更小。

以上两个指标说明合理的测试模型能让机器学习的效果事半功倍,适当考虑一些对预测特征相关的因素可以让模型的拟合效果更好。

综上,个人认为模型B的性价比最高,因为考虑的特征更少,运行时间更短,并且在训练集和测试集上的表现都和C几乎一样,相比之下C消耗的资源显然是更多的。

8.2 不同学习率对学习过程的影响

一共测试了6种不同学习率下loss随迭代次数增加的变化过程,三种模型在图像上描绘出来的结果主要不同在于loss值的大小,但是整个变化过程大同小异。

和预想的一致,更高的学习率意味着更快的收敛,学习率越高收敛越快,学习率越低收敛越慢,而且如果学习率过小甚至无法在规定的迭代次数内呈现出收敛趋势。

另外,收敛线对应loss值的大小也不一样,学习率高的模型收敛时loss更小,学习率低的模型收敛时loss更大。

分析原因是由于使用了Adagrad算法,如果初始设置的学习率过小,随着迭代次数增加,学习率越来越小,很有可能在没有到达极值点的时候就处于停滞不前的状态。


9 References

[1] python.org

[2] kaggle.com

[3] 百度百科

[4] CSDN专业开发者技术社区

[5] 十分钟入门 Pandas | Pandas 中文 (pypandas.cn)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/138497.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法】超详细哈夫曼编码JAVA解释

综合实验报告格式 综合实验题目 一、人员和分工 LenckCuak 二、问题描述和基本要求 1、 用哈夫曼编码设计一个压缩软件; 2、 能对输入的任何类型的文件进行哈夫曼编码,产生编码后的文件——压缩文件; 3、 能对输入的压缩文件进行译码&…

【机器学习】李宏毅-食物图像分类器

李宏毅-食物图像分类器1 实验目的 掌握使用Pytorch的使用方法: Pytorch的安装以及环境搭建Pytorch处理数据Pytorch计算梯度以及搭建神经网络Pytorch训练模型 并使用Pytorch来训练CNN模型,实作一个食物的图像分类器。 2 实验要求 可以使用tensorflow或…

print()函数的使用

一、print()函数共三种类型的使用方法二、代码展示

Excel求解运输问题——以福斯特公司问题为例

目录 1.1 问题 福斯特问题例 1.2 数学模型 1.3 excel求解 第一步:建立一个工作表 第二步:求解器求解 1.1 问题 运输问题通常出现在计划货物配送机从供给地区到达需求地区之间的服务中,一般供给地区货物数量有限,需求地区货物…

时间序列分析原理

一、定义 时间序列,是指将某种现象某一个统计指标在不同时间上的各个数值,按时间先后顺序排列而形成的序列 生活中各领域各行业有很多时间序列的数据,销售额,顾客数,访问量,股价,油价&#xff…

k8s 部署canal admin及server单机服务

目录 1. 前言 2. 部署canal-admin 2.1 数据库初始化 2.2 canal-admin k8s yaml部署文件 3. 部署canal-server单机 1. 前言 canal官方文档:https://github.com/alibaba/canal/wiki 主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。…

一文读懂深度学习中文本处理的4种方式

一、序言文本处理方式是深度学习领域中自然语言处理的基础,即把文本转变成计算机识别的语言过程。转变之后才能用算法做后续的文本分析和理解。所以有必要了解文本处理的几种方式,做到对不同的场景采用不同的处理方式。常见的文本处理方式有独热编码(one…

OSI参考模型与TCP/IP模型比较

TCP/IP模型 — TCP/IP协议簇 TCP/IP分为两种体系结构,一种是分为四层网络接口层、网络层、传输层和应用层;另外一种是分为五层物理层、数据链路层、网络层、传输层和应用层。这两种体系结构都对。 TCP/IP四层模型 — TCP/IP标准模型 TCP/IP五层模型 — T…

hive数据仓库搭建

一、虚拟机安装CentOS7并配置共享文件夹 二、CentOS 7 上hadoop伪分布式搭建全流程完整教程 三、本机使用python操作hdfs搭建及常见问题 四、mapreduce搭建 五、mapper-reducer编程搭建 六、hive数据仓库安装 hive数据仓库搭建一、hive数据仓库安装1.1下载hive安装包1.2修改配置…

2022年亚太杯APMCM数学建模大赛C题全球是否变暖求解全过程文档及程序

2022年亚太杯APMCM数学建模大赛 C题 全球是否变暖 为方便各位阅览及了解掌握亚太杯的写作技巧,这里非技术使用中文,公式部分由于翻译过程繁琐使用英文来撰写此文章. 原题再现: 加拿大的49.6C创造了地球北纬50以上地区的气温新纪录&#xf…

SpringBoot的字符画(banner.txt)

好多小伙伴最近问我如何在启动项目的时候,在控制台打印如下的图案logo 其实很简单,Springboot提供了很方便的操作,在resource目录先新建一个banner.txt 然后将我们想要的图案拼接即可,如下图: 配置完成后正常启动项目…

TorchServe 详解:5 步将模型部署到生产环境

内容导读 TorchServe 自 2020 年 4 月推出至今,经历了 2 年多的发展,变得愈发成熟和稳定,本文将对 TorchServe 进行全面介绍。 TorchServe 是 PyTorch 中将模型部署到生产环境的首选解决方案。它是一个性能良好且可扩展的工具,用 …

【Java】多线程详解

目录 一、线程简介 进程(Process )与 线程(Thread) 二、线程创建 1、线程Thread 1.1. 步骤 1.2 应用 1.3 案例:下载图片 2、实现Runnable接口 2.1 步骤 2.2 应用 3.小结 3. 实现Callable接口(了解…

利用Github账号实现(多个)个人网站

创建仓库 命名一定要是<username>.github.io这种形式username就是自己github账号的用户名。因为我已经有这个仓库&#xff0c;所以这里的报错可以忽略。 往仓库放入静态html文件 命名为index.html&#xff0c;随便放点内容。 在设置里面开启github page 这里可以选…

verilog学习笔记- 2)时序约束文件

目录 为什么要创建时序约束文件&#xff1f; 时序&#xff1a; 创建时序约束文件&#xff1a; 为什么要创建时序约束文件&#xff1f; 对于一些简单的工程时序的要求并不是特别的严格&#xff0c;添不添加时序约束文件影响不大。但是对于一些复杂的工程&#xff0c;涉及到高…

【SpringBoot应用篇】SpringBoot 启动扩展点/常用接口

【SpringBoot应用篇】SpringBoot 启动扩展点/常用接口SpringBoot常用的接口ApplicationContextInitializerBeanDefinitionRegistryPostProcessorBeanFactoryPostProcessorInstantiationAwareBeanPostProcessorSmartInstantiationAwareBeanPostProcessorBeanFactoryAwareApplica…

Dom 重点核心

关于dom操作&#xff0c;主要针对元素的操作。 主要有创建&#xff0c;增&#xff0c;删&#xff0c;改&#xff0c;查&#xff0c;属性操作&#xff0c;事件操作。 一、创建 1.document.write 2.innerHTML 3.createElement 二、增 1.appendChild&#xff08;在后面添加&am…

【iOS】块与大中枢派发

文章目录[TOC](文章目录)前言理解“块”这一概念块的基础知识块的内部结构全局块&#xff0c;栈块&#xff0c;堆块为常用的块类型创建typedef用handler块降低代码分散程度用块引用其所属对象时不要出现保留环多用派发系列&#xff0c;少用同步锁多用GCD&#xff0c;少用perfor…

Linux/ARM下QT MQTT库的编译安装

&#x1f482; 个人主页:风间琉璃&#x1f91f; 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦目录 一、 Linux 环境下编译安装 二、 ARM Linux 环境下安装 一、 Linux 环境下…

破解分布式光伏运维难题,光伏+屋面数字化监控融合是关键

2022年5月&#xff0c;在东南地区某城市一幢写字楼上&#xff0c;技术人员们正不辞辛苦爬上数十米高的墙面&#xff0c;对写字楼的屋面和墙面进行勘察。随后&#xff0c;他们准备赶在台风季来临之前完成该写字楼的建筑光伏一体化项目安装与部署。 这是森特士兴集团股份有限公司…