首页 文章

如何使用样本函数将数据拆分为训练/测试集

提问于
浏览
118

我刚刚开始使用R,我不知道如何将我的数据集与以下示例代码合并:

sample(x, size, replace = FALSE, prob = NULL)

我有一个数据集,我需要进行培训(75%)和测试(25%)设置 . 我不确定我应该把什么信息放入x和大小? x是数据集文件,并确定了我有多少个样本?

19 回答

  • -2

    有许多方法可以实现数据分区 . 有关更完整的方法,请查看 caret 包中的 createDataPartition 函数 .

    这是一个简单的例子:

    data(mtcars)
    
    ## 75% of the sample size
    smp_size <- floor(0.75 * nrow(mtcars))
    
    ## set the seed to make your partition reproducible
    set.seed(123)
    train_ind <- sample(seq_len(nrow(mtcars)), size = smp_size)
    
    train <- mtcars[train_ind, ]
    test <- mtcars[-train_ind, ]
    
  • 1

    它可以通过以下方式轻松完成:

    set.seed(101) # Set Seed so that same sample can be reproduced in future also
    # Now Selecting 75% of data as sample from total 'n' rows of the data  
    sample <- sample.int(n = nrow(data), size = floor(.75*nrow(data)), replace = F)
    train <- data[sample, ]
    test  <- data[-sample, ]
    

    使用caTools包:

    require(caTools)
    set.seed(101) 
    sample = sample.split(data$anycolumn, SplitRatio = .75)
    train = subset(data, sample == TRUE)
    test  = subset(data, sample == FALSE)
    
  • 23

    这几乎是相同的代码,但更好看

    bound <- floor((nrow(df)/4)*3)         #define % of training and test set
    
    df <- df[sample(nrow(df)), ]           #sample rows 
    df.train <- df[1:bound, ]              #get training set
    df.test <- df[(bound+1):nrow(df), ]    #get test set
    
  • 5

    我会使用 dplyr ,这使它变得非常简单 . 它确实需要数据集中的id变量,这无论如何都是一个好主意,不仅用于创建集合,还用于项目期间的可跟踪性 . 如果不包含它,请添加它 .

    mtcars$id <- 1:nrow(mtcars)
    train <- mtcars %>% dplyr::sample_frac(.75)
    test  <- dplyr::anti_join(mtcars, train, by = 'id')
    
  • 26

    我会把'a'分成火车(70%)和测试(30%)

    a # original data frame
        library(dplyr)
        train<-sample_frac(a, 0.7)
        sid<-as.numeric(rownames(train)) # because rownames() returns character
        test<-a[-sid,]
    

    DONE

  • 3
    library(caret)
    intrain<-createDataPartition(y=sub_train$classe,p=0.7,list=FALSE)
    training<-m_train[intrain,]
    testing<-m_train[-intrain,]
    
  • 2

    我的解决方案与dickoa基本相同,但更容易理解:

    data(mtcars)
    n = nrow(mtcars)
    trainIndex = sample(1:n, size = round(0.7*n), replace=FALSE)
    train = mtcars[trainIndex ,]
    test = mtcars[-trainIndex ,]
    
  • 0

    如果您输入:

    ?sample
    

    如果将启动帮助菜单来解释样本函数的参数含义 .

    我不是专家,但这里有一些代码:

    data <- data.frame(matrix(rnorm(400), nrow=100))<br>
    splitdata <- split(data[1:nrow(data),],sample(rep(1:4,as.integer(nrow(data)/4))))<br>
    test <- splitdata[[1]]<br>
    train <- rbind(splitdata[[1]],splitdata[[2]],splitdata[[3]])<br>
    

    这将为您提供75%的火车和25%的测试 .

  • 73

    我的解决方案将行洗牌,然后将前75%的行作为列车,将最后25%作为测试 . 超级简单!

    row_count <- nrow(orders_pivotted)
    shuffled_rows <- sample(row_count)
    train <- orders_pivotted[head(shuffled_rows,floor(row_count*0.75)),]
    test <- orders_pivotted[tail(shuffled_rows,floor(row_count*0.25)),]
    
  • 16

    在创建 list of sub-samples of the same size 的函数下面,这不是您想要的,但可能对其他人有用 . 在我的例子中,在较小的样本上创建多个分类树以测试过度拟合:

    df_split <- function (df, number){
      sizedf      <- length(df[,1])
      bound       <- sizedf/number
      list        <- list() 
      for (i in 1:number){
        list[i] <- list(df[((i*bound+1)-bound):(i*bound),])
      }
      return(list)
    }
    

    示例:

    x <- matrix(c(1:10), ncol=1)
    x
    # [,1]
    # [1,]    1
    # [2,]    2
    # [3,]    3
    # [4,]    4
    # [5,]    5
    # [6,]    6
    # [7,]    7
    # [8,]    8
    # [9,]    9
    #[10,]   10
    
    x.split <- df_split(x,5)
    x.split
    # [[1]]
    # [1] 1 2
    
    # [[2]]
    # [1] 3 4
    
    # [[3]]
    # [1] 5 6
    
    # [[4]]
    # [1] 7 8
    
    # [[5]]
    # [1] 9 10
    
  • 2

    在R示例代码中使用caTools包将如下: -

    data
    split = sample.split(data$DependentcoloumnName, SplitRatio = 0.6)
    training_set = subset(data, split == TRUE)
    test_set = subset(data, split == FALSE)
    
  • 2

    使用基数R.函数 runif 生成从0到1的均匀分布值 . 通过变化的截止值(下面的示例中为train.size),您将始终在截止值以下具有大致相同的随机记录百分比 .

    data(mtcars)
    set.seed(123)
    
    #desired proportion of records in training set
    train.size<-.7
    #true/false vector of values above/below the cutoff above
    train.ind<-runif(nrow(mtcars))<train.size
    
    #train
    train.df<-mtcars[train.ind,]
    
    
    #test
    test.df<-mtcars[!train.ind,]
    
  • 18

    使用awesome dplyr 库只是一个更简单,更简单的方法:

    library(dplyr)
    set.seed(275) #to get repeatable data
    
    data.train <- sample_frac(Default, 0.7)
    
    train_index <- as.numeric(rownames(data.train))
    data.test <- Default[-train.index, ]
    
  • 14
    require(caTools)
    
    set.seed(101)            #This is used to create same samples everytime
    
    split1=sample.split(data$anycol,SplitRatio=2/3)
    
    train=subset(data,split1==TRUE)
    
    test=subset(data,split1==FALSE)
    

    sample.split() 函数将向数据帧添加一个额外的列'split1',其中2/3的行将此值设置为TRUE而其他行将为FALSE . 否则,split1为TRUE的行将被复制到train中,其他行将被复制到测试数据帧 .

  • 1

    我建议使用rsample包:

    # choosing 75% of the data to be the training data
    data_split <- initial_split(data, prop = .75)
    # extracting training data and test data as two seperate dataframes
    data_train <- training(data_split)
    data_test  <- testing(data_split)
    
  • 2

    假设 df 是您的数据框,并且您要创建 75% train25% test

    all <- 1:nrow(df)
    train_i <- sort(sample(all, round(nrow(df)*0.75,digits = 0),replace=FALSE))
    test_i <- all[-train_i]
    

    然后创建一个列车并测试数据帧

    df_train <- df[train_i,]
    df_test <- df[test_i,]
    
  • 0

    如果您寻找可重现的结果,请注意 sample 以进行拆分 . 如果您的数据稍有变化,即使您使用 set.seed ,分割也会有所不同 . 例如,假设您数据中已排序的ID列表是1到10之间的所有数字 . 如果您只丢弃一个观察值,例如4,按位置采样会产生不同的结果,因为现在5到10个所有移动的位置 .

    另一种方法是使用散列函数将ID映射到一些伪随机数,然后对这些数字的mod进行采样 . 此样本更稳定,因为分配现在由每个观察的散列决定,而不是由其相对位置决定 .

    例如:

    require(openssl)  # for md5
    require(data.table)  # for the demo data
    
    set.seed(1)  # this won't help `sample`
    
    population <- as.character(1e5:(1e6-1))  # some made up ID names
    
    N <- 1e4  # sample size
    
    sample1 <- data.table(id = sort(sample(population, N)))  # randomly sample N ids
    sample2 <- sample1[-sample(N, 1)]  # randomly drop one observation from sample1
    
    # samples are all but identical
    sample1
    sample2
    nrow(merge(sample1, sample2))
    

    [1] 9999

    # row splitting yields very different test sets, even though we've set the seed
    test <- sample(N-1, N/2, replace = F)
    
    test1 <- sample1[test, .(id)]
    test2 <- sample2[test, .(id)]
    nrow(test1)
    

    [1] 5000

    nrow(merge(test1, test2))
    

    [1] 2653

    # to fix that, we can use some hash function to sample on the last digit
    
    md5_bit_mod <- function(x, m = 2L) {
      # Inputs: 
      #  x: a character vector of ids
      #  m: the modulo divisor (modify for split proportions other than 50:50)
      # Output: remainders from dividing the first digit of the md5 hash of x by m
      as.integer(as.hexmode(substr(openssl::md5(x), 1, 1)) %% m)
    }
    
    # hash splitting preserves the similarity, because the assignment of test/train 
    # is determined by the hash of each obs., and not by its relative location in the data
    # which may change 
    test1a <- sample1[md5_bit_mod(id) == 0L, .(id)]
    test2a <- sample2[md5_bit_mod(id) == 0L, .(id)]
    nrow(merge(test1a, test2a))
    

    [1] 5057

    nrow(test1a)
    

    [1] 5057

    样本大小不完全是5000,因为赋值是概率性的,但由于大数定律,它在大样本中不应该成为问题 .

    另见:http://blog.richardweiss.org/2016/12/25/hash-splits.htmlhttps://crypto.stackexchange.com/questions/20742/statistical-properties-of-hash-functions-when-calculating-modulo

  • 189
    set.seed(123)
    llwork<-sample(1:length(mydata),round(0.75*length(mydata),digits=0)) 
    wmydata<-mydata[llwork, ]
    tmydata<-mydata[-llwork, ]
    
  • 1

    有一种非常简单的方法可以使用行索引和列的R索引来选择多行 . 这使您可以在给定多行的情况下清理分割数据集 - 比如说您的数据的前80% .

    在R中,所有行和列都被编入索引,因此DataSetName [1,1]是分配给第一列和“DataSetName”的第一行的值 . 我可以使用[,x]和[,x]列选择行

    例如:如果我有一个方便地命名为“data”且100行的数据集,我可以使用查看前80行

    查看(数据[1:80,])

    以同样的方式,我可以使用以下选择这些行并对它们进行子集化

    train = data [1:80,] test = data [81:100,]

    现在我将我的数据分成两部分而不可能重新采样 . 快捷方便 .

相关问题