R语言神经网络

一、机器学习
 
1、学习方式:根据数据类型的不同,对一个问题的建模有不同的方式。在机器学习或者人工智能领域,人们首先会考虑算法的学习方式。在机器学习领域,有几种主要的学习方式。将算法按照学习方式分类是一个不错的想法,这样可以让人们在建模和算法选择的时候考虑能根据输入数据来选择最合适的算法来获得最好的结果。

监督式学习:在监督式学习下,输入数据被称为“训练数据”,每组训练数据有一个明确的标识或结果,如对防垃圾邮件系统中“垃圾邮件”“非垃圾邮件”,对手写数字识别中的“1“,”2“,”3“,”4“等。在建立预测模型的时候,监督式学习建立一个学习过程,将预测结果与“训练数据”的实际结果进行比较,不断的调整预测模型,直到模型的预测结果达到一个预期的准确率。监督式学习的常见应用场景如分类问题和回归问题。常见算法有逻辑回归(Logistic Regression)和反向传递神经网络(Back Propagation Neural Network)

 

非监督式学习:在非监督式学习中,数据并不被特别标识,学习模型是为了推断出数据的一些内在结构。常见的应用场景包括关联规则的学习以及聚类等。常见算法包括Apriori算法以及k-Means算法。

半监督式学习:在此学习方式下,输入数据部分被标识,部分没有被标识,这种学习模型可以用来进行预测,但是模型首先需要学习数据的内在结构以便合理的组织数据来进行预测。应用场景包括分类和回归,算法包括一些对常用监督式学习算法的延伸,这些算法首先试图对未标识数据进行建模,在此基础上再对标识的数据进行预测。如图论推理算法(Graph Inference)或者拉普拉斯支持向量机(Laplacian SVM.)等。 

      二、神级网络简介

神经网络没有一个严格的正式定义它的基本特点,是试图模仿大脑的神经元之间传递,处理信息的模式。
  R语言之神经网络

一个计算模型,要划分为神经网络,通常需要大量彼此连接的节点 (也称 ‘神经元’),并且具备两个特性:每个神经元,通过某种特定的输出函数 (也叫激励函数 activation function),计算处理来自其它相邻神经元的加权输入值;

      神经元之间的信息传递的强度,用所谓加权值来定义,算法会不断自我学习,调整这个加权值。在此基础上,神经网络的计算模型,依靠大量的数据来训练,还需要:

       成本函数 (cost function):用来定量评估根据特定输入值,计算出来的输出结果,离正确值有多远,结果有多靠;

       学习的算法 ( learning algorithm ):这是根据成本函数的结果,自学,纠错,最快地找到神经元之间最优化的加权值;

二、R语言中的神经网络包:
R语言中已经有许多用于神经网络的package。例如nnet、AMORE以及neuralnet,
nnet提供了最常见的前馈反向传播神经网络算法
AMORE包则更进一步提供了更为丰富的控制参数,并可以增加多个隐藏层。
neuralnet包的改进在于提供了弹性反向传播算法和更多的激活函数形式
但以上各包均围绕着BP网络,并未涉及到神经网络中的其它拓扑结构和网络模型。而新出炉的RSNNS包则在这方面有了极大的扩充。
(一)RSNNS包
1、安装和加载 RSNNS
install.packages("RSNNS")
library(Rcpp)
library(RSNNS)
2、加载和编辑数据:
data(iris)
#将数据顺序打乱 
iris = iris[sample(1:nrow(iris),length(1:nrow(iris))),1:ncol(iris)]
#定义网络输入 
irisValues= iris[,1:4]
#定义网络输出,并将数据进行格式转换 
irisTargets = decodeClassLabels(iris[,5])
#从中划分出训练样本和检验样本 
iris = splitForTrainingAndTest(irisValues, irisTargets, ratio=0.15)
#数据标准化 
iris = normTrainingAndTestSet(iris)
#利用mlp命令执行前馈反向传播神经网络算法 
model = mlp(iris$inputsTrain, iris$targetsTrain, size=5, learnFunc="Quickprop", learnFuncParams=c(0.1, 2.0, 0.0001, 0.1),maxit=100, inputsTest=iris$inputsTest, targetsTest=iris$targetsTest) 
      #利用上面建立的模型进行预测 
       predictions = predict(model,iris$inputsTest)
