SMOTE in r значительно уменьшает размер выборки

У меня есть набор данных около 130000 записей. Записи делятся на два класса целевой переменной,0 и 1. 1 содержит только 0,09% от общей доли.

Я выполняю анализ в R-3.5.1 в Windows 10. Я использовал алгоритм SMOTE для работы с этим несбалансированным набором данных.

Я использовал следующий код для обработки несбалансированного набора данных

library(DMwR)
data_code$target=as.factor(data_code$target) #Converted to factor as 
# SMOTE works with factor data type
smoted_data <- SMOTE(target~., data_code, perc.over=100)

Но после выполнения кода я вижу, что счетчик 0 равен 212, а 1 также равен 212, что является значительным уменьшением размера моей выборки. Можете ли вы предложить мне, как мне обрабатывать этот несбалансированный набор данных с помощью SMOTE без изменения размера данных

1 ответ

Решение

Вам нужно немного поиграть с двумя параметрами, доступными из функции: perc.over а также perc.under,

Согласно документу от SMOTE:

Параметры perc.over и perc.under управляют количеством избыточной выборки для класса меньшинства и недостаточной выборки для большинства классов соответственно.

Так:

perc.over, как правило, будет числом выше 100. При значениях этого типа для каждого случая в наборе исходных данных, принадлежащих к классу меньшинства, в perc.over/100 будут создаваться новые примеры этого класса.

Я не могу видеть ваши данные, но, если ваш класс меньшинства имеет 100 случаев и perc.over=100 алгоритм сгенерирует 100/100 = 1 новых случаев из этого класса.

Параметр perc.under контролирует долю случаев класса большинства, которые будут случайным образом выбраны для окончательного "сбалансированного" набора данных. Эта пропорция рассчитывается по отношению к числу вновь сгенерированных случаев меньшинства.

Так, например, значение perc.under=100 выберет из класса большинства на исходных данных то же количество наблюдений, которое было сгенерировано для класса меньшинства.

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

Я предлагаю использовать значения выше 100 для perc.over и еще более высокое значение для perc.under (по умолчанию 100 и 200).

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

Числовой пример:

set.seed(123)

data <- data.frame(var1 = sample(50),
                   var2 = sample(50),
                   out = as.factor(rbinom(50, 1, prob=0.1)))

table(data$out)
#  0  1 
# 43  7 # 50 rows total (original data)
smote_data <- DMwR::SMOTE(out ~ var1, data, perc.over = 200, perc.under = 400)
table(smote_data$out)
#  0  1 
# 56 21 # 77 rows total (smote data)

Я знаю, что слишком поздно отвечать на ваш вопрос, но надеюсь, что этот ответ поможет другим! Используемый вами пакетDMwRкоторый использует комбинацию SMOTE и недостаточную выборку класса большинства.

Я бы посоветовал вам использовать smotefamily::SMOTE поскольку это только выборка класса меньшинства, поэтому вы не потеряете свои наблюдения класса большинства.

Альтернатива DMwR пакет это smotefamilyпакет, не уменьшающий размер выборки.

Вместо этого он создает дополнительные данные (= синтезированные данные) из класса меньшинства и добавляет их к исходным данным. Итак, вывод в$dataаргумент готов к обучению. Чтобы настроить объем синтезируемых данных, вы можете изменить параметрdup_size. Однако по умолчаниюdup_size = 0 уже оптимизирует вывод для достижения сбалансированных классов, поэтому вам не нужно его настраивать.

Это подробно объясняется в этой записи блога Ричарда Ричарда.

Пример кода (с функциями в первых двух столбцах):

smote1 <- smotefamily::SMOTE(features, target, K = 4, dup_size = 0)
formula1 <- "class ~ ." %>% as.formula
model.smote <- caret::train(formula1, method = "rpart", smote1$data)
predictions.smote <- predict(model.smote, smote1$data[,1:2]) %>% print
cv2 <- confusionMatrix(smote1$data$class %>% as.factor, predictions.smote)

Я нахожу smotefamily::SMOTE удобнее, потому что вам не нужно настраивать два параметра perc_over а также perc_under пока вы не получите приемлемый размер выборки, а DMwR::SMOTE часто генерирует значения NA.

Другие вопросы по тегам