R 数据分离与交叉验证的一些抽样方法

> #等比例数据抽样
> library(caret)
> str(iris)
'data.frame':	150 obs. of  5 variables:
 $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
 $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
 $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
 $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
 $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
> #数据划分时,考虑预测的分类Y的属性。Y为因子类型
> #并且划分的数据中,Y的比例与原始数据一致
> idx<-createDataPartition(iris$Species,times=1,p=0.8,list=TRUE)$Resample
> train<-iris[idx,]
> test<-iris[-idx,]
> prop.table(table(train$Species))

    setosa versicolor  virginica 
 0.3333333  0.3333333  0.3333333 
> prop.table(table(test$Species))

    setosa versicolor  virginica 
 0.3333333  0.3333333  0.3333333 
> prop.table(table(iris$Species))

    setosa versicolor  virginica 
 0.3333333  0.3333333  0.3333333 
> 
> #利用createFolds(),createMultiFolds()划分数据集
> library(rpart)
> index<-createFolds(iris$Species,k=5,list=FALSE,returnTrain=FALSE)
> str(index)
 int [1:150] 1 4 2 4 2 5 1 4 3 1 ...
> e0=rep(0,5);e1=e0
> set.seed(137)
> for (i in 1:5) {
+   train<-iris[!index==i,]
+   test<-iris[index==i,]
+   fit<-rpart(Species~.,data=train)
+   e0[i]=sum(predict(fit,train,type='class')== train$Species)/nrow(train)
+   e1[i]=sum(predict(fit,test,type='class')== test$Species)/nrow(test)
+   }
> 
> mean(e0) ;sd(e0)
[1] 0.965
[1] 0.009128709
> mean(e1);sd(e1)
[1] 0.9333333
[1] 0.03333333
> 
> 
> index<-createMultiFolds(iris$Species,k=5,times=3)
> str(index)
List of 15
 $ Fold1.Rep1: int [1:120] 1 3 4 5 6 8 9 10 11 12 ...
 $ Fold2.Rep1: int [1:120] 1 2 3 6 7 8 10 12 13 14 ...
 $ Fold3.Rep1: int [1:120] 1 2 3 4 5 6 7 9 10 11 ...
 $ Fold4.Rep1: int [1:120] 2 4 5 7 8 9 10 11 12 15 ...
 $ Fold5.Rep1: int [1:120] 1 2 3 4 5 6 7 8 9 11 ...
 $ Fold1.Rep2: int [1:120] 1 2 3 4 5 6 7 8 9 10 ...
 $ Fold2.Rep2: int [1:120] 3 4 5 6 7 8 9 11 13 14 ...
 $ Fold3.Rep2: int [1:120] 1 2 5 6 7 8 9 10 11 12 ...
 $ Fold4.Rep2: int [1:120] 1 2 3 4 5 8 9 10 12 13 ...
 $ Fold5.Rep2: int [1:120] 1 2 3 4 6 7 10 11 12 13 ...
 $ Fold1.Rep3: int [1:120] 1 2 4 5 6 7 8 9 10 13 ...
 $ Fold2.Rep3: int [1:120] 1 2 3 4 5 6 7 10 11 12 ...
 $ Fold3.Rep3: int [1:120] 1 3 5 6 7 8 9 11 12 13 ...
 $ Fold4.Rep3: int [1:120] 1 2 3 4 6 8 9 10 11 12 ...
 $ Fold5.Rep3: int [1:120] 2 3 4 5 7 8 9 10 11 12 ...
> e0=rep(0,15);e1=e0
> set.seed(137)
> times=3
> k=5
> for (j in 1:times) {
+   for (i in 1:k) {
+     train_index<-index[[j*times+k]]
+     train<-iris[train_index,]
+     test<-iris[-train_index,]
+     fit<-rpart(Species~.,data=train)
+     e0[j*times+k]=sum(predict(fit,train,type='class')== train$Species)/nrow(train)
+     e1[j*times+k]=sum(predict(fit,test,type='class')== test$Species)/nrow(test)
+ }
+ }
> mean(e0) ;sd(e0)
[1] 0.1927778
[1] 0.3991045
> mean(e1);sd(e1)
[1] 0.1844444
[1] 0.382321

