一、实验目的
1.掌握利用随机森林算法构建分类器模型的方法,并且了解如何准确评估随机森林模型分类器的性能,包括准确率、精确度、召回率和F1分数等指标的计算和解读,以便对模型的表现进行全面评价;
2.深入学习随机森林模型的参数调整方法,包括调整决策树数量、最大深度和最大特征数量等参数,以提高模型的预测准确性和泛化能力,通过系统地调整这些参数,并观察模型性能的变化总结相关规律,更好地理解参数对模型性能的影响;
3.通过实现基于LSTM循环神经网络的玉米产量估计,回顾LSTM模型相关概念的同时,探索深度学习在农业领域中的应用,了解如何利用神经网络模型进行产量预测并进行结果可视化,深入理解其在农业生产中的潜在应用价值。
二、实验内容
1.随机森林制作柑橘分布图
1.1 实验代码
import xlrd
import numpy as np
import pandas as pd
import sklearn.utils as su
import csv,os
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from math import sqrt
from sklearn.model_selection import train_test_split#导入训练数据
df = pd.read_csv(r'C:\Users\付嘉琪\Desktop\农业大数据\实验二\实验二\随机森林\训练样本.csv', encoding='gbk')
df['name'] = df['name'].astype(str).map({'是': 1, '不是': 2})#划分训练集、测试集,验证集
y_train = df.pop('name')
X_train =df
X_train, X_test, y_train, y_test = train_test_split(X_train, y_train, test_size=0.2, random_state=0, shuffle=True)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=0, shuffle=True)print('Train data shape:', X_train.shape)
print('Train labels shape:', y_train.shape)# 创建随机森林分类器
rfc = RandomForestClassifier()
rfc = rfc.fit(X_train, y_train)# 计算验证集和测试集的准确率
result = rfc.score(X_val, y_val)
result1 = rfc.score(X_test, y_test)
print('X_val accuracy: %f, X_test accuracy: %f' % (result, result1))# 输出特征重要性排序
importances = rfc.feature_importances_
indices = np.argsort(importances)[::-1]
print('Feature ranking:')
for f in range(min(20, X_train.shape[1])):print("%2d) %-*s %f" % (f + 1, 30, X_train.columns[indices[f]], importances[indices[f]]))# 输出混淆矩阵
from sklearn.metrics import classification_report,confusion_matrix
y_true = y_test
y_pred = rfc.predict(X_test)
cmat = confusion_matrix(y_true, y_pred)
print('Confusion matrix:')
print(cmat)
print('Classification report:')
print(classification_report(y_true, y_pred))# 读取研究区数据
df1 = pd.read_csv(r'C:\Users\付嘉琪\Desktop\农业大数据\实验二\实验二\随机森林\研究区数据.csv', encoding='gbk')# 提取特征
y = df1.pop('id')
longitude = df1.pop('X')
latitude = df1.pop('Y')
x = df1# 预测并保存结果
res = rfc.predict(x)
result_df = pd.DataFrame({'id': y, 'longitude': longitude, 'latitude': latitude, 'Res': res})
result_df.to_csv(r'C:\Users\付嘉琪\Desktop\农业大数据\实验二\实验二\随机森林/res.csv', encoding='gbk', index=False)
1.2 实验结果
通过观察代码输出的验证集(X_val)和测试集(X_test)上的准确率与Classification report(分类报告),我们可以定量化的评估分类器的性能,其中准确率是最为直观直接的指标,而分类报告则是一个更详细的性能评估指标,具体包括四个部分:
- Precision(精确度): 在所有被分类器预测为正例的样本中,实际为正例的比例;
- Recall(召回率): 在所有实际为正例的样本中,被分类器正确预测为正例的比例;
- F1-score(F1 分数): 精确度和召回率的加权平均值,用于综合评估模型的性能, F1 分数的范围在0到1之内,其中1表示最佳性能;
- Support(支持度): 表示每个类别在测试集中的样本数量。
本次实验中验证集与测试集的准确率分别为0.933150与0.931868,分类报告如下图所示,因此可以得出本模型在测试集上表现良好,并且具有较高的准确率、精确度、召回率和F1分数:
最终得到柑橘分布图如下图所示:
1.3 参数调整
通过观察上述代码可知,在此调用的随机森林中我们使用的是默认参数设置,虽然模型的精度已经较高且符合我们的需要,但我们仍可以通过调节模型的相关参数以进一步的提高模型的精度,首先让我们了解随机森林模型相关参数的具体概念与基本调参方法如下所示:
- n_estimators:随机森林中决策树的数量,每颗决策树都是一个分类器,它们各自独立地对输入样本进行分类,通过增加树的数量,我们可以提高模型的稳定性和准确性,但同时也会增加训练和预测的时间;
- max_depth:随机森林中决策树的最大深度,影响了每个决策树的复杂度和泛化能力,设置较大的最大深度可能导致过拟合,而设置较小的最大深度可能导致欠拟合;
- max_features:每个决策树在拟合时的最大特征数量,控制了每棵树的随机性,较小的值会增加树之间的差异性,从而增加随机性,而较大的值会减少随机性;
random_state:随机数种子,设置一个固定的随机数种子可以使得结果可重复,即多次运行相同的代码得到相同的结果,如果不设置随机数种子,则每次运行时都会得到不同的结果。
(1)决策树数量
根据老师建议,在此次实验中我们主要调试的参数为:n_estimators,max_features与max_depth,首先我们针对n_estimators参数修改代码如下所示,保持其它参数值不变,从10到200,以5为间隔依次递增参数值并得到验证集和测试集的准确率:
将上述得到的结果存储在Excel中,并在Excel中绘图结果如下所示,综合验证集与测试集的准确率可得,决策树数量为65时,模型精度最高,但同样可以观察得到的时:该曲线图似乎并不符合我们的变化幅度明显且较大的预期,推测原因为此数据集的随机森林模型精度已较高,因此改变相关参数时模型精度的变化较小:
(2)最大深度
在上述结果的基础上,我们再次修改代码使n_estimators参数固定为65,其它参数保持不变,而使max_depth参数的值从10开始以5为间隔,依次递增至100并得到验证集和测试集的准确率:
将上述得到的结果存储在Excel中,并在Excel中绘图结果如下所示,综合验证集与测试集的准确率可得,最大深度为10时,模型精度最高,同时我们可以观察到当最大深度大于30时,模型精度不再发生变化,这说明此时的模型已经过拟合:
(3)最大特征数量
在上述两个参数不断调整得到的结果的基础上,我们将n_estimators设置为65,max_depth设置为10且保持不变,而max_features设置为从10开始以5为间隔依次递增至100并得到验证集和测试集的准确率:
将上述得到的结果存储在Excel中,并在Excel中绘图结果如下所示,综合验证集与测试集的准确率可得,当最大特征数量为25时,模型精度最高,但与决策树数量参数的变化相同,最大特征数量的变化对模型精度的影响并不大,所得到的模型精度均在0.92以上:
1.4 实验结论
在上述的实验内容中我们利用随机森林方法构建了一个柑橘分布的分类器模型,得到的结果精度较高大于0.9并以此绘制得到了柑橘分布图。但实验的重点内容为1.3的参数调整部分。
在这一内容中,我们针对决策树数量、最大深度、最大特征数量三个参数进行值的调整,并绘制得到了折线图以观察模型精度的变化,得到结论如下:决策树数量为65时,模型精度最高;最大深度为10时,模型精度最高;当最大特征数量为25时,模型精度最高,但在此次实验中,各个参数对模型精度的影响不大,得到的所有模型精度均在0.9以上,推测原因为输入数据的质量非常高,特征与标签之间存在明显的关联性,使得模型十分容易学习到数据的模式和规律。
2. 基于LSTM循环神经网络的玉米产量估计
2.1 实验代码
由于基于LSTM循环神经网络的玉米产量估计的代码过长,且老师提供的实验指导中已有完整详细的代码,因此在此不再赘述,仅将代码的基本思路总结如下所示,我认为其中最为关键与核心的部分为模型的构建:
2.2 实验结果
运行代码后,将会循环输出训练过程中,不同训练轮数的损失情况和模型在测试集上的均方根误差,以及在验证集上的训练损失和均方根误差,除此之外,还会输出模型在验证集上的预测值和真实值之间的差值,以及保存误差至一个CSV文件中,将该文件导入ArcGIS与相应栅格数据连接,我们可以得到玉米产量估计偏差的专题地图如下图所示:
2.3 参数调整
本部分内容此次实验由于时间关系未能深入进行自己的代码编写与动手操作,主要通过学习老师提供的代码详解文档与网络资料了解相关内容:
(1)迭代次数
在此次实验的代码中EPOCH表示迭代次数,迭代次数表示训练模型所需要的更新参数的次数。一般而言,迭代次数越多,模型的训练效果越好。但是,迭代次数过多会导致模型过拟合,并且会增加模型训练的时间,在此次实验中我首先使用的Pycharm运行迭代次数为100的LSTM模型速度已经非常之慢,后改为使用VS运行模型速度才有所改善,可见迭代次数并非越大越好。
(2)损失函数
损失函数(loss function)就是用来度量模型的预测值f(x)与真实值Y的差异程度的运算函数。在此次实验的代码中,损失函数靠nn.MSELoss函数进行调整,其含有reduce、size_average两个参数(后者已被官方废弃),表示维度要不要缩减,以及怎么缩减,reduce参数共含有三种类型:
None | 表示不进行维度缩减,即保持损失函数的维度不变; |
Mean | 表示对损失函数的输出进行均值计算,即将输出的所有元素相加后除以元素的总个数,得到平均损失值; |
Sum | 表示对损失函数的输出进行求和,即将输出的所有元素相加得到总损失值。 |
(3)优化器
优化器是用于更新模型参数的算法,常见的优化器包括随机梯度下降(SGD)、Adam、RMSprop等,其目的是通过调整模型参数来最小化损失函数,不同的优化器有着不同的方法原理与考虑(如时间、精度等),在此次实验中我们使用的是Adam优化器,并通过以下代码进行了初始化:
optimizer = torch.optim.Adam(rnn.parameters(), lr=LR)
三、实验心得
1. 在此次实验中我们首先学习回顾了随机森林算法的基本原理和相关代码的实现方法。随机森林作为一种机器学习方法,通过构建多个决策树来进行分类或回归任务,对于处理高维数据和大量样本具有较高的准确性和稳健性,并且通过调整参数和评估模型性能,我更加深入地理解了随机森林模型的调参方法和性能评估指标;
2. 其次通过实现基于LSTM的玉米产量估计估计任务,我们进一步学习了深度学习的LSTM算法在农业领域的应用,LSTM作为一种常用于处理序列数据的循环神经网络,适用于时间序列或具有时间关联性的数据分析任务。在实验中,我们学习了解了如何利用代码构建LSTM模型,并通过结果可视化了解模型了在验证集和测试集上的表现,虽然后续因时间不足未能进行模型参数的调整,但通过实验指导书与网络资料的学习依然收获颇丰;
3.在此次实验中我认为收获最大的点就在于得到了真正的脚踏实地的机器学习相关概念的练习,在以往的理论课学习中,其实我们已经接触过了随机森林、LSTM算法的相关概念,但那时我们的学习不过停留于纸面,对于许多概念的理解也相当的片面不够准确,然而即使希望可以有深入的学习了解也苦于不知如何入手,但幸好本实验课提供给了我们这样一个机会,教我们从编程环境的配置开始,到具体的代码编写,结合相关论文与实例数据,脚踏实地的一点点开始学习,虽然刚开始过程有一点困难,但最终得到结果的喜悦与掌握新的技能、攻克新的难题的快乐同样是无与伦比的。