如何在火车集中重复少数 class 行?

How can I repeat rows of minority class in train set?

我想在我的训练集中重复我的少数 class 的特定行。我知道,这不是一个很花哨的工作方式,但我只是想尝试一下。

假设,我有这个数据框:

> 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

现在我想重复我的少数 class (class4) 行很多次,我有 50% 的 class1 和 50% 的 class4 在新数据框中。

我知道有函数 rep,但我只能找到重复整个数据帧的解决方案。

我该怎么做?

这是一个使用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

基础 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 

我建议您使用 "Synthetic minority over-sampling technique (SMOTE)"(Chawla 等人,2002 年)或 "Randomly Over Sampling Examples (ROSE)"(Menardi 和 Torelli,2013 年)。

1) 您可以通过在 trainControl.

中添加 sampling= 来调整每个交叉验证折叠中的采样

例如:

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

2) 或者,通过调用 SMOTEROSE 在训练前调整采样函数。

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