#生成混淆矩阵,观察预测精度 
confusionMatrix(iris$targetsTest,predictions)
          predictions
targets  1  2  3
      1    5  0  0
      2    0 10  1
      3    0  1  6
 
mlp意指多层感知器,RSNNS包中其它重要的网络形式还包括: dlvq(动态学习向量化网络), rbf(径向基函数网络), elman(elman神经网络), jordan(jordan神经网络), som(自组织映射神经网络), art1(适应性共振神经网络)等等 
data(snnsData)
inputs <- snnsData$laser_1000.pat[,inputColumns(snnsData$laser_1000.pat)]
inputs <- snnsDataeight16.pat[,inputColumns(snnsDataeight_016.pat)]
outputs <- snnsDataeight16.pat[,outputColumns(snnsDataeight_016.pat)]
par(mfrow=c(1,2))
modelElman <- elman(inputs, outputs, size=8, learnFuncParams=c(0.1), maxit=1000)
modelElman
modelJordan <- jordan(inputs, outputs, size=8, learnFuncParams=c(0.1), maxit=1000)
modelJordan
plotIterativeError(modelElman)
plotIterativeError(modelJordan)
summary(modelElman)
summary(modelJordan)
 

(二)nnet包(前馈反向传播神经网络算法)
Feed-Forward Neural Networks and Multinomial Log-Linear Models
BP(Back Propagation)神经网络  是1986年由Rumelhart和McCelland为首的科学家小组提出,是一种按误差逆传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一。BP网络能学习和存贮大量的输入-输出模式映射关系,而无需事前揭示描述这种映射关系的数学方程。它的学习规则是使用最速下降法,通过反向传播来不断调整网络的权值和阈值,使网络的误差平方和最小。BP神经网络模型拓扑结构包括输入层(input)、隐层(hide layer)和输出层(output layer)。 
install.packages("DMwR")
library(lattice)
library(grid)
library(DMwR)
library(nnet)
nnet(formula, data, weights, ...,subset, na.action, contrasts = NULL)
nnet(x, y, weights, size, Wts, mask,
     linout = FALSE, entropy = FALSE, softmax = FALSE,
     censored = FALSE, skip = FALSE, rang = 0.7, decay = 0,
     maxit = 100, Hess = FALSE, trace = TRUE, MaxNWts = 1000,
     abstol = 1.0e-4, reltol = 1.0e-8, ...)
其中formula:公式的形式class ~ x1 + x2 + ...
x:矩阵x值的例子或数据框 Y:矩阵或数据框的例子目标值
size:隐藏层单位数目   linout:切换线性输出单位  
nnet包中的nnet(x, y, size, rang, decay, maxit, skip, Hess, trace)函数:单层的前向神经网络模型。
size神经网络隐藏层的神经元个数;
rang初始随机权值[-rang, rang];
decay经元输入权重的一个修改偏正参数,表明权值是递减的(可以防止过拟合);
maxit最大反馈迭代次数;
skip是否允许跳过隐藏层;
Hess是否输出Hessian值;
trace指出是否要最优化。
 
data(algae)  #藻数量数据,200个水样,每个记录由11个变量组成,seasonsizespeed为名义变量,其余为所观测水样的不同化学参数,参数为连续变量。
      algae <- algae[-manyNAs(algae), ]  #去除无效值(包含多个无效值的行数据)
clean.algae <- knnImputation(algae[,1:12],k=10) 
#处理NA值的方法,这个函数用一个欧式距离的变种来找到距离任何个案最近的K个邻居。填补缺失值的方法可以是k个邻居的中位数,或者众数以及加权均值。
algae<-knnImputation(algae,k=10,meth=”median”)  就是使用中位数填补
#神经网络还需要对数据进行标准化 
norm.data <- scale(clean.algae[,4:12]) 
#使用nnet命令,参数规定隐层单元个数为10,权重调整速度为0.1,最大迭代次数为1000次,线性输入。 
nn <- nnet(a1~., norm.data, size = 10, decay = 0.01, 
 maxit = 1000, linout = T, trace = F) 
