Фиктивные переменные для невидимых данных в R

Вопрос или проблема

У меня возникла следующая проблема: когда я обучал свою модель, я создал фиктивные переменные (до разделения на тренировочную и тестовую выборки) следующим образом:

dummy <- dummyVars(formula = CLASS_INV ~ ., data = campaign_spending_final_imputed, fullRank = TRUE)
dummy %>% saveRDS('model/dummy.rds') #Я сохраняю это, чтобы использовать позже
campaign_spending_final_dummy <- predict(dummy, newdata = campaign_spending_final_imputed) %>% as.data.frame() %>%
  mutate(CLASS_INV = campaign_spending_final$CLASS_INV)

Модель была успешно обучена и протестирована. Теперь я хочу протестировать её на ‘реальных’ данных и мне нужно создать фиктивные переменные из одной новой записи. Вот что я попробовал сделать:

dummy_inv <- readRDS('model/dummy_inv.rds') #Файл, который я сохранил ранее
predict(dummy_inv,single_record)

У отдельной записи есть те же характеристики, что и у обучающего и тестового наборов данных, это только одна строка.
Однако, когда я выполняю функцию predict, появляется следующая ошибка:

Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) : 
  contrasts can be applied only to factors with 2 or more levels

Я правильно поступаю? Нужно ли мне создать новый объект dummyVars? Не нужно ли использовать тот, который был адаптирован к моим тренировочным данным?
Спасибо

Я немного опоздал, но так как у меня была такая же проблема, вот как я её решил.

Это не самый элегантный способ, но я просто создал новые столбцы для всех фиктивных переменных, созданных с функцией dummyVars(), и затем заполнил значения вручную.

Так что если “df” – это наш новый набор данных, а x_train – это тот, который мы создали с помощью функции dummyVars(), я использовал:

    existing_cols <- names(x_train)[names(x_train) %in% names(df)]
    new_cols <- names(x_train)[!names(x_train) %in% names(df)]
    df[new_cols] <- 0
    nomvars <- c("cp", "ca", "thal", "restecg", "slope")

    for (i in 1:nrow(df)){
      for(j in 1:length(nomvars)){
        df[i,paste0(nomvars[j],df[nomvars[j]][i])] <- 1 
      }
    }

    df <- df[,names(df) %in% c(existing_cols, new_cols)]

Ответ или решение

Если вы столкнулись с проблемой создания дамми-переменных для новых данных в R, следуя указанной методике, то, вероятно, вы уже обнаружили, что это может вызывать определённые сложности. Преждевременное создание дамми-переменных перед разделением данных на обучающую и тестовую выборки может привести к несовпадениям при предсказании на новых, ранее не виданных данных.

Итак, давайте разберёмся, что произошло и как исправить ситуацию.

Проблема

Вы создали дамми-переменные, используя dummyVars на полном наборе данных, а затем обучили модель на этих переменных. Однако, когда вы попытались применить ту же трансформацию к новому наблюдению, возникла ошибка:

Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) : 
contrasts can be applied only to factors with 2 or more levels

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

Решение

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

  1. Сохранение метаданных о факторах: При использовании dummyVars, важно сохранить информацию о уровнях факторов из обучающей выборки. Это гарантирует, что даже если определённый уровень не присутствует в новом наборе данных, он будет обработан корректно.

  2. Использование сохранённых дамми-переменных: Убедитесь, что вы используете заранее созданный и сохранённый объект dummyVars, чтобы преобразования соответствовали тем, которые были применены к тренировочному набору данных.

  3. Инициализация отсутствующих переменных: Если любой уровень фактора в новых данных не присутствует, эта ситуация может быть корректно обработана инициализацией соответствующих дамми-переменных нулями.

Пример кода:

# Чтение сохранённого объекта dummyVars
dummy_inv <- readRDS('model/dummy.rds')

# Функция предсказания с учетом новых значений
dummy_new_data <- predict(dummy_inv, newdata = single_record) %>% as.data.frame()

# Создание недостающих переменных
existing_cols <- names(dummy_new_data)[names(dummy_new_data) %in% names(single_record)]
new_cols <- names(dummy_new_data)[!names(dummy_new_data) %in% names(single_record)]
single_record[new_cols] <- 0

# Применяем факторные уровни для каждой номинальной переменной
nomvars <- c("cp", "ca", "thal", "restecg", "slope")

for (i in 1:nrow(single_record)){
  for (j in 1:length(nomvars)){
    single_record[i, paste0(nomvars[j], single_record[nomvars[j]][i])] <- 1 
  }
}

# Убедимся, что новый набор данных содержит все нужные столбцы
single_record <- single_record[, names(single_record) %in% c(existing_cols, new_cols)]

Заключение

Таким образом, корректное управление дамми-переменными при работе с новыми данными требует учёта всех возможных уровней факторов и раннего сохранения необходимой информации о факторных переменных. Применив предложенное решение, вы сможете избавиться от ошибок, связанных с несовпадающими уровнями факторов в R, и спокойно применять свой обученный модельный алгоритм на новых данных.

Оцените материал
Добавить комментарий

Капча загружается...