【R的机器学习】模型性能提升探索:R的其他神经网络包-neuralnet

来源:互联网 发布:小非农数据公布网站 编辑:程序博客网 时间:2024/05/19 22:02

上一节简单说明了神经网络,这里对R中进行神经网络算法的其他函数做下具体说明。

之前说到RSNNS包的神经网络,但是这个函数比较复杂,这里介绍下neuralnet包的神经网络。

这个包中的神经网络建模有个缺陷,只能对数值型的变量进行回归。也就是默认是无法进行分类变量的建模的,比如我们的iris数据集:

head(iris)  Sepal.Length Sepal.Width Petal.Length Petal.Width Species1          5.1         3.5          1.4         0.2  setosa2          4.9         3.0          1.4         0.2  setosa3          4.7         3.2          1.3         0.2  setosa4          4.6         3.1          1.5         0.2  setosa5          5.0         3.6          1.4         0.2  setosa6          5.4         3.9          1.7         0.4  setosa

最后一列:Species分成了三类,如果是一个,比如花期,然后这一列都是数值型变量,可以直接应用neuralnet,可是这里是因子型,需要手工进行转换成哑变量,或者简单理解,就是从分类数据新建几个列,按照T/F的形式进行结果储存。

这里需要用到一个哑变量转化的函数,这个函数在另一个神经网络包里(囧),首先载入两个包:

library(neuralnet)library(nnet)

nnet里面的class.ind函数就是转化变量的工具,转化前:

head(iris_train$Species)[1] versicolor setosa     setosa     versicolor setosa    [6] virginica Levels: setosa versicolor virginica

转化后:

new<-class.ind(as.factor(iris_train$Species)) head(new)     setosa versicolor virginica[1,]      0          1         0[2,]      1          0         0[3,]      1          0         0[4,]      0          1         0[5,]      1          0         0[6,]      0          0         1

看到从一列变成了三列,而且只在列中是这一列的显示为1,其他都是0。这里就是一个典型的哑变量转换。

然后对这三个变量为结果建模:

iris_train1<-cbind(iris_train,new)m_neuralnet<-neuralnet(setosa+versicolor+virginica~Sepal.Length+Sepal.Width+Petal.Length+Petal.Width,                       data=iris_train1,hidden=1,                       linear.output = FALSE,                       act.fct = "logistic")

其中的hidden就是层数,默认是1,看下图形:

plot(m_neuralnet)

这里写图片描述

这四个变量的权重也看到,并且看到误差平方和是9.4;

如果我们改变下层数,改成五层的话:

m_neuralnet<-neuralnet(setosa+versicolor+virginica~Sepal.Length+Sepal.Width+Petal.Length+Petal.Width,                       data=iris_train1,hidden=5,                       linear.output = FALSE,                       act.fct = "logistic")plot(m_neuralnet)

这里写图片描述

模型会变得非常复杂,而且误差平方和急剧减少。

其中的linear.output = FALSE 以及act.fct = "logistic" 都是默认选项,可以简单理解为让输出值为正;

既然我们这个五层的效果更好,我们就用这个看下准确率

m_neuralnet_result<-compute(m_neuralnet,iris_test[,1:4])m_neuralnet_result$net.result

而出现了下面的情况:

head(m_neuralnet_result$net.result)                                 [,1]          [,2]27 1.00000000000000000000000000000000 0.0561786299555 0.00000000000000000000003373619417 0.4795580576971 0.00000000000000000000001592745084 0.4849140755365 0.00000000000000000000062350814915 0.4587985751087 0.00000000000000000000003974685356 0.4783885698320 1.00000000000000000000000000000000 0.04237947425                             [,3]27 0.000000000000000000000000000055 0.000491994785513811378439841371 0.749673009512628718553628459665 0.000000000000000000967368997187 0.000073358770340629852134938020 0.0000000000000000000000000000

这个当然不是因子了,而且无法解释,其实是相当于我们把二分类进行logistic回归一样的感觉:logistic回归就是把原本的布尔值,改成了概率,那么原本为1的我们通过回归可以看到为1的概率。在这里,我们当然是取最大的那个概率作为我们的预测值;

m_neuralnet_result1<-max.col(m_neuralnet_result$net.result)

看到

 [1] 1 2 3 2 2 1 2 3 2 1 1 1 1 1 2 1 2 1 1 1 3 2 2 3 3 3 2 3[29] 3 3 1 3 3 2 3 1 3 2 3 2 2 2 2 3 3

我们选取了最大的这一列,m_neuralnet_result1是列序号,我们需要还原为真实的变量名:

new_test<-class.ind(as.factor(iris_test$Species))m_neuralnet_result2<-  sapply(m_neuralnet_result1,function(x)colnames(new_test)[m_neuralnet_result1[x]])

这里用了一个sapply函数,也就是返回new_test的变量名;而new_test是什么呢?是用同样的方式针对iris_test的Species变量进行哑变量转换的数据。

看到

m_neuralnet_result2 [1] "setosa"     "versicolor" "virginica"  "versicolor" [5] "versicolor" "setosa"     "versicolor" "virginica"  [9] "versicolor" "setosa"     "setosa"     "setosa"    [13] "setosa"     "setosa"     "versicolor" "setosa"    [17] "versicolor" "setosa"     "setosa"     "setosa"    [21] "virginica"  "versicolor" "versicolor" "virginica" [25] "virginica"  "virginica"  "versicolor" "virginica" [29] "virginica"  "virginica"  "setosa"     "virginica" [33] "virginica"  "versicolor" "virginica"  "setosa"    [37] "virginica"  "versicolor" "virginica"  "versicolor"[41] "versicolor" "versicolor" "versicolor" "virginica" [45] "virginica" 

这个就是我们预测的变量结果啦。

下面还是老规矩,比较下预测值和实际值:

table(iris_test[,5],m_neuralnet_result2)
            m_neuralnet_result2             setosa versicolor virginica  setosa         13          0         0  versicolor      0         16         1  virginica       0          0        15

这里看到,准确率为97.8%,可以说是很高了;

然后看下Kappa值:

library(vcd)Kappa(table(predict=m_neuralnet_result2,test=iris_test$Species))
value        ASE        z     Pr(>|z|)Unweighted 0.9665179 0.03312992 29.17357 4.19822e-187Weighted   0.9742416 0.02560386 38.05058  0.00000e+00

有96.7%的unweight值,迄今为止,应该是最高的了

最后说一句,理论上对于不同维度的数值需要进行标准化,但是本例中,由于四类数据差异不大,就省略了这个步骤,其实是不太严谨的。

原创粉丝点击