R: Рекодирование, категорическое для Numeri c, лишает возможности применять модель к новым данным - PullRequest
0 голосов
/ 06 апреля 2020

Чтобы использовать случайные леса и c, у которых есть ограничение на количество категорийных значений, которые они могут принять для переменной, решение обычно заключается в перекодировании в цифру c. Например, у меня есть список продуктов, который насчитывает 100 продуктов. Поэтому я перекодирую, используя as.numeri c. Это преобразует яблоко в 1, банан в 2 и т. Д. c. Поскольку я делаю это на этапе сборки, это делается для всех данных обучения, тестирования и проверки, прежде чем я разделю их на эти 3 сегмента, и, следовательно, модель работает отлично. , и я могу оценить тест и данные проверки.

Моя проблема в том, когда я хочу использовать модель на основе новых данных, например, новых клиентов за последние недели. Они не имеют одинаковых категориальных переменных, поэтому, когда я запускаю as.numeri c, он выдает каждое категориальное значение и совершенно новое значение цифр c, не совпадая с исходными значениями чисел c в модели. А также, они могут представить новые продукты, ранее невиданные в модели. Например, мы никогда не продавали апельсин и раньше, и теперь он существует, но в данных обучения нет апельсинов.

Поэтому я сталкиваюсь с 2 проблемами:

1) "Тип предикторов в новых данных не совпадают с предикторами обучения "в случае наличия" оранжевого ".

2) Новые значения цифры c не представляют те же значения категории c в обучении data.

Мне не удалось найти решение этой проблемы с помощью Google. Я пробовал пакеты типа "vtreat", но у них та же проблема.

Есть ли функция package / caret или что-то, что обрабатывает это? Как это сделать?

(Моя ручная опция - создать таблицу поиска для каждого возможного категориального значения в каждом столбце, которое будет ужасно трудоемким для обслуживания, поэтому ищите другие варианты).

Заранее спасибо.

Вот воспроизводимый пример:

library(dplyr)
library(caret)
library(randomForest)

Trn_ID <- c(1:10)
Cust_ID <- c('1','2','3','4','5','5','4','2','1','5')
Subrub <- c('Malvern','Bentleigh','CBD','Ivanhoe','Altona','Altona','Ivanhoe','Bentleigh','Malvern','Altona')
Product <- c('Fish','Apple','Fish','Banana','Bread','Fish','Milk','Apple','Banana','Bread')
Online <- c('Y','N','N','N','Y','Y','Y','N','Y','Y')

df <- data.frame(Trn_ID,Cust_ID,Subrub,Product,Online)

## cleanup
df$Subrub <- as.numeric(df$Subrub)
df$Product <- as.numeric(df$Product)

set.seed(150)
inTrain <- createDataPartition(y=df$Online, p=0.75, list=FALSE)
training <- df[inTrain,]
testing <- df[-inTrain,]
training$Online <- factor(training$Online)
testing$Online <- factor(testing$Online)

model <- randomForest(training$Online ~ ., data=training, ntree=50, mtry=3, importance=TRUE, replace=FALSE) 

print(model)

## new data

Trn_ID <- c(11:14)
Cust_ID <- c('1','2','6','5')
Subrub <- c('Malvern','Bentleigh','Alphington','Altona')
Product <- c('Apple','Fish','Orange','Banana')
Online <- c(NA,NA,NA,NA)

nd <- data.frame(Trn_ID,Cust_ID,Subrub,Product,Online)

## cleanup
nd$Subrub <- as.numeric(nd$Subrub)
nd$Product <- as.numeric(nd$Product)

## score

sd <- predict(model,newdata=nd, type="prob")
...