欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

《数据挖掘:R语言实战》神经网络完整代码

程序员文章站 2022-05-12 19:06:08
《数据挖掘:R语言实战》神经网络完整代码 # class.ind()函数############################################ v1=c('a...

《数据挖掘:R语言实战》神经网络完整代码

# class.ind()函数############################################
v1=c('a','b','a','c')
v2=c(1,2,1,3)

class.ind(v1)
class.ind(v2)

# 数据归一化方法 #############################################
scale01=function(x){
  # 提取预处理样本集中特征变量个数
  ncol=dim(x)[2]-1
  # 提取预处理样本的样本总量
  nrow=dim(x)[1]
  # 建立用于保存新样本集的矩阵
  new=matrix(0,nrow,ncol)

  for(i in 1:ncol){
    # 提取每个变量的最大值
    max=max(x[,i])
    # 提取每个变量的最小值
    min=min(x[,i])
    # 对每个变量的所有样本数据进行归一化处理
    for(j in 1:nrow){
      new[j,i]=(x[j,i]-min)/(max-min)
    }
  }
  new
}


# 数据集预处理#################################################
wine=read.csv("winequality-white.csv",head=TRUE,sep = ';')  
View(wine)
dim(wine)
summary(wine)

# 将quality结果分为3类
# 中间变量
cha=0   

# 对数据分类处理
for(i in 1:4898) 
{
  if(wine[i,12]>6)
  {
    cha[i]="good"
  }
  else if(wine[i,12]>5)
  {
    cha[i]="mid"    
  }
  else
  {
    cha[i]="bad"    
  }
}

# 分类
wine[,12]=factor(cha)   
# 查看对应类别的情况
summary(wine$quality)

# 重命名
names(wine)=c("fixed","volatile","citric","residual","chlorides","free","total","density","PH","sulphates","alcohol","quality")                                                     
View(wine)

# 随机抽样
set.seed(71)
samp=sample(1:4898,3000) 

# 对抽样的进行数据归一化处理,并提取前11列的变量
wine[samp,1:11]=scale01(wine[samp,])

# 确定参数 range的变化范围
r=1/max(abs(wine[samp,1:11]))   

# 第 1 种方式,建立神经网络模型
set.seed(101)
model1=nnet(quality~.,data=wine,subset=samp,size=4,rang=r,decay=5e-4,maxit=200)                                            


# 第 2 种方式,建立神经网络模型
x=subset(wine,select=-quality)      
y=wine[,12] 
# 建立类指标矩阵
y=class.ind(y)              
set.seed(101)
# 建立神经网络模型
model2=nnet(x,y,decay=5e-4,maxit=200,size=4,rang=r)     


# 模型结果分析###########################################
# 模型1
summary(model1)
# 模型2
summary(model2)


# 模型预测###############################################
# 第 1 种方法预测
x=wine[,1:11]       
# 预测
pred1=predict(model1,x,type="class")    
set.seed(110)
# 抽取8个样本,进行预测
sample(1:4898,8);pred1[sample(1:4898,8)]            


# 第 2 种方法预测
xt=wine[,1:11]
# 预测
pred=predict(model2,xt)     
dim(pred)   
# 得到的结果,是矩阵
sample(1:4898,8);pred[sample(1:4898,8),]            

# 确定3个类别的名称
name1=c("bad","good","mid") 
# 确定每行中最大值所在的列
prednew=max.col(pred)       
# 将每行取出的值,即由"1,2,3"组成
# name1[]:利用"过滤器"的方式,为每行的取值,“打标签”
prednewn=name1[prednew]     
# 随机抽样
set.seed(201)
sample(1:4898,8);prednewn[sample(1:4898,8)] 

# 构建混淆矩阵
# 将“类指标矩阵”的"1"提取出来,即是相应的判定类别
true=max.col(y) 
# 混淆矩阵
table(true,prednewn)            


# 模型差异分析##############################################
# 加载包
library(e1071)                  

# 数据集处理
data(iris)  
View(iris)
summary(iris)
dim(iris)

# 特征向量
x=iris[,-5]
# 结果变量
y=iris[,5]

# 将 x 转换为矩阵
x=as.matrix(x)
# 构建 类指标矩阵
y=class.ind(y)

# 对抽样的进行数据归一化处理,并提取前4列的变量
iris[x,1:4]=scale01(iris[x,])

