Как я могу повторить ряды класса меньшинства в наборе поездов? - PullRequest
0 голосов
/ 22 октября 2018

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

Предположим, у меня есть этот фрейм данных:

> df

    group     type  number
1   class1     one    4
2   class1   three   10
3   class1    nine    3
4   class4   seven    9
5   class1   eight    4
6   class1     ten    2
7   class1     two   22
8   class4  eleven    8

Теперь я хочу повторитьСтрока моего класса меньшинства (class4) так много раз, что у меня есть 50% class1 и 50% class4 в новом фрейме данных.

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

Как я могу это сделать?

Ответы [ 3 ]

0 голосов
/ 22 октября 2018

Базовый подход R

#Count frequency of groups
tab <- table(df$group)

#Count number of rows to be added
no_of_rows <- max(tab) - min(tab)

#count number of rows which are already there in the dataframe for the minimum group
existing_rows <- which(df$group %in% names(which.min(tab)))

#Add new rows
new_df <- rbind(df, df[rep(existing_rows,no_of_rows/length(existing_rows)), ])

#Check the count
table(new_df$group)

#class1 class4 
#     6      6 
0 голосов
/ 22 октября 2018

Я бы предложил вам использовать «Технику избыточной выборки синтетического меньшинства ( SMOTE )» (Chawla et al. 2002) или «Примеры случайной выборки ( ROSE )» (Menardiи Torelli, 2013).

1) Вы можете отрегулировать выборку в каждом сечении перекрестной проверки, добавив sampling= в trainControl.

Например:

trainControl(method = "repeatedcv", 
                     number = 10, 
                     repeats = 10, 
                     sampling = "up")

2) Или, отрегулировав выборку перед тренировкой, вызвав функции SMOTE и ROSE .

library("DMwR") #for smote
library("ROSE")

dat <- iris[1:70,]
dat$Species <- factor(dat$Species)

table(dat$Species) #class imbalances

setosa versicolor 
    50         20     

set.seed(100)
smote_train <- SMOTE(Species ~ ., data  = dat)                         
table(smote_train$Species)

setosa versicolor 
    80         60 


set.seed(100)
rose_train <- ROSE(Species ~ ., data  = dat)$data    
table(rose_train$Species)


setosa versicolor 
    37         33 
0 голосов
/ 22 октября 2018

Вот вариант с использованием tidyverse

library(tidyverse)
n1 <- df %>% 
        count(group) %>% 
        slice(which.max(n)) %>%
        pull(n) 
df %>%
   filter(group == "class4") %>%
   mutate(n = n1/2) %>% 
   uncount(n) %>%
   bind_rows(filter(df, group == "class1"))
#    group   type number
#1  class4  seven      9
#2  class4  seven      9
#3  class4  seven      9
#4  class4 eleven      8
#5  class4 eleven      8
#6  class4 eleven      8
#7  class1    one      4
#8  class1  three     10
#9  class1   nine      3
#10 class1  eight      4
#11 class1    ten      2
#12 class1    two     22
...