SMOTE(),采用K近邻算法,所以要求数据是数值类型。 

data(iris)
> data<-iris[,c(1,2,5)]
> data$Species<-factor(ifelse(data$Species=='setosa','rare','commom'))
> table(data$Species)

commom   rare 
   100     50 
> 
> newdata<-SMOTE(Species~.,data=data,k=5,perc.over=600,perc.under=100)
> 
> table(newdata$Species)

commom   rare 
   300    350 
> 
  •  不考虑数据属性,随机划分数据集 cvTools::cvFolds()
#cvTools::cvFolds()不考虑数据数据属性,随机划分交叉检验
install.packages('cvTools')
set.seed(719)
library(cvTools)
library(lattice)
library(robustbase)
cv<-cvFolds(nrow(iris),K=10,R=3,type='random')
str(cv)
cv$which[1:20]
head(cv$subsets)
#获取K=1,R=1的检验数据
(test_idx<-cv$subsets[which(cv$which==1),1])
#K=1,R=1的训练数据与检验数据
train<-iris[-test_idx,]
test<-iris[test_idx,]
#反复执行R次K层的交叉检验的全部代码
library(foreach)
set.seed(179)
R=3
K=10
cv<-cvFolds(nrow(iris),K=K,R=R)
foreach(r = 1:R) %do% {
  foreach(k = 1:K,.combine=c) %do% {
    test_idx<-cv$subsets[which(cv$which==k),r]
    test<-iris[test_idx,]
    train<-iris[-test_idx]

    #数据预处理
    
    #模型训练
    
    #预测
    
    #性能评估
    return(性能值)
  }
}
#从foreach()返回值识别性能最优的建模方法
#采用最优建模方法,使用全体数据创建模型
#类失衡数据的处理
#caret::upSample();caret::downSample()
#DMwR::SMOTE()
data(BreastCancer,package='mlbench')
table(BreastCancer$Class)
str(BreastCancer)
x<-upSample(BreastCancer[,1:10],BreastCancer$Class)
table(x$Class)

nrow(x)
nrow(unique(x))#从少数类中抽取更多的数据

#模型比较:使用向上取样对训练集
data<-subset(BreastCancer,select=-Id)
idx<-createDataPartition(data$Class,p=0.8)
train<-data[idx$Resample1,]
test<-data[-idx$Resample1,]
library(party)
m<-ctree(Class~.,data=train)
confusionMatrix(predict(m,test,type='response'),test$Class)

up.train<-upSample(subset(train,select=-Class),train$Class)
m<-ctree(Class~.,data=up.train)
confusionMatrix(predict(m,test,type='response'),test$Class)
table(up.train$Class)

library(DMwR) 
data(iris)
data<-iris[,c(1,2,5)]
data$Species<-factor(ifelse(data$Species=='setosa','rare','commom'))
table(data$Species)

newdata<-SMOTE(Species~.,data=data,k=5,perc.over=600,perc.under=100)

table(newdata$Species)

#cvTools::cvFolds()不考虑数据数据属性,随机划分交叉检验
install.packages('cvTools')
set.seed(719)
library(cvTools)
library(lattice)
library(robustbase)
cv<-cvFolds(nrow(iris),K=1,R=3,type='random')
str(cv)
cv$which[1:20]
head(cv$subsets)
#获取K=1,R=1的检验数据
(test_idx<-cv$subsets[which(cv$which==1),1])
#K=1,R=1的训练数据与检验数据
train<-iris[-test_idx,]
test<-iris[test_idx,]
#反复执行R次K层的交叉检验的全部代码
library(foreach)
?et.seed(179)
R=3
K=10
cv<-cvFolds(nrow(iris),K=K,R=R)
foreach(r = 1:R) %do% {
  foreach(k = 1:K,.combine=c) %do% {
    test_idx<-cv$subsets[which(cv$which==k),r]
    test<-iris[test_idx,]
    train<-iris[-test_idx]

    #数据预处理
    
    #模型训练
    
?   #预测
    
    #性能评估
    return(性能值)
  }
}
#从foreach()返回值识别性能最优的建模方法
#采用最优建模方法,使用全体数据创建模型

猜你喜欢

转载自blog.csdn.net/baibingbingbing/article/details/81323484