#利用模型进行预测 
norm.preds <- predict(nn, norm.data) 
#绘制预测值与真实值之间的散点图 
plot(norm.preds~ scale(clean.algae$a1)) 
#计算相对误差 
(nmse2 <- mean((norm.preds-scale(clean.algae$a1))^2)/ 
mean((mean( scale(clean.algae$a1))- scale(clean.algae$a1))^2)) 
      再来看看处理分类数据的表现,利用iris数据来判断花的种类 
model.nnet <-nnet(Species ~ ., linout = F,size = 10, decay = 0.01, 
 maxit = 1000,trace = F,data = iris) 
#对分类数据预测需要加上type参数 
pre.forest=predict(model.nnet, iris,type='class') 
table(pre.forest,iris$Species) 
    支持向量机SVM是九十年代中期发展起来的新的机器学习技术,与传统的神经网络NN技术不同,SVM是以统计学习理论SLT为基础,NN是以传统统计学理论为基础。传统统计学的前提条件是要有足够多的样本,而统计学习理论是着重研究小样本条件下的统计规律和学习方法的,它为机器学习问题建立了一个很好的理论框架。 

library(e1071) 
model.svm <- svm(a1~., norm.data) 
preds <- predict(model.svm, norm.data) 
plot(preds~ scale(clean.algae$a1)) 
model.svm <-svm(Species ~ .,data = iris) 
pre=predict(model.svm, iris,type='class') 
table(pre,iris$Species) 
多元自适应回归样条(MARS) 
library(earth) 
model.mars <- earth(a1~., clean.algae) 
preds <- predict(model.mars, clean.algae) 
plot(preds~ clean.algae$a1) 
(nmse2 <- mean((preds-clean.algae$a1)^2)/ 
mean((mean( clean.algae$a1)- clean.algae$a1)^2)) 
model.mars <-earth(Species ~ .,data = iris) 
pre=predict(model.mars, iris,type='class') 
table(pre,iris$Species) 
(三)AMORE 
newff(n.neurons, learning.rate.global, momentum.global, error.criterium, Stao, hidden.layer, output.layer, method)函数:创建多层前馈神经网络。
n.neurons是个数值向量,包含在每个层的神经元的数目,第一个数是输入神经元的数量,最后是输出神经元的数量,其余的都是隐藏层神经元的数量;
learning.rate.global全局的学习率;
momentum.global全局的动量值(有的学习算法需要设置这个值貌似是步长);
error.criterium误差衡量算法,我用误差平方和,所以选“LMS”,“LMLS”为对数平方差,“TAO”为TAO Error;hidden.layer隐藏层激活函数;
output.layer输出层激活函数;
method学习方法,翻译过来都是梯度下降,不是BP最速下降;
Stao 为Taobao错误判断标准。
 
train(net, P, T, error.criterium, report, show.step, n.shows)函数:神经网络训练函数。对于一个给定的数据集(训练集),此功能修改的神经网络的权重和偏差的近似的训练集中存在的变量之间的关系。这些可以满足一些需要,即拟合非线性函数。 
net为神经网络训练;
P为输入的训练集;
T为输出的训练集;
error.criterium为衡量拟合优度的标准(LMS、LMLS、TAO);
report表示训练函数是否保持安静(或应在训练过程中提供图形/文字信息);
show.step直到训练函数给出结果的最大值;
n.shows报告训练的次数。
 
sim(net, P)函数:计算给定数据集神经网络的输出值。
net模拟神经网络;
P输入数据集。
 
