2016-09-27 5 views
5

У меня есть dataframe Д.Ф., я строй модели машинного обучения (C5.0 дерева решений), чтобы предсказать класс колонка (loan_approved):Как обрабатывать ошибки в функции прогнозирования R?

структуры (не реальные данные):

id occupation income loan_approved 
1 business 4214214 yes 
2 business 32134 yes 
3 business 43255 no 
4 sailor  5642 yes 
5 teacher 53335 no 
6 teacher 6342 no 

Процесс:

  • я случайным образом разделить кадр данных в тесте и поезд, узнал на поезде набора данных (строки 1,2,3,5,6 тренировать д строка 4 в качестве испытания)
  • Для того, чтобы учесть новые категориальные уровни в одном или многом колонке, я использовал функцию попытки

Функции:

error_free_predict = function(x){ 
    output = tryCatch({ 
    predict(C50_model, newdata = test[x,], type = "class") 
    }, error = function(e) { 
    "no" 
    }) 
    return(output) 
    } 

Прикладных функции предсказывают:

test <- mutate(test, predicted_class = error_free_predict(1:NROW(test))) 

Проблема:

id occupation income loan_approved predicted_class 
1 business 4214214 yes   no 
2 business 32134 yes   no 
3 business 43255 no   no 
4 sailor  5642 yes   no 
5 teacher 53335 no   no 
6 teacher 6342 no   no 

Вопрос:

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

P.S: не использовать sapply, потому что он был слишком медленным

+0

Какая проблема Ваша проблема? Неужели это только возвращение «нет»? Какова ошибка, возвращаемая вызовом 'pred'? – cdeterman

+1

проблема заключается в том, что функция прогнозирования встречает новые уровни факторов в «оккупации» столбца и не работает не только для одной строки, но и обрабатывает весь фрейм данных как неудачный случай. –

+0

Кажется, что вы должны расслоить раскол, чтобы вы имели примерно одинаковое количество каждой категории в каждом расколе. – Aaron

ответ

1

Есть две части этой проблемы.

  1. Первая часть проблемы возникает во время обучения модели, поскольку категориальные переменные не разделяются поровну между поездом и тестом, если вы делаете случайное расщепление. В вашем случае говорят, что у вас есть только одна запись с оккупацией «матрос», тогда вполне возможно, что она закончится в тестовом наборе, когда вы производите раскол. Модель, построенная с использованием набора данных поезда, никогда бы не увидела влияния «матроса» оккупации, и, следовательно, это вызовет ошибку. В более обобщенном случае возможно, что какой-то другой категориальный уровень переменной целиком будет полностью тестироваться после случайного разбиения.

Таким образом, вместо случайного разделения данных между поездом и тестом вы можете сделать стратифицированную выборку. Код, использующий data.table для 70:30 раскола:

ind <- total_data[, sample(.I, round(0.3*.N), FALSE),by="occupation"]$V1 
train <- total_data[-ind,] 
test <- total_data[ind,] 

Это гарантирует, что любой уровень делится поровну между поездом и тестового набора данных. Таким образом, вы не получите «новый» категориальный уровень в тестовом наборе данных; который в случае случайного расщепления мог бы быть там.

  1. Вторая часть проблемы возникает, когда модель находится в производстве, и она встречает совершенно новую переменную, которой не было даже в тренировочном или тестовом наборе. Для решения этой проблемы можно сохранить список всех уровней всех категориальных переменных, используя lvl_cat_var1 <- unique(cat_var1) и lvl_cat_var2 <- unique(cat_var2) и т. Д.Тогда, прежде чем предсказать можно проверить на новый уровень и фильтр:

    new_lvl_data <- total_data[!(var1 %in% lvl_cat_var1 & var2 %in% lvl_cat_var2)] 
    pred_data <- total_data[(var1 %in% lvl_cat_var1 & var2 %in% lvl_cat_var2)] 
    

то для предсказания по умолчанию сделать:

new_lvl_data$predicted_class <- "no" 

и полномасштабного прогноз pred_data.

+0

, вы можете сохранить список всех уровней всех категориальных переменных, используя 'lvl_cat_var1 <- уникальный (cat_var1) '' lvl_cat_var2 <- unique (cat_var2) ', а затем перед предсказанием вы можете проверить новый уровень и фильтр' new_lvl_data <- total_data [! (var1% in% lvl_cat_var1 & var2% in% lvl_cat_var2)] 'и' pred_data <- total_data [(var1% in% lvl_cat_var1 & var2% in% lvl_cat_var2)] 'then do' new_lvl_data $ predicted_class <- "no" 'и полномасштабное предсказание для' pred_data' – abhiieor

+0

сделайте это как ваш ответ, и я с удовольствием Примите это! –

+0

@agenis: OP хочет, чтобы запись нового уровня классифицировалась как класс по умолчанию. Я просто выбрал «нет» в качестве примера. Больше никаких последствий. – abhiieor

0

Я обычно делаю это, используя петлю, где любые уровни вне поезда будут перекодированы как NA этой функцией. Здесь поезд - это данные, которые вы использовали для обучения модели, и тест - это данные, которые будут использоваться для прогнозирования.

for(i in 1:ncol(train)){ 
    if(is.factor(train[,i])){ 
    test[,i] <- factor(test[,i],levels=levels(train[,i])) 
    } 
} 

Trycatch - это механизм обработки ошибок, то есть после возникновения ошибки. Это не применимо, если вы не захотите сделать что-то другое после того, как ошибка возникла. Но вы все равно хотите запустить модель, тогда этот цикл позаботится о новых уровнях.

+0

Спасибо за ответ, но вы не думаете, что для циклов или любых циклов в этом случае будет очень медленно. Это вызывает беспокойство, потому что я думаю о том, чтобы сделать его производственным классом! –

+0

Для цикла здесь только для устранения уровней факторов. Это не имело бы никакого значения с точки зрения производительности. –

 Смежные вопросы

  • Нет связанных вопросов^_^