r语言课程设计Word格式文档下载.docx
《r语言课程设计Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《r语言课程设计Word格式文档下载.docx(13页珍藏版)》请在冰豆网上搜索。
另外,用该判别方法建立的判别方差可以直接用手工计算的方法进行新样品的判别,这在许多时候是非常方便的。
(二).BP神经网络
BP神经网络是1986年由Rumelhart和McCelland为首的科学家小组提出,是一种按误差逆传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一。
BP网络能学习和存贮大量的输入-输出模式映射关系,而无需事前揭示描述这种映射关系的数学方程。
它的学习规则是使用梯度下降法,通过反向传播来不断调整网络的权值和阈值,使网络的误差平方和最小。
BP神经网络模型拓扑结构包括输入层、隐藏层和输出层。
BP神经网络,由信息的正向传播和误差的反向传播两个过程组成。
输入层各神经元负责接收来自外界的输入信息,并传递给中间层各神经元;
中间层是内部信息处理层,负责信息变换,根据信息变化能力的需求,中间层可以设计为单隐层或者多隐层结构;
最后一个隐层传递到输出层各神经元的信息,经进一步处理后,完成一次学习的正向传播处理过程,由输出层向外界输出信息处理结果。
当实际输出与期望输出不符时,进入误差的反向传播阶段。
误差通过输出层,按误差梯度下降的方式修正各层权值,向隐层、输入层逐层反传。
周而复始的信息正向传播和误差反向传播过程,是各层权值不断调整的过程,也是神经网络学习训练的过程,此过程一直进行到网络输出的误差减少到可以接受的程度,或者预先设定的学习次数为止。
本文运用的是单层前馈网络模型,一般称为三层前馈网或三层感知器,即:
输入层、中间层(也称隐层)和输出层。
如下图所示它的特点是:
各层神经元仅与相邻层神经元之间相互全连接,同层内神经元之间无连接,各层神经元之间无反馈连接,构成具有层次结构的前馈型神经网络系统。
四.数据处理与分析
数据来自于1980~1988年6~10月安徽庐江的月平均温度、月最低温度、月日照时间、月降雨量以及水稻的月平均虫害程度,且数据都是经过标准化之后的。
(一).数据预处理
首先,将降雨量的最后一个数据中的空格消除,再把原始数据的前两列合并为一列,并保存为CSV(逗号分隔)格式,之后用函数将数据读入到R的内存中。
>
shuju<
-read.csv('
chongqing.csv'
)
为了方便之后的操作,对各列进行命名,其中date代表年度时间,x1~x4分别代表平均气温、最低气温、日照时间、降雨量,y代表虫害程度。
同时给出各类别下的样本量个数。
由于本文不采用时间序列预测的方法进行分析,故第一列的数据使用不到,最终确定使用的数据集为剔除原数据框第一列之后的数据框。
从原始数据中可知样本量为54,不是很多,如果再进行分块,可能由于样本量的限制无法得到最好的结果,因此,下文中的训练集和测试集均选用原始数据来充当。
names(shuju)<
-c('
date'
'
x1'
x2'
x3'
x4'
y'
)
x<
-shuju[,2:
6]
table(y)
y
1234
356211
将数据框X中的变量链接到内存中,降低后续代码的复杂程度,提高代码的可读性。
attach(x)
(二).判别分析
1.模型建立
安装并加载软件包MASS。
install.packages(“MASS”)
library(MASS)
将训练集中的y变量作为判别变量,其他剩余的变量作为特征变量,运用lda()函数来进行费希尔判别下的线性判别。
lda<
-lda(y~.,data=x)#线性判别
lda
Call:
lda(y~.,data=x)
Priorprobabilitiesofgroups:
1234
0.648148150.111111110.037037040.20370370
Groupmeans:
x1x2x3x4
1-0.03336857-0.007231429-0.0008800-0.2286971
20.769233330.7488000000.1302167-0.2696333
30.377650000.4366000000.6406500-0.4973500
40.565145450.6081909090.2076455-0.2936727
Coefficientsoflineardiscriminants:
LD1LD2LD3
x11.1966105-1.8868126-3.1952390
x20.97735881.18404273.3471367
x30.24311362.1779657-0.2219837
x4-0.2754396-0.37820630.4283132
Proportionoftrace:
LD1LD2LD3
0.87670.11970.0036
输出结果的第二项为此次过程中各类别所使用的先验概率,其实就是训练集中判别变量各水平下的数量占总样本量的比例。
第三项为各变量在每一类别中的均值,从中可以看出x1~x3在各类别下有较明显的差别,相反x4在各类别下的差别很小,也就说明降雨量对虫害程度的影响不是很显著。
第四项给出线性判别式的参数矩阵。
第五项给出各线性判别式分别的贡献比例。
plot(lda)
从上图可以看到,在3个线性判别式下1~4这4个类别的分布情况,不同类别样本已经用相应数字标出。
可能受样本量的限制,图中并不能看出很明显的分布情况。
下面用上述模型对测试集进行预测,并给出测试集中y变量的预测结果与实际类别的混淆矩阵。
pred<
-predict(lda,x[,1:
4])
pred$class
[1]11441111441111111111141111441111441111421
[42]1114411111111
Levels:
1234
table(y,pred$class)
y1234
132003
22103
31001
46005
上述混淆矩阵的行表示实际的类别,列表示预测判定的类别。
在54个测试样本中,实际属于第1类的有35个,而由判定结果,在35个样本中,有32个判定正确,有3个被错判为第4类;
第2类只有1个判定正确,有2个被错判为第1类,3个被错判为第4类;
第3类没有一个判定正确;
第4类有5个判定正确,6个被错判为第1类。
从矩阵中只能看出每一类别的预测结果与实际类别的差距,只是一个直观的判断,并不能由此看出该模型的优劣,所以我们需要构造一个数量指标(误判概率=矩阵非对角线之和/样本总量),通过这个指标来确定模型的优劣。
e_lda<
-sum(as.numeric(pred$class)!
=y)/nrow(x)
e_lda
[1]0.2962963
通过计算,上述模型的误判率为29.6%,可以看出该模型的预测效果并不好,因此需要进一步的改进。
2.模型优化
从上文中我们知道,使用Fisher判别要求各组变量的均值有显著性差异,从上述结果已经知道降雨量在各类别下的均值差异性很小,所以我们可以考虑将其剔除,通过计算各变量在各类别下均值的方差,来作为剔除某一变量的理论依据。
var=>
c(var(lda$means[,1]),var(lda$means[,2]),
+var(lda$means[,3]),var(lda$means[,4]))
var
[1]0.116789090.107833140.077188360.01433243
从结果来看,x4在各类别下均值的方差相对其他三者而言差别较大,因此考虑将其剔除,然后重新进行线性判别分析。
lda2<
-lda(y~x1+x2+x3,data=x)#线性判别
pred2<
-predict(lda2,x[,1:
3])
table(y,pred2$class)
133002
23003
45006
e_lda2<
-sum(as.numeric(pred2$class)!
e_lda2
[1]0.2777778
从误判率的角度来看,剔除x4之后的模型误判率为27.8%,相对原来的模型有所降低;
但从混淆矩阵来看,对于第2类和第3类的误判率为100%,这相对原来的模型更难让人接受。
两个模型各有好坏,但整体而言,都不是很好。
3.模型应用
如果运用上述两个模型对未来进行预测的话,只需将所需要的变量存放至一个新的数据框,需要注意的是,数据框中各变量的名字需要和建立模型时使用的数据框中各变量的名称一样,即平均气温、最低气温、日照时间、降雨量分别用x1~x4来表示。
然后直接运用模型来给出预测结果。
(三).BP神经网络
安装并加载软件包nnet。
install.packages(“nnet”)
library(nnet)
首先在建模之前,先介绍软件包nnet中的一个函数:
class.ind()。
该函数可以通过类别变量的因子变量来生成一个类指标矩阵。
下面通过一个简单的例子来更清楚地表明该函数的功能。
z=c(1,2,3)#定义一个水平数为3的向量
class.ind(z)
123
[1,]100
[2,]010
[3,]001
从输出结果可以看到,该函数主要是将向量变成一个矩阵,其中每行代表一个样本。
只是将样本的类别用0和1来表示,即如果是该类,则在该类别名下用1表示,而其余的类别名下面用0表示。
将数据框的前4列作为自变量数据,class.ind(y)作为类别变量数据,设置隐藏层节点个数为4,模型的最大迭代次数为1000次,用来防止模型的死循环。
之后用核心函数nnet()来建立神经网络模型。
model=nnet(x[1:
4],class.ind(y),data=x,size=4,
+decay=5e-4,maxit=1000)#神经网络
p=x[,1:
4]#测试集定为原始数据
pred3=predict(model,p)#对测试集进行预测
head(pred3)#预测结果的部分显示
[1,]0.99999415950.00000000001.474405e-044.459695e-05
[2,]0.94903083780.01131001011.454422e-059.221503e-03
[3,]0.00496943100.02406255892.918010e-048.973849e-01
[4,]0.00025403970.00019419714.926029e-049.982468e-01
[5,]0.86827598540.00000000005.810529e-031.975710e-01
[6,]0.99998319910.00000000001.631513e-042.351911e-04
上述结果的每一行代表测试集中的每一个样本,其判别准则为:
每一行中最大值所在的列名即为该样本所属的类别。
pnew=max.col(pred3)#确定测试集中每一个样本所属类别
table(y,pnew)#给出混淆矩阵
pnew
133101
22400
30011
410010
e_e<
-sum(pnew!
=y)/nrow(x)#计算误判率
e_e
[1]0.1111111
从结果可以看出,该模型的误判率为11.1%,相比较判别分析大幅度降低,说明该模型对测试集的预测效果很好。
names(model)#模型中包含的所有输出结果
[1]"
n"
"
nunits"
nconn"
conn"
nsunits"
decay"
[7]"
entropy"
softmax"
censored"
value"
wts"
convergence"
[13]"
fitted.values"
residuals"
call"
其中:
value表示迭代最终值。
wts表示模型在迭代过程中所寻找到的最优权重值,其取值为系统随机生成,即每次建模所使用的迭代初始值都是不相同的。
由此可以看出神经网络模型的灵活性很高。
convergence表示在模型建立的迭代过程中,迭代次数是否达到最大迭代次数。
如果结果为1,则表明达到最大迭代次数;
如果结果为0,则表明没有达到最大迭代次数。
如果结果没有达到最大迭代次数,说明该模型可以被采纳,否则,就要增大参数maxit的设定值,重新建模。
model$convergence
[1]0
该模型的convergence取值为0,说明该模型可以被采纳。
虽然上述模型的各项指标可能都满足要求,但是,隐藏层中节点的个数和迭代次数都是人为设定的,随着两者数值的改变建立的模型也不尽相同,所以我们需要寻找两者的最优值,使其对应的模型最优。
下面通过编写函数来实现这一目的。
(1).寻找隐藏层节点个数最优值
f=function(n){
+e=matrix(0,2,n,dimnames=list(c('
误判概率'
+'
迭代终值'
),c(1:
n)))#定义一矩阵,用于存放结果
+for(iin1:
n){
+model=nnet(x[1:
4],class.ind(y),data=x,size=i,
+decay=5e-4,maxit=1000)
+pred=predict(model,p)
+pnew=max.col(pred)
+table(y,pnew)
+e_e<
+e[1,i]=e_e
+e[2,i]=model$value
+}
+print(e)
+print(plot(as.numeric(e[1,]),type='
l'
col='
red'
+main='
误判率变化曲线'
xlab='
隐藏层结点个数'
ylab
+='
误判率'
))
f(10)#将n取为10
输出结果:
12345误判概率0.25925930.20370370.18518520.07407410.0370371
迭代终值20.70701215.36959815.7799998.23342796.5062853
678910
误判概率0.01851850.03703710.0000000.03703710.0185185
迭代终值4.49751954.66498322.7332964.39859893.2961255
结合矩阵以及折线图,可以看出当n=8的时候,误判率最小,同时迭代最终值也达到最小,说明当n=8即隐藏层节点个数为8时,模型的拟合效果最好,对测试集做出的预测效果也最好。
(2).寻找迭代次数最优值
ff=function(n){
+e=0
+for(iin1:
+model=nnet(x[,1:
4],class.ind(x$y),data=x,
+size=8,decay=5e-4,maxit=i)
+e[i]=sum(max.col(predict(model,x[,1:
4]))!
=
+x$y)/nrow(x)
+}
+print(plot(1:
n,e,'
ylab='
训练周
+期'
blue'
ylim=c(min(e),max(e))))
}
ff(1000)
从模型对测试集的误判率随训练周期的变化曲线可以看出,误判概率随着训练周期的增大先是急速下降,后趋于平稳。
但是也有出现反向增长的现象,可能与训练集和测试集的选取有关。
不过,从图中整体的变化趋势可以看出曲线的拐点在maxit=200处,所以maxit的最优值可能为200。
3.建模重建
取size=8,maxit=200,重新建立神经网络模型,得到如下结果:
model1=nnet(x[,1:
4],class.ind(y),data=x,size=8,
+decay=5e-4,maxit=200)
pred4=predict(model1,p)
pnew1=max.col(pred4)
e_e1<
-sum(pnew1!
e_e1
[1]0.05555556
model1$convergence
[1]1
误判概率为5.6%,较上次模型有所下降,但是模型的迭代次数达到了最大迭代次数,因此该模型可能还不是最优的。
取size=8,maxit=1000,重新建立神经网络模型,得到如下结果:
model2=nnet(x[1:
+decay=5e-4,maxit=1000)
pred5=predict(model2,p)
pnew2=max.col(pred5)
table(y,pnew2)
Pnew2
135000
20600
30020
400011
e_e2<
-sum(pnew2!
e_e2
model2$convergence
从输出结果来看,该模型的误判率为0,迭代次数也没有达到最大值,说明该模型可以被采纳,在样本量如此小的条件下,建立的模型能有如此高的预测精度,确实不得不让人佩服神经网络模型的强大。
然而,由于训练集样本和测试集样本完全相同,所以两者的特征也完全一样,可能由于这个原因,才会使得测试集的预测结果与实际值重合度如此高;
况且由于神经网络模型太过灵活,当训练周期很长的时候,建立出来的神经网络模型可能会记住训练集的几乎所有信息,而测试集又和训练集相同,所以,模型的误判率才会如此低。
尽管在此次建立神经网络模型的过程中出现了这么多问题,但并不能够掩盖神经网络模型的强大之处,所以,神经网络模型还是值得我们深入学习和深入研究的。
4.模型应用
当运用此模型进行预测时,需要注意的是,首先必须对用来预测的自变量进行标准化,以消除数量级和量纲的影响。
然后直接带入模型给出预测结果。
五.总结与建议
通过此次课程设计,使我更加扎实的掌握了有关如何使用R语言进行统计分析方面的知识,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。
实践出真知,通过亲自动手制作,让我根绝掌握的知识不再是纸上谈兵。
回顾这次课程设计,学到了很多很多的东西,不仅巩固了以前所学过的知识,而且通过翻阅书籍也学到了很多在课堂上所没有学到过的知识,例如:
BP神经网络模型是如何建立的。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正提高自己的实际动手能力和独立思考的能力。
通过课程设计的训练,让我进一步学习和掌握了对R语言编程艺术的更深理解,在对函数进行设计和编写的过程中,让我明白了在编程之前,要有明确的目标和整体的设计思想,另外某些具体的细节内容也是相当的重要,我相信这些宝贵的编程思想和从中摸索到的经验,对我以后的编程会有很大的帮助,所以,我会珍惜这次所有的收获。
通过不懈的努力,课程设计虽然完成,但由于本人能力有限,论文之中肯定还存在着很多的不足之处,这也督促着我更好的去学习,努力让自己学到的知识有所升华。
最后,要对给过我帮助的所有同学和各位指导老师表示忠心的感谢!
任务的完成,少不了老师的耐心指导和同学的热心帮助,再次谢谢大家!