人工神经网络之乳腺癌识别_Sim1480的博客-程序员宅基地

人工神经网络是一种类似于大脑神经突触连接的结构进行信息处理的数学模型,由大量的输入层节点、隐藏层节点和输出层节点连接构成。其构造类似于下图:

0?wx_fmt=png
上图中明确显示了输入层、隐藏层和输出层,红框表示节点与节点之间连接函数(或激活函数),黄框表示上一个节点到下一个节点变换权重。所以,有关神经网络算法最核心的三个问题就是:选择激活函数、隐藏层数目和节点的确定以及权重的设置


一、选择激活函数

这里简单介绍以下6种激活函数:

0?wx_fmt=png
其中最为常用的是Logistic激活函数、双曲正切激活函数和高斯激活函数,R中一般默认使用Logistic激活函数。通常情况下,激活函数的输出信号值范围可以是(0,1)、(-1,1)、(-∞,∞),而输入信号之和的范围可以是(-∞,∞),如果仔细看图的话,会发现随着输入信号之和的绝对值越大,输出信号值始终为0或1或-1,这样的结果将会失真。所以一般需要将输入信号X变量压缩到0附近,通常的做法是数据标准化,以下自定义标准化函数:

standard1 <- function(x){

(x-min(x))/(max(x)-min(x))

}

standard2 <- function(x){

(x-mean(x))/sd(x)

}

前一种是最大最小标准化,后一种是标准正态化。如果数据集基本服从正态分布的话,可以考虑使用后一种标注化方法;否则就使用前一种标准化方法。


二、选择隐藏层数目和节点数量

如上文中的神经网络图所示,只有1层隐藏层,称其为单层网络,单层网络一般可用于基本的模式分类,特别是可用于能够线性分割的模式,但实际中往往需要更多的隐藏层,目前多层前馈网络已成为人工神经网络拓扑结构的事实标准。多层隐藏层的神经网络图:

0?wx_fmt=png

除了隐藏层数目可以改动,其每层的节点数量也可以灵活的改变,对于节点数量的选择可以通过循环测试,最终挑选出比较理想的节点数量

一般情况下,随着隐藏层数目和节点数量的增加,使神经网络显得尤为复杂,实现复杂问题的学习,但是这样的模型会产生过拟合的风险,而且计算量的增加导致训练缓慢。


三、权重的设置

通过调整连接权重训练神经网络模型的计算量非常巨大,因此很少将其应用到真实世界的学习任务中。幸运的是,一种有效的训练人工神经网络的方法被发现,其可以解决权重的设置的问题,该算法使用了一种后向传播误差的策略(Backpropagation)


四、神经网络算法优缺点

优点:

1)适用于分类和数值预测问题

2)对数据几乎不作任何假设条件

缺点:

1)计算量大、训练缓慢,尤其是网络拓扑结构相当复杂时

2)容易发生过拟合

3)输出结果很难解释


有关R中神经网络算法的实现可以使用自带的nnet包,也可以使用neuralnet包,还可以使用一套完整的神经网络功能包RSNNS

nnet包中的函数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:模型的公式表达形式,类似于y~x1+x2+x3

data:指定要分析的数据对象

weights:代表各类样本在模型中所占比重,默认将各类样本按原始比重建立模型

subset:可提取目标数据集的子集作为模型的训练样本

na.action:处理缺失值的方法,默认忽略缺失值

x:为输入的自变量矩阵或数据框

y:为输入的因变量,但必须经过class.ind()函数的预处理

size:指定隐藏层节点个数,通常为输入变量个数的1.2至1.5倍

Wts:设置初始的权重,默认情况将随机产生权重值

mask:指定哪个参数需要最优化,默认全部参数都需要最优化

linout:指定线性输出还是Logistic输出,默认为Logistic输出

rang:设置初始权重值的范围[-rang,rang]

decay:指模型建立过程中,模型权重值的衰减精度,默认为0

maxit:指定模型的最大迭代次数


RSNNS包中的mlp()函数--多层前馈网络

mlp(x, y, size = c(5), maxit = 100,

initFunc = "Randomize_Weights", initFuncParams = c(-0.3, 0.3),

learnFunc = "Std_Backpropagation", learnFuncParams = c(0.2, 0),

updateFunc = "Topological_Order", updateFuncParams = c(0),

hiddenActFunc = "Act_Logistic", shufflePatterns = TRUE, linOut = FALSE,

inputsTest = NULL, targetsTest = NULL, pruneFunc = NULL,

pruneFuncParams = NULL, ...)

x:为输入的自变量矩阵或数据框

y:为输入的因变量

size:指定每个隐藏层的节点数,默认是单层5节点的拓扑结构

maxit:指定模型的最大迭代次数

initFunc:指定权重的初始函数

initFuncParams:权重的初始值默认在(-0.3, 0.3)之间

learnFunc:指定计算神经网络的算法类型,默认为标准后向传播算法

learnFuncParams:指定学习算法参数的初始值,即学习速率和最大输出误差

updateFunc:指定替换的算法类型

hiddenActFunc:指定隐藏层的算法类型

linOut:指定输出层的激活函数,可以是线性或Logistic


neuralnet包中的neuralnet()函数语法

neuralnet(formula, data, hidden = c(1), threshold = 0.01,

stepmax = 1e+05, rep = 1, startweights = NULL,

learningrate.limit = NULL,

learningrate.factor = list(minus = 0.5, plus = 1.2),

learningrate=NULL, lifesign = "none",

lifesign.step = 1000, algorithm = "rprop+",

err.fct = "sse", act.fct = "logistic",

linear.output = TRUE, exclude = NULL,

constant.weights = NULL, likelihood = FALSE)

formula:模型的公式表达形式,类似于y~x1+x2+x3,不允许y~.的格式

data:指定要分析的数据对象

hidden:指定每个隐藏层的节点数,默认是单层1节点的拓扑结构

threshold:指定误差函数的偏差阈值,默认为0.01

stepmax:指定模型的最大迭代次数

rep:指定神经网络训练的次数

startweights:设置初始的权重,默认情况将随机产生权重值

learningrate.limit:指定学习速率的最小最大值,该参数仅对RPROP和 GRPROP方法起效

learningrate:可为后向传播算法指定学习速率

algorithm:指定计算神经网络的算法类型

但该包只能处理连续型因变量的预测。


五、应用

本文尝试使用神经网络算法对乳腺癌进行分类,数据来自于《机器学习与R语言》中的案例,数据包括569条样本和32个变量。

#读取数据

cancer <- read.csv(file = file.choose())

str(cancer)

除样本的标识号ID以外,diagnosis变量为目标变量,其余都是数值型变量。

#数据标准化

cancer_stand <- sapply(cancer[,-c(1,2)], standard1)

#数据合并

cancer_stand <- as.data.frame(cbind(diagnosis = cancer$diagnosis, cancer_stand))

#将目标变量转换为因子

cancer_stand$diagnosis <- factor(cancer_stand$diagnosis, levels = c(1,2), labels = c('B','M'))


#构建训练样本集和测试样本集

set.seed(1234)

index <- sample(c(1,2), nrow(cancer_stand), replace = TRUE, prob = c(0.8,0.2))

train <- cancer_stand[index == 1,]

test <- cancer_stand[index == 2,]


#使用nnet包中的nnet()函数建模

library(nnet)

#通过循环,确定最佳的节点数

err1 <- 0

err2 <- 0

for (i in 1:45){

set.seed(1234)

model <- nnet(diagnosis ~ ., data = train, maxit = 300, size = i, trace = FALSE)

err1[i] <- sum(predict(model, train, type = 'class') != train$diagnosis)/nrow(train)

err2[i] <- sum(predict(model, test, type = 'class') != test$diagnosis)/nrow(test)

}

plot(err1, type = 'b', col = 'black', lty = 2, lwd = 2, ylab = '误差', xlab = '节点数', ylim = c(0,0.05), pch = 10)

lines(err2, type = 'b', col = 'blue', lty = 2, lwd = 2, pch = 23)

legend(locator(1), legend = c('训练集误差率','测试集误差率'), col = c('black','blue'), lty = c(2,2), lwd = c(2,2), bty = 'n',

pch = c(10,23))

0?wx_fmt=png
通过返回的图形结果,选择最佳的节点数为4。


#通过循环,确定最大迭代次数

err1 <- numeric()

err2 <- numeric()

for (i in 1:500){

set.seed(1234)

model <- nnet(diagnosis ~ ., data = train, maxit = i, size = 4, trace = FALSE)

err1[i] <- sum(predict(model, train, type = 'class') != train$diagnosis)/nrow(train)

err2[i] <- sum(predict(model, test, type = 'class') != test$diagnosis)/nrow(test)

}

plot(err1, type = 'l', col = 'black', lty = 1, ylab = '误差', xlab = '节点数')

lines(err2, type = 'l', col = 'blue', lty = 4)

legend(locator(1), legend = c('训练集误差率','测试集误差率'), col = c('black','blue'), lty = c(1,4), bty = 'n')

0?wx_fmt=png
通过返回的图形结果,选择最大迭代次数为50。


#建立最终的神经网络模型

set.seed(1234)

model_nnet <- nnet(diagnosis ~ ., data = train, maxit = 50, size = 4, trace = FALSE)

pred_nnet <- predict(model_nnet, test, type = 'class')

#预测精度

Freq_nnet <- table(test$diagnosis, pred_nnet)

Freq_nnet

accuracy_nnet <- sum(diag(Freq_nnet))/sum(Freq_nnet)

accuracy_nnet

0?wx_fmt=png
模型准确判断率超过99%,模型非常完美的刻画了数据。


#使用RSNNS包中的mlp()函数建模

library(RSNNS)

#将数据顺序打乱

data_cancer = cancer[sample(1:nrow(cancer),length(1:nrow(cancer))),2:ncol(cancer)]

#定义网络输入

cancerValues= data_cancer[,-1]

#定义网络输出,并将数据进行格式转换

cancerTargets = decodeClassLabels(data_cancer[,1])

#从中划分出训练样本和检验样本

set.seed(1234)

model_cancer = splitForTrainingAndTest(cancerValues, cancerTargets, ratio=0.20)

#数据标准化

model_cancer = normTrainingAndTestSet(model_cancer, type = '0_1')

#利用mlp命令执行前馈反向传播神经网络算法

model_mlp = mlp(model_cancer$inputsTrain, model_cancer$targetsTrain, size=4, maxit=100, inputsTest=model_cancer$inputsTest, targetsTest=model_cancer$targetsTest)

#利用上面建立的模型进行预测

pred_mlp = predict(model_mlp, model_cancer$inputsTest)

#生成混淆矩阵,观察预测精度

Freq_mlp <- confusionMatrix(model_cancer$targetsTest,pred_mlp)

Freq_mlp

accuracy_mlp <- sum(diag(Freq_mlp))/sum(Freq_mlp)

accuracy_mlp

0?wx_fmt=png
模型的预测能力也非常高,准确率超过95%,但相比于nnet()函数准确率明显下降。


文中的数据和代码可到如下链接下载:

链接:http://pan.baidu.com/s/1o7a8Ph4 密码:x7mk


总结:文章涉及到的R包和函数

read.csv()

sapply()

nnet包

nnet()

predict()

table()

RSNNS包

decodeClassLabels()

splitForTrainingAndTest()

normTrainingAndTestSet()

mlp()

confusionMatrix()

neuralnet包

neuralnet()

compute()


参考资料

机器学习与R语言

数据挖掘:R语言实战

http://ju.outofmemory.cn/entry/84442

http://www.r-bloggers.com/fitting-a-neural-network-in-r-neuralnet-package/

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lsxxx2011/article/details/98764200

智能推荐

985考研上岸之数据结构部分(很全,抓住重点)_fchqqj-程序员宅基地

考研数据结构-Data Structure of Kao YanZhou Bo(Suzhou University of Science and Technology)Email:[email protected] QQ:2364339378主要王道代码风格太乱了(怀疑不是一个人敲的,我统一了一下)有问题的地方欢迎评论区指正~ 参考:王道+一些算法模板线性表那一块应该主要考察算法要不就是双指针,要不就是分治,实在不行就是暴力,自己主要练一下链表那块的规范因此主要整理树(重中之重)、图、串这一_fchqqj

JAVA 逆序_逆序java-程序员宅基地

54321 =》12345有这样的一个规则:JAVA:java的/取的是整数部分1%10=120/10%10=230/10/10%10=340/10/10/10%10=450/10/10/10%10=5public class arrx { public static void main(String[] args){ _逆序java

磊科nw705p虚拟服务器设置,教你如何设置磊科nw705p无线路由器的详细步骤【图文】...-程序员宅基地

路由器的设置其实方法很简单,一般来说安装宽带的时候都会顺便安装上路由器并设置好,但是有用户对于刚买的磊科nw705p无线路由器却不知道如何下手了,对于这个磊科nw705p无线路由器的设置有什么好的方法呢?下面小编就来教大家设置磊科nw705p无线路由器的详细步骤。具体方法:1、光纤插连接到光纤猫PON口→从光纤猫LAN口用网线连接到路由器WAN口→从路由器LAN口用网线连接到电脑网卡上。2、打开“..._磊科nw705p路由器怎么设置

VC 小型矢量图形系统开发的实现-程序员宅基地

大家学习了VC的MFC的一些基础知识后,如果能用VC开发一个比较实用的软件,对熟悉VC各方面编程和面向对象的软件设计和开发都是很有帮助的。本文旨在通过对一个作者自己开发的小型矢量图形系统全面讲述而达到让读者了解一个小软件从设计到实现的阶段的解决的问题。同时也从界面和功能上对MFC和Windows系统功能的挖掘,同样,对于学习计算机图形学的读者,也可以看到本文有很多对图形学算法和实现的有益探讨。

Echarts在js中引用是无需下载文件,直接网络引用。src地址记录_echarts-all-3.js网址在哪-程序员宅基地

在一个帖子里找到了一个链接,帖子的网址是:点击打开链接;这个链接是<script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/echarts-all-3.js"></script>引入这个连接就可以使用echarts了。页面给一个div的位置<div id="main" style="width: 600px;height:400px;"&..._echarts-all-3.js网址在哪

Duplicate property mapping of xxx found in xx 解决办法_duplicate property mapping of code found in com.ce-程序员宅基地

原因*.hbm.xml中有二个一样的<property name="名字" /><property name="名字" />MemberGuessCycle类中 映射字段重复 createdTime 父类中已有该属性解决方法改个名字即可..._duplicate property mapping of code found in com.cems.erp.domain.sb.byjhdetai

随便推点

动态执行程序-程序员宅基地

1,语法检查EDITOR_SYNTAX_CHECK2,程序生成 GENERATE SUBROUTINE POOL itab_prog NAME prog MESSAGE msg.

2019-10-21 设置GeoTif图像中缺失值为Nodata_tif文件像素值为0-程序员宅基地

需求与目的在批量将MODIS数据hdf转为GeoTif格式之后(具体操作可参考我的另一篇博客),在ArcGIS打开图像发现,图像中的缺失值是一个具体的数值(有时是+3888888888888或者是-3888888888888或者是其它)而非Nodata(如下图所示)可以看出,图像中像素值为0的像元都是Nodata区域。如果不将0值设为Nodata,不仅影响ArcGIS中图像显示的美观效果,而..._tif文件像素值为0

UEditor的使用-程序员宅基地

最近的开发一个模块,要使用的html

cocos2d-x学习遇到的问题-程序员宅基地

程序移植到安卓平台后运行出现以下错误:1、Fatalsignal11(SIGSEGV)转载于:https://www.cnblogs.com/zhong-dev/p/4044618.html

文本分类-必读论文合集推荐-AMiner-程序员宅基地

AMiner平台由清华大学计算机系研发,拥有我国完全自主知识产权。平台包含了超过2.3亿学术论文/专利和1.36亿学者的科技图谱,提供学者评价、专家发现、智能指派、学术地图等科技情报专业化服务。系统2006年上线,吸引了全球220个国家/地区1000多万独立IP访问,数据下载量230万次,年度访问量超过1100万,成为学术搜索和社会网络挖掘研究的重要数据和实验平台。AMiner平台:https://www.aminer.cn文本分类用电脑对文本集(或其他实体或物件)按照一定的分类体系或标准进行自动分.

使用for循环输出一个倒三角形。_for循环输出倒三角-程序员宅基地

// 使用for循环输出一个倒三角形。for (int i = 0;i < 10;i++){for (int j = 10;j >= i;j–){System.out.print(" “);}for (int c = 1;c <= i;c++){System.out.print(”*");}System.out.print("\n");}输出结果:_for循环输出倒三角

推荐文章

热门文章

相关标签