Как вы справляетесь с применением XGBoost в R? У меня проблема с этим, так как, когда столбец данных категориального типа не содержит всех своих возможных значений (которые учитывает модель), я получаю сообщение об ошибке: «Избранные имена, хранящиеся в object
и newdata
, отличаются».
Я знаю, как обойти эту проблему, подготавливая входные данные другим способом, то есть путем добавления достаточного количества фиктивных переменных, чтобы охватить все возможные значения категориальных переменных, которые я намерен учитывать. Например, если объект FI, который требуется использовать, принимает значения «a», «b» или «c», я создаю модель XGBoost, используя функции is_a, is_b и is_c. Затем, если в моих входных данных, к которым я хочу применить модель, функция F поставляется только со значениями 'b' или 'c', я все еще использую эти 3 функции, и is_c равен 0 при каждом наблюдении.
Но я не хочу этого делать, так как в целом это кажется довольно утомительным, и, кроме того, я не сталкиваюсь с подобными проблемами при использовании разных моделей, например, логистической регрессии с помощью функции glm ().
Итак, мой вопрос: возможно ли применить модель XGBoost к наблюдениям, содержащим категориальные (факторные) переменные с неполными значениями? Incomplete
значение здесь: не все значения, которые учитывает модель.
Я подготовил пример для демонстрации этого случая на основе данных mtcars. Допустим, мы хотим иметь классификационную модель, предсказывающую тип коробки передач (автоматическая или ручная, столбец «am»). Одна из возможных функций - это вес (столбец «вес»), и мы хотим использовать данные о весе в качестве признака типа фактора, а не признака непрерывного типа.
library(xgboost)
library(dplyr)
library(dummies)
##### Example 0: wt as a continuous variable (no errors on data with incomplete values) #####
# Train:
data_train <- mtcars
model_matrix_train <- model.matrix(am ~ ., data = data_train)
xgb_data_train <- xgb.DMatrix(model_matrix_train, label = data_train$am)
param <- list(max_depth = 2, eta = 1, objective = "binary:logistic")
model_xgb <- xgb.train(param, xgb_data_train, nrounds = 100)
# Test on data with incomplete wt values:
data_test <- mtcars %>%
filter(wt < 4)
model_matrix_test <- model.matrix(am ~ ., data = data_test)
xgb_data_test <- xgb.DMatrix(model_matrix_test, label = data_test$am)
predict(model_xgb, newdata = xgb_data_test, type="prob")
##### Example 1: wt as a factor (error on data with incomplete values) #####
# Train:
data_train <- mtcars %>%
mutate(wt = factor(
case_when(
wt < 2 ~ "1_2",
wt < 3 ~ "2_3",
wt < 4 ~ "3_4",
wt < 5 ~ "4_5",
TRUE ~ "5_6"
))
)
model_matrix_train <- model.matrix(am ~ ., data = data_train)
xgb_data_train <- xgb.DMatrix(model_matrix_train, label = data_train$am)
param <- list(max_depth = 2, eta = 1, objective = "binary:logistic")
model_xgb <- xgb.train(param, xgb_data_train, nrounds = 100)
# Test on data with incomplete wt values:
data_test <- mtcars %>%
filter(wt < 4) %>%
mutate(wt = factor(
case_when(
wt < 2 ~ "1_2",
wt < 3 ~ "2_3",
wt < 4 ~ "3_4",
wt < 5 ~ "4_5",
TRUE ~ "5_6"
))
)
model_matrix_test <- model.matrix(am ~ ., data = data_test)
xgb_data_test <- xgb.DMatrix(model_matrix_test, label = data_test$am)
predict(model_xgb, newdata = xgb_data_test, type="prob") # ERROR
Я также пытался использовать фиктивные переменные для всехсоответствующие случаи wt (вместо преобразования wt в факторную переменную). Результат был аналогичен приведенному выше примеру 1:
##### Example 2: wt as a dummy variable (error on data with incomplete values) #####
# Train:
data_train <- mtcars %>%
mutate(wt = factor(
case_when(
wt < 2 ~ "1_2",
wt < 3 ~ "2_3",
wt < 4 ~ "3_4",
wt < 5 ~ "4_5",
TRUE ~ "5_6"
))
)
data_train <- dummy.data.frame(data_train, "wt", sep = "_")
model_matrix_train <- model.matrix(am ~ ., data = data_train)
xgb_data_train <- xgb.DMatrix(model_matrix_train, label = data_train$am)
param <- list(max_depth = 2, eta = 1, objective = "binary:logistic")
model_xgb <- xgb.train(param, xgb_data_train, nrounds = 100)
# Test on data with incomplete wt values:
data_test <- mtcars %>%
filter(wt < 4) %>%
mutate(wt = factor(
case_when(
wt < 2 ~ "1_2",
wt < 3 ~ "2_3",
wt < 4 ~ "3_4",
wt < 5 ~ "4_5",
TRUE ~ "5_6"
))
)
data_test <- dummy.data.frame(data_test, "wt", sep = "_")
model_matrix_test <- model.matrix(am ~ ., data = data_test)
xgb_data_test <- xgb.DMatrix(model_matrix_test, label = data_test$am)
predict(model_xgb, newdata = xgb_data_test, type="prob") # ERROR