install.packages("AMORE")
library(AMORE)
#生成输入数据
P <- matrix(sample(seq(-1,1,length=1000), 1000, replace=FALSE), ncol=1)
#生成输出数据
target <- P^2
#生成2个隐藏层的神经网络结构,
net <- newff(n.neurons=c(1,3,2,1), learning.rate.global=1e-2, momentum.global=0.5,

error.criterium="LMS", Stao=NA, hidden.layer="tansig",output.layer="purelin", method="ADAPTgdwm")
# n.neurons=c(输入节点个数,……中间节点,输出节点个数),
# error.criterium="LMS"判断收敛的依据,最小平均平方法,
#hidden.layer="tansig"隐藏层的激活函数,
#output.layer="purelin"输出层的激活函数
result <- train(net, P, target, error.criterium="LMS", report=TRUE, show.step=100, n.shows=5 )
#对待测集进行预测
y<-sim(result$net,P)     
plot(P,y, col="blue", pch="+")
points(P,target, col="red", pch="x")
(四)Neuralnet包
neuralnet(formula, data, hidden)函数:神经网络训练函数。
hidden一个向量的整数,指定在每一层中的隐层神经元(顶点)的数目。
hidden=c(3)表示第一个隐藏层的3个隐藏单元;
hidden=c(3, 2)分别表示第一、第二隐藏层的3个和2个隐藏单元。 
 
compute(x, covariate):神经网络计算一个给定的变量向量。
x为NN的模型;
covariate用来训练神经网络的数据框或矩阵。相当于predict函数(neuralnet中无predict函数)
 
 
案例一、
1、准备数据MASS package中的 Boston dataset )
目标:Our goal is to predict the median value of owner-occupied homes (medv) using all the other continuous variables available.
set.seed(500)
library(MASS)
data <- Boston
检查是否存在缺失值
apply(data,2,function(x) sum(is.na(x)))
结果显示不存在缺失值
将数据随机分成训练集和测试集,我们先通过多元线性回归的方法来预测,采用函数gml() ,以便对比神经网络和线性回归的方法差距。
index <- sample(1:nrow(data),round(0.75*nrow(data))) train <- data[index,] test <- data[-index,]
lm.fit <- glm(medv~., data=train)
summary(lm.fit)
pr.lm <- predict(lm.fit,test)
MSE.lm <- sum((pr.lm - test$medv)^2)/nrow(test)   #多元线性回归的均方误差
2、神经网络数据前期处理
1)数据处理:
在训练神经网络时最好先对数据进行标准化,强调一点标准化数据很重要。可以通过不同的方法对数据进行标准化(z-normalization, min-max scale, etc…),这里采用min-max scale方法,将数据映射到[0,1]区间。
maxs <- apply(data, 2, max)
mins <- apply(data, 2, min)
scaled <- as.data.frame(scale(data, center = mins, scale = maxs - mins))  #scale函数返回的是一个矩阵,而我们需要将其转换成一个数据框格式,以便后面的数据处理。
train_ <- scaled[index,] test_ <- scaled[-index,]
2)参数选择:
对于隐藏层和节点数的确定没有一个确定的规则。通常来说,一个隐藏层对大部分神经网络已经足够了。一般来说隐藏层数一般介于输入层和输出层之间,通常为输入层的2/3.在本例中我们采用双层隐藏层,分别为5、3个节点数,因此神经网络的结构为13:5:3:1。
3)神经网络训练
library(neuralnet)
n <- names(train_)
f <- as.formula(paste("medv ~", paste(n[!n %in% "medv"], collapse = " + ")))  #神经网络回归公式的生成
nn <- neuralnet(f,data=train_,hidden=c(5,3),linear.output=T)
注意:
对于公式 y~. 的形式在neuralnet() 函数中是不被接受的,你必须将整个回归公式写出来;
hidden 参数允许通过一个向量确定每个隐藏层的节点数;
linear.output=TRUE 表明做的是一般的回归,linear.output=FALSE表明做的是分类回归。
plot(nn) #画出神经网络图



4)神经网络预测
pr.nn <- compute(nn,test_[,1:13])
pr.nn_ <- pr.nn$net.result*(max(data$medv)-min(data$medv))+min(data$medv)
test.r <- (test_$medv)*(max(data$medv)-min(data$medv))+min(data$medv)
MSE.nn <- sum((test.r - pr.nn_)^2)/nrow(test_)
print(paste(MSE.lm,MSE.nn))  #对比两种回归方式的误差
通过图表来表示对比两种方式下的误差
par(mfrow=c(1,2))
plot(test$medv,pr.nn_,col='red',main='Real vs predicted NN',pch=18,cex=0.7)
abline(0,1,lwd=2)
legend('bottomright',legend='NN',pch=18,col='red', bty='n')
plot(test$medv,pr.lm,col='blue',main='Real vs predicted lm',pch=18, cex=0.7)
abline(0,1,lwd=2)
legend('bottomright',legend='LM',pch=18,col='blue', bty='n', cex=.95)




