Могу ли я указать прогнозируемому игнорировать строки с ошибками в R?

У меня есть набор обучающих данных, который я беру (случайным образом) для обучения модели в R.

sampleSize <- floor(0.1 * nrow(trainingDataFrame))
train_index <- sample(seq_len(nrow(trainingDataFrame)), size = sampleSize)
trainDF <- trainingDataFrame[train_index,]
fit <- train(dependentVariable ~ ., data=trainDF,
             trControl = trainControl(method = "cv",number = 10),method="lm")

Затем я использую эту модель для predict значений в отдельном наборе данных тестирования. Однако есть факторное поле, которое для некоторых строк в моем наборе тестовых данных иногда имеет значения, которые не встречались в обучающем наборе из-за того, что я произвольно выбираю для обучающего набора значения. Это приводит к "factor ... has new levels" ошибке.

На самом деле я повторяю этот процесс образец-поезд-прогноз на протяжении нескольких итераций, поэтому каждая запись тестового набора данных, скорее всего, в конечном итоге будет иметь некоторые допустимые прогнозы. Таким образом, для моего варианта использования действительно нормально, если некоторые записи не могут быть predict-совместимы в любой конкретной итерации. Я бы не хотел исключать данную область из обучения модели.

Вместо этого можно ли указать функции predict выдать мне na или другое значение по умолчанию для этих недопустимых строк?


person mjumbewu    schedule 07.08.2018    source источник
comment
Вы могли бы использовать predict с tryCatch или purrr::safely()? Или вы можете получить уровни, присутствующие в обучающем наборе для каждой итерации, и отфильтровать тестовый набор данных перед использованием predict?   -  person Calum You    schedule 08.08.2018


Ответы (1)


Вот возможность.

Ключ в том, чтобы определить вашу собственную predict функцию, которая сравнивает уровни factor переменных из объекта lm с уровнями из newdata. Затем мы predict только для тех наблюдений с совпадающими factor уровнями и возвращаем NA для всех остальных.

Я продемонстрирую использование данных mtcars.

  1. Сначала создадим образцы данных, состоящие из одного числового ответа (mpg) и трех категориальных переменных-предикторов (cyl, gear, carb).

    library(tidyverse)
    df <- mtcars %>%
        select(mpg, cyl, gear, carb) %>%
        mutate_at(vars(-mpg), as.factor)
    
  2. Затем мы обучаем модель на обучающих наборах данных наблюдений, которые имеют только некоторые (но не все) уровни факторов для cyl и gear.

    df.train <- df %>% filter(cyl %in% c(4, 6) & gear %in% c(3, 4))
    
  3. Мы подбираем простую линейную модель.

    fit <- lm(mpg ~ ., data = df.train)
    
  4. Теперь мы определяем пользовательскую функцию, которая разделяет newdata на наблюдения с (1) совпадающими factor уровнями, для которых мы можем predict ответ, и (2) «новыми» уровнями, для которых мы возвращаем NA в качестве ответа.

    factor уровни для всех категориальных переменных хранятся в fit$xlevels как list. Мы используем purrr::imap и purrr::reduce(..., intersect) для определения индексов строк тех наблюдений из newdata, которые имеют совпадающие factor уровни.

    my.predict <- function(fit, newdata) {
        lvls <- fit$xlevels
        idx <- reduce(imap(lvls, ~which(newdata[, .y] %in% .x)), intersect)
        res <- rep(NA, nrow(newdata))
        res[idx] <- predict(fit, newdata = newdata[idx, ])
        return(res)
    }
    
  5. Мы подтверждаем результаты по полному набору данных df:

    df$pred <- my.predict(fit, df)
    df
    #    mpg cyl gear carb  pred
    #1  21.0   6    4    4 19.75
    #2  21.0   6    4    4 19.75
    #3  22.8   4    4    1 29.10
    #4  21.4   6    3    1 19.75
    #5  18.7   8    3    2    NA
    #6  18.1   6    3    1 19.75
    #7  14.3   8    3    4    NA
    #8  24.4   4    4    2 24.75
    #9  22.8   4    4    2 24.75
    #10 19.2   6    4    4 19.75
    #11 17.8   6    4    4 19.75
    #12 16.4   8    3    3    NA
    #13 17.3   8    3    3    NA
    #14 15.2   8    3    3    NA
    #15 10.4   8    3    4    NA
    #16 10.4   8    3    4    NA
    #17 14.7   8    3    4    NA
    #18 32.4   4    4    1 29.10
    #19 30.4   4    4    2 24.75
    #20 33.9   4    4    1 29.10
    #21 21.5   4    3    1 21.50
    #22 15.5   8    3    2    NA
    #23 15.2   8    3    2    NA
    #24 13.3   8    3    4    NA
    #25 19.2   8    3    2    NA
    #26 27.3   4    4    1 29.10
    #27 26.0   4    5    2    NA
    #28 30.4   4    5    2    NA
    #29 15.8   8    5    4    NA
    #30 19.7   6    5    6    NA
    #31 15.0   8    5    8    NA
    #32 21.4   4    4    2 24.75
    
person Maurits Evers    schedule 08.08.2018
comment
Многообещающе! Я попробую это завтра - person mjumbewu; 08.08.2018