2013-05-11 1 views
4

Я написал небольшую функцию для разделения моего набора данных на обучающие и тестовые наборы. Тем не менее, я столкнулся с трудностями при работе с факторными переменными. На этапе проверки модели моего кода я получаю сообщение об ошибке, если модель была построена на наборе данных, который не имеет представления с каждого уровня фактора. Как я могу исправить эту функцию partition(), чтобы включить хотя бы одно наблюдение с каждого уровня фактор-переменной?Как я могу обеспечить, чтобы раздел имел репрезентативные наблюдения с каждого уровня фактора?

test.df <- data.frame(a = sample(c(0,1),100, rep = T), 
         b = factor(sample(letters, 100, rep = T)), 
         c = factor(sample(c("apple", "orange"), 100, rep = T))) 

set.seed(123) 
partition <- function(data, train.size = .7){ 
    train <- data[sample(1:nrow(data), round(train.size*nrow(data)), rep= FALSE), ] 
    test <- data[-as.numeric(row.names(train)), ] 
    partitioned.data <- list(train = train, test = test) 
    return(partitioned.data) 
} 

part.data <- partition(test.df) 
table(part.data$train[,'b']) 
table(part.data$test[,'b']) 

EDIT - Новая функция использования 'каретка' пакет и createDataPartition():

partition <- function(data, factor=NULL, train.size = .7){ 
    if (("package:caret" %in% search()) == FALSE){ 
    stop("Install and Load 'caret' package") 
    } 
    if (is.null(factor)){ 
    train.index <- createDataPartition(as.numeric(row.names(data)), 
             times = 1, p = train.size, list = FALSE) 
    train <- data[train.index, ] 
    test <- data[-train.index, ] 
    } 
    else{ 
    train.index <- createDataPartition(factor, 
             times = 1, p = train.size, list = FALSE) 
    train <- data[train.index, ] 
    test <- data[-train.index, ] 
    } 
    partitioned.data <- list(train = train, test = test) 
    return(partitioned.data) 
} 
+0

Я знаю, что это не отвечает на ваш вопрос, но разве даже хорошая идея обусловить факторную переменную с таким небольшим количеством наблюдений? Они должны быть очень неточно оценены и могут сделать ваши прогнозы вне образца хуже, чем лучше. – RoyalTS

+0

Вы правы, что это была бы плохая идея. Тем не менее, я бы никогда не использовал эту функцию на таком небольшом наборе данных на практике. Я сделал это маленьким, так что в секционированном test.df в значительной степени гарантировано наличие некоторых факторов с 0 наблюдениями. – zap2008

+0

У меня такая же проблема, но, по-видимому, второе определение функции 'partition' применяется только для одного фактора за раз. Я понял, что ваш вопрос касается наличия раздела в наборе данных «train», который содержит все уровни факторов для входных столбцов: 'b' и' c', но 'createDataPartition' работает только для одного столбца, например:' partition (test.df, factor = test.df [, c ("b", "c")]) 'не работает. –

ответ

4

Попробуйте пакет каретку, в частности, функцию createDataPartition(). Он должен делать то, что вам нужно, доступно на CRAN, домашняя страница находится здесь:

caret - data splitting

Функции я уже частично некоторый код, я нашел некоторое время назад на сетке, а затем я изменил его немного лучше ручку (например, когда вы запрашиваете размер выборки, превышающий набор, или подмножество).

stratified <- function(df, group, size) { 
    # USE: * Specify your data frame and grouping variable (as column 
    # number) as the first two arguments. 
    # * Decide on your sample size. For a sample proportional to the 
    # population, enter "size" as a decimal. For an equal number 
    # of samples from each group, enter "size" as a whole number. 
    # 
    # Example 1: Sample 10% of each group from a data frame named "z", 
    # where the grouping variable is the fourth variable, use: 
    # 
    # > stratified(z, 4, .1) 
    # 
    # Example 2: Sample 5 observations from each group from a data frame 
    # named "z"; grouping variable is the third variable: 
    # 
    # > stratified(z, 3, 5) 
    # 
    require(sampling) 
    temp = df[order(df[group]),] 
    colsToReturn <- ncol(df) 

    #Don't want to attempt to sample more than possible 
    dfCounts <- table(df[group]) 
    if (size > min(dfCounts)) { 
    size <- min(dfCounts) 
    } 



    if (size < 1) { 
    size = ceiling(table(temp[group]) * size) 
    } else if (size >= 1) { 
    size = rep(size, times=length(table(temp[group]))) 
    } 
    strat = strata(temp, stratanames = names(temp[group]), 
       size = size, method = "srswor") 
    (dsample = getdata(temp, strat)) 

    dsample <- dsample[order(dsample[1]),] 
    dsample <- data.frame(dsample[,1:colsToReturn], row.names=NULL) 
    return(dsample) 

} 
+0

Я проверю это. Я слышал об этом раньше, но никогда не использовал его. – zap2008

+0

Дайте мне знать. У меня есть еще одна функция, которую я мог бы дать вам для этого кода. –

+0

было бы неплохо увидеть вашу функцию ... У меня все еще есть проблемы. Я выделил часть createDataPartition(), которая меня путала, но я не уверен, как ее исправить. Это своего рода вопрос о том, «стоит ли строить модель, используя множество факторов только с одним наблюдением?» – zap2008