下面以费希尔的鸢尾花数据为例,演示利用nnet软件包提供的函数进行基于人工神经网络的数据挖掘方法。我们也已经知道,nnet()函数在建立支持单隐藏层前馈神经网络模型的时候有两种建立方式,即根据既定公式建立模型和根据所给的数据建立模型。接下来我们将具体演示基于上述数据函数的两种建模过程。
根据函数的第一种使用格式,在针对上述数据建模时,应该先确定我们所建立模型所使用的数据,然后再确定所建立模型的响应变量和自变量。来看下面这段示例代码。注意,这里使用的是iris3数据集,这与第14章中所用到的鸢尾花数据是一致的,但数据格式略有不同。
> samp <- c(sample(1:50,25), sample(51:100,25), sample(101:150,25))
> ird <- data.frame(rbind(iris3[,,1], iris3[,,2], iris3[,,3]),
+ species = factor(c(rep("s",50), rep("c", 50), rep("v", 50))))
> ir.nn1 <- nnet(species ~ ., data = ird, subset = samp, size = 2,
+ rang = 0.1, decay = 5e-4, maxit = 200)
正如15.3.1节中所讲的,在使用第1种格式建立模型时,如果使用数据中的全部自变量作为模型自变量时,我们可以简要地使用形如“species ~ .”这样的写法,其中的“.”代替全部的自变量。
根据函数的第2种使用格式,在针对上述数据建立模型时,首先应该将因变量和自变量分别提取出。自变量通常用一个矩阵表示,而对于因变量则应该进行相应的预处理。具体而言,就是利用函数class.ind()将因变量处理为类指标矩阵。来看下面这段示例代码。
> targets <- class.ind( c(rep("s", 50), rep("c", 50), rep("v", 50)))
> ir <- rbind(iris3[,,1],iris3[,,2],iris3[,,3])
> ir.nn2 <- nnet(ir[samp,], targets[samp,], size = 2, rang = 0.1,
+ decay = 5e-4, maxit = 200)
在使用第2种格式建立模型时,不需要特别强调所建立模型的形式,函数会自动将所有输入到x矩阵中的数据作为建立模型所需要的自变量。
在上述过程中,两种模型的相关参数都是一样的,两个模型的权重衰减速度最小值都为5e-4,最大迭代次数都为200次,隐藏层的节点数都为4个。需要说明的是,由于初始值赋值的随机性,达到收敛状态时所需耗用的迭代次数并不会每次都一样。事实上,每次构建的模型也不会完全都一致,这是很正常的。
下面通过 summary()函数来检视一下所建模型的相关信息。在输出结果的第1行可以看到模型的总体类型,该模型总共有3层,输入层有4个节点,隐藏层有2个节点,输出层有3个节点,该模型的权重总共有19个。
> summary(ir.nn1)
a 4-2-3 network with 19 weights
options were - softmax modelling decay=5e-04
b->h1 i1->h1 i2->h1 i3->h1 i4->h1
13.01 4.40 5.69 -8.00 -10.19
b->h2 i1->h2 i2->h2 i3->h2 i4->h2
0.32 0.71 1.71 -2.94 -1.30
b->o1 h1->o1 h2->o1
-3.67 11.19 -8.58
b->o2 h1->o2 h2->o2
-4.07 2.37 8.72
b->o3 h1->o3 h2->o3
7.74 -13.56 -0.13
在输出结果的第2部分显示的是模型中的相关参数的设定,在该模型的建立过程中,我们只设定了相应的模型权重衰减最小值,所以这里显示出了模型衰减最小值为5e-4。
接下来的第3部分是模型的具体构建结果,其中的i1、i2、i3和i4分别代表输入层的4个节点。hl和h2代表的是隐藏层的两个节点,而o1、o2和o3则分别代表输出层的3个节点。此外,b就是模型中的常数项。第3部分中的数字则代表的是每一个节点向下一个节点的输入值的权重值。
在利用样本数据建立模型之后,接下来就可以利用模型来进行相应的预测和判别。在利用nnet()函数建立的模型进行预测时,我们将用到R软件自带的函数predict()对模型进行预测。但是在使用 predict()函数时,我们应该首先确认将要用于预测模型的类别。这是因为建立神经网络模型时有两种不同的建立方式。所以利用 predict()函数进行预测时,对于两种模型也会存在两种不同的预测结果,必须分清楚将要进行预测的模型是哪一类模型。
针对第1种建模方式所建立的模型,可采用下面的方式来进行预测判别。在进行数据预测时,应注意必须保证用于预测的自变量向量的个数同模型建立时使用的自变量向量个数一致,否则将无法预测结果。而且在使用 predict()函数进行预测时,不用刻意去调整预测结果类型。原数据集中标记为c、s和v的3种鸢尾花的观测样本各有50条,在建立模型时,分别从中各抽取25条共计75条,并用这样一个子集来作为训练数据集。下面的代码则使用剩余的75条数据来作为测试数据集。
> table(ird$species[-samp], predict(ir.nn1, ird[-samp,], type = "class"))
c s v
c 25 0 0
s 0 25 0
v 1 0 24
通过上述预测结果的展示,我们可以看出所有标记为c和s的鸢尾花都被正确地划分了。有1个本来应该被标记为v的鸢尾花被错误地预测成了c类别。总的来说,模型的预测效果还是较为理想的。需要说明的是,训练集和测试集都是随机采样的,所以也不可能每次都得到跟上述预测结果相一致的矩阵,这是很正常的。
针对第2种建模方式所建立的模型,可采用下面的方式来进行预测判别。从输出结果来看,所有标记为s和v的鸢尾花都被正确地划分了。有2个本来应该被标记为c的鸢尾花被错误地预测成了v类别。总的来说,模型的预测效果还是较为理想的。
> pre.matrix <- function(true, pred) {
+ name = c("c","s","v")
+ true <- name[max.col(true)]
+ cres <- name[max.col(pred)]
+ table(true, cres)
+ }
> pre.matrix(targets[-samp,], predict(ir.nn2, ir[-samp,]))
cres
true c s v
c 23 0 2
s 0 25 0
v 0 0 25
读者评论