或者
plot(test$medv,pr.nn_,col='red',main='Real vs predicted NN',pch=18,cex=0.7)
points(test$medv,pr.lm,col='blue',pch=18,cex=0.7)
abline(0,1,lwd=2)
legend('bottomright',legend=c('NN','LM'),pch=18,col=c('red','blue'))
 

3、模型交叉验证(A(fast) cross validation)
train-test split
1)Do the train-test split
2)Fit the model to the train set
3)Test the model on the test set
4)Calculate the prediction error
5)Repeat the process K times
We are going to implement a fast cross validation using a for loop for the neural network and the cv.glm() function in the boot package for the linear model.
多元线性回归的交叉验证
library(boot)
set.seed(200)
lm.fit <- glm(medv~.,data=data)
cv.glm(data,lm.fit,K=10)$delta[1]
神经网络的交叉验证
Note that I am splitting the data in this way: 90% train set and 10% test set in a random way for 10 times. I am also initializing a progress bar using the plyr library because I want to keep an eye on the status of the process since the fitting of the neural network may take a while.
set.seed(450)
cv.error <- NULL
k <- 10
library(plyr)
pbar <- create_progress_bar('text')
pbar$init(k)
for(i in 1:k){
index <- sample(1:nrow(data),round(0.9*nrow(data)))
train.cv <- scaled[index,]
test.cv <- scaled[-index,]  
nn <- neuralnet(f,data=train.cv,hidden=c(5,2),linear.output=T)  
pr.nn <- compute(nn,test.cv[,1:13])
pr.nn <- pr.nn$net.result*(max(data$medv)-min(data$medv))+min(data$medv)
test.cv.r <- (test.cv$medv)*(max(data$medv)-min(data$medv))+min(data$medv)
cv.error[i] <- sum((test.cv.r - pr.nn)^2)/nrow(test.cv) 
pbar$step()
}
计算平均均方误差

mean(cv.error)
可以看出神经网络比多元线性回归的误差要小的多,拟合效果更加好。
boxplot(cv.error,xlab='MSE CV',col='cyan',border='blue',names='CV error (MSE)',main='CV error (MSE) for NN',horizontal=TRUE)
 
 
     
案例二
我们将会模拟一组很简单的数据实现输入和输出,其中,输出的变量是独立分布的随机数,输入的变量则是输出变量的平方。本次试验中,将会训练10个隐藏神经元。
install.packages('neuralnet')
library(grid)
library(MASS)
library(neuralnet)
# 构造50个独立分布在0到100之间的随机数 ,然后将他们保存成数据框架(data.frame)
traininginput <-  as.data.frame(runif(50, min=0, max=100))
trainingoutput <- sqrt(traininginput)
# 通过cbind函数将输入和输出向量构造成一个数据,用一些训练数据测试该神经网络
trainingdata <- cbind(traininginput,trainingoutput)
colnames(trainingdata) <- c("Input","Output")
# 训练10个隐藏神经元的神经网络
net.sqrt <- neuralnet(Output~Input,trainingdata, hidden=10, threshold=0.01)
print(net.sqrt)
# 绘制神经网络拓扑图
plot(net.sqrt)
testdata <- as.data.frame((1:10)^2) 
net.results <- compute(net.sqrt, testdata) 
ls(net.results)
# 查看结果 print(net.results$net.result)
让结果更直观些 cleanoutput <- cbind(testdata,sqrt(testdata),as.data.frame(net.results$net.result)) colnames(cleanoutput) <- c("Input","Expected Output","Neural Net Output") print(cleanoutput)

你可能感兴趣的:(R语言,r语言,神经网络,neuralnet包,AMORE包,nnet包)