# 建立神经网络模型
model1=nnet(x,y,size=4,maxit=500,decay=5e-4,rang=1/max(abs(x)))  
model2=nnet(x,y,size=4,maxit=500,decay=5e-4,rang=1/max(abs(x)))   

# 查看迭代次数是否达到最大值
model1$convergence
model2$convergence

# 模型迭代的最终值
model1$value
model2$value

# 为三个类别确定名称
name=c("setosa","versicolor","virginica")

# 模型的预测
pred1=name[max.col(predict(model1,x))]
pred2=name[max.col(predict(model2,x))]

# 混淆矩阵
table(iris$Species,pred1)                  
table(iris$Species,pred2)  


# 优化模型#######################################################
wine=read.csv("winequality-white.csv",head=TRUE,sep = ';')  
names(wine)=c("fixed","volatile","citric","residual","chlorides","free","total","density","PH","sulphates","alcohol","quality")                                                         
# 抽样
set.seed(71)
wine=wine[sample(1:4898,3000),]
# 样本数
nrow.wine=dim(wine)[1]

# 元数据归一化
scale01=function(x)
{
    ncol=dim(x)[2]-1
    nrow=dim(x)[1]
    new=matrix(0,nrow,ncol)
    for(i in 1:ncol)
    {
        max=max(x[,i])
        min=min(x[,i])
        for(j in 1:nrow)
        {
            new[j,i]=(x[j,i]-min)/(max-min)
        }
    }
    new
}

# 分类==>打标签
cha=0   
for(i in 1: nrow.wine) 
{
    if(wine[i,12]>6)
    {
        cha[i]="good"   
    }
    else if(wine[i,12]>5)
    {
        cha[i]="mid"    
    }
    else
    {
        cha[i]="bad"    
    }
}

# 打标签
wine[,12]=factor(cha)   

# 抽样
set.seed(444)
samp=sample(1:nrow.wine, nrow.wine*0.7)

# 归一化处理
wine[samp,1:11]=scale01(wine[samp,])        
wine[-samp,1:11]=scale01(wine[-samp,])

# 随机变量权重的范围
r=1/max(abs(wine[samp,1:11]))       

n=length(samp)
err1=0
err2=0

# 改变size的值,即隐藏层中的节点个数11*1.5=16.5,取17
# 取输入节点个数的1.2--1.5倍
for(i in 1:17)
{   
    set.seed(111)
    model=nnet(quality~.,data=wine,maxit=400,rang=r,size=i,subset=samp,decay=5e-4)
    err1[i]=sum(predict(model,wine[samp,1:11],type='class')!=wine[samp,12])/n
    err2[i]=sum(predict(model,wine[-samp,1:11],type='class')!=wine[-samp,12])/(nrow.wine -n)
}

plot(1:17,err1,'l',col=1,lty=1,ylab="模型误判率",xlab="隐藏层节点个数",ylim=c(min(min(err1),min(err2)),max(max(err1),max(err2))))
lines(1:17,err2,col=1,lty=3)
points(1:17,err1,col=1,pch="+")
points(1:17,err2,col=1,pch="o")
legend(1,0.53,"测试集误判率",bty="n",cex=1.5)
legend(1,0.35,"训练集误判率",bty="n",cex=1.5)


# maxit:控制的是 模型的最大迭代次数
err11=0
err12=0
for(i in 1:500)
{
    set.seed(111)   
    model=nnet(quality~.,data=wine,maxit=i,rang=r,size=3,subset=samp)
    err11[i]=sum(predict(model,wine[samp,1:11],type='class')!=wine[samp,12])/n
    err12[i]=sum(predict(model,wine[-samp,1:11],type='class')!=wine[-samp,12])/(nrow.wine-n)
}

plot(1:length(err11),err11,'l',ylab="模型误判率",xlab="训练周期",col=1,ylim=c(min(min(err11),min(err12)),max(max(err11),max(err12))))
lines(1:length(err11),err12,col=1,lty=3)
legend(250,0.47,"测试集误判率",bty="n",cex=1.2)
legend(250,0.425,"训练集误判率",bty="n",cex=1.2)

# 取迭代次数为300,隐藏节点为3
set.seed(111)
model=nnet(quality~.,data=wine,maxit=300,rang=r,size=3,subset=samp)
x=wine[-samp,1:11]          
pred=predict(model,x,type="class")  
table(wine[-samp,12],pred)