Вопрос или проблема
У меня возникла следующая проблема: когда я обучал свою модель, я создал фиктивные переменные (до разделения на тренировочную и тестовую выборки) следующим образом:
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
Эта ошибка свидетельствует о том, что фактор, к которому вы попытались применить контрасты, имеет только один уровень в новых данных. Это может произойти, если в ваших тренировочных данных были категории, которые отсутствуют в новом единичном наблюдении.
Решение
Для успешной обработки новой записи и избежания подобных ошибок вы можете следовать следующей стратегии:
-
Сохранение метаданных о факторах: При использовании
dummyVars
, важно сохранить информацию о уровнях факторов из обучающей выборки. Это гарантирует, что даже если определённый уровень не присутствует в новом наборе данных, он будет обработан корректно. -
Использование сохранённых дамми-переменных: Убедитесь, что вы используете заранее созданный и сохранённый объект
dummyVars
, чтобы преобразования соответствовали тем, которые были применены к тренировочному набору данных. -
Инициализация отсутствующих переменных: Если любой уровень фактора в новых данных не присутствует, эта ситуация может быть корректно обработана инициализацией соответствующих дамми-переменных нулями.
Пример кода:
# Чтение сохранённого объекта 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, и спокойно применять свой обученный модельный алгоритм на новых данных.