我有不平衡的数据,比方说:2%的错误和98%的良好。
我现在想做的是重复不良的课堂,直到我达到(例如)70%的坏关系和30%的良好关系。
我知道这是一种非常不寻常的方法(我已经尝试过SMOTE),但我只是对结果感到好奇。
我将使用这些数据在其上应用决策树。
示例数据:
> df
class percentage color
bad 0.45 green
bad 0.67 red
bad 0.34 blue
good 0.22 black
good 0.25 pink
good 0.89 green
good 0.76 yellow
good 0.35 grey
good 0.44 red
good 0.99 red
good 0.12 blue
good 0.56 black
good 0.70 pink
good 0.49 yellow
输出为:
> df
class percentage color
bad 0.45 green
bad 0.67 red
bad 0.34 blue
bad 0.45 green
bad 0.67 red
bad 0.34 blue
bad 0.67 red
bad 0.34 blue
bad 0.45 green
bad 0.45 green
bad 0.67 red
bad 0.34 blue
bad 0.45 green
bad 0.67 red
bad 0.34 blue
bad 0.45 green
bad 0.67 red
bad 0.34 blue
bad 0.45 green
bad 0.67 red
bad 0.34 blue
bad 0.45 green
bad 0.67 red
bad 0.34 blue
good 0.22 black
good 0.25 pink
good 0.89 green
good 0.76 yellow
good 0.35 grey
good 0.44 red
good 0.99 red
good 0.12 blue
good 0.56 black
good 0.70 pink
good 0.49 yellow
答案 0 :(得分:1)
不确定这是否是最有效的方法,但它应该可以工作:
false
答案 1 :(得分:1)
首先,我想你应该避免这种情况,因为你可能会得到一个非代表性的事实样本。
实际上,您只复制了这3种情况。 SMOTE
应该是重新平衡事物的更好方法。
无论如何,这是一种方法:
do.call("rbind", replicate(n_bad, d_bad, simplify = FALSE))
最主要的是,这条线复制了糟糕的情况。
library(dplyr)
# we set some parameters that you can play with
n_rows_final <- 100
perc_bad <- 0.7
bad_cases <- nrow(d %>% filter(class=="bad"))
n_bad <- (n_rows_final*perc_bad)/bad_cases # nrows final * desired perc bad
n_good <- (n_rows_final*(1-perc_bad)) # nrows final * desired perc good
# filter the original data
d_bad <- d %>% filter(class=="bad")
d_good <- d %>% filter(class=="good")
set.seed(123)
d_good <- d_good[sample(n_good), ] # sample n_good cases
d_bad <- do.call("rbind", replicate(n_bad, d_bad, simplify = FALSE)) # replicates bad cases n_bad times
d_final <- rbind(d_bad, d_good) # binds
table(d_final$class)
# bad good
# 69 11
数据:
tt <- "class percentage color
bad 0.45 green
bad 0.67 red
bad 0.34 blue
good 0.22 black
good 0.25 pink
good 0.89 green
good 0.76 yellow
good 0.35 grey
good 0.44 red
good 0.99 red
good 0.12 blue
good 0.56 black
good 0.70 pink
good 0.49 yellow"
d <- read.table(text=tt, header=T)
答案 2 :(得分:1)
您可以尝试
library(tidyverse)
set.seed(134)
d %>%
group_by(class) %>%
sample_n(size = 100, replace = T) %>%
split(.$class) %>%
map2(.,c(0.3, 0.7), ~mutate(.x, gr=sample(c(TRUE, FALSE), size = n(), replace = T, prob = c(1-.y, .y)))) %>%
bind_rows() %>%
ungroup() %>%
filter(gr) %>%
select(-gr)
# A tibble: 101 x 3
class percentage color
<fct> <dbl> <fct>
1 bad 0.45 green
2 bad 0.34 blue
3 bad 0.34 blue
4 bad 0.67 red
5 bad 0.67 red
6 bad 0.34 blue
7 bad 0.45 green
8 bad 0.34 blue
9 bad 0.67 red
10 bad 0.34 blue
# ... with 91 more rows
.Last.value %>%
count(class)
# A tibble: 2 x 2
class n
<fct> <int>
1 bad 71
2 good 28
想法是将两个组的样本采样到相同的大小(此处为100,但您可以增加到100。)。然后添加具有相应概率70:30的过滤器变量gr
。