2016-09-27 15 views
5

mam df dataframe, Buduję model uczenia maszynowego (drzewo decyzyjne C5.0) do przewidywania klasy kolumny (loan_approved):Jak radzić sobie z błędami w przewidywaniu funkcji R?

konstrukcji (nie prawdziwe dane):

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 

procesu:

  • i podzielono losowo ramkę danych do testów i pociągu kolejowego nabytych w zbiorze (wiersze 1,2,3,5,6 trenowanie d wiersz 4 jako test)
  • W celu uwzględnienia nowego poziomu skategoryzowane w jednym lub wielu kolumn, że stosuje się funkcję próba

Funkcja:

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

zastosował funkcję przewidywania:

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

problem:

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 

Pytanie:

wiem, że to dlatego, że ramka danych Test miał nowy poziom, który nie był obecny w danych pociąg, ale nie powinno moja funkcja pracy we wszystkich przypadkach z wyjątkiem tego?

P.S: nie używać sapply ponieważ był zbyt powolny

+0

Jaki jest twój rzeczywisty problem? Czy to tylko powrót "nie"? Jaki jest błąd, który jest zwracany przez wywołanie 'predict'? – cdeterman

+1

Problem polega na tym, że funkcja przewidywania napotyka nowe poziomy czynników w kolumnie "okupacja" i nie tylko dla tego jednego wiersza, ale traktuje całą ramkę danych jako nieudaną próbę. –

+0

Wygląda na to, że powinieneś rozwarstwiać podział tak, aby z grubsza ten sam numer każdej kategorii w każdym podziale. – Aaron

Odpowiedz

1

Istnieją dwie części tego problemu.

  1. Pierwsza część problemu pojawia się podczas szkolenia modelu, ponieważ zmienne kategorialne nie są równo podzielone między pociągi i test, jeśli do podziału losowego. W twoim przypadku powiedz, że masz tylko jedną płytę z zawodowym "żeglarzem", to możliwe, że skończy się zestawem testowym podczas losowego podziału. Model zbudowany przy użyciu zbioru danych pociągu nigdy nie widziałby wpływu zawodu "żeglarz", a zatem będzie on powodował błędy. W bardziej uogólnionym przypadku jest możliwe, że jakiś inny zmienny poziom jakościowy przechodzi całkowicie do zestawu testów po losowym dzieleniu.

Zamiast dzielenia danych losowo pomiędzy pociągiem a teście, można przeprowadzić stratyfikację próbkowania. Kod użyciu data.table do 70:30 rozłamu jest:

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

To sprawia, że ​​na pewno każdy poziom jest podzielona równo między pociągiem i zbiorze testowym. Więc nie otrzymasz "nowego" poziomu jakościowego w zestawie danych testowych; który w przypadkowym rozdarciu może tam być.

  1. Druga część problemu jest, gdy model jest w produkcji i napotka zupełnie nową zmienną, która nie była tam nawet szkolenia lub zestawu testowego. Aby rozwiązać ten problem, można utrzymywać listę wszystkich poziomów wszystkich zmiennych jakościowych przy użyciu lvl_cat_var1 <- unique(cat_var1) i lvl_cat_var2 <- unique(cat_var2) itd.Następnie przed przewidzieć można sprawdzić na nowy poziom i filtrem:

    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)] 
    

następnie do przewidywania domyślnym zrobić:

new_lvl_data$predicted_class <- "no" 

i pełnowartościowy prognozy dla pred_data.

+0

można utrzymywać listę wszystkich poziomów wszystkich zmiennych jakościowych za pomocą 'lvl_cat_var1 <- unique (cat_var1) '' lvl_cat_var2 <- unique (cat_var2) ', a następnie przed przewidywaniem możesz sprawdzić nowy poziom i przefiltrować' new_lvl_data <- total_data [! (var1% w% lvl_cat_var1 i var2% w% lvl_cat_var2)] 'i' pred_data <- total_data [(var1% w% lvl_cat_var1 i var2% w% lvl_cat_var2)] 'następnie wykonaj' new_lvl_data $ predicted_class <- "no" 'i przepowiednia przepełniona dla' pred_data' – abhiieor

+0

sprawiają, że jest to twoja odpowiedź i chętnie Zaakceptuj to! –

+0

@agenis: OP chce, aby rekord nowych poziomów został sklasyfikowany jako klasa domyślna. Ja tylko wybrałem "nie" jako przykład. Koniec z implikacją. – abhiieor

0

Generalnie robię to za pomocą pętli, w której dowolne poziomy poza pociągiem zostaną zakodowane jako NA przez tę funkcję. Tutaj pociąg to dane, których użyłeś do szkolenia modelu, a test to dane, które posłużyłyby do prognozowania.

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

Trycash jest mechanizmem obsługi błędów, tj. Po napotkaniu błędu. Nie będzie to miało zastosowania, chyba że chcesz zrobić coś innego po napotkaniu błędu. Ale nadal chciałbyś uruchomić model, wtedy ta pętla zajmie się nowymi poziomami.

+0

Dzięki za odpowiedź, ale nie sądzisz, że pętle lub inne pętle będą naprawdę powolne. Jest to problem, ponieważ myślę o tym, aby nadać mu stopień produkcyjny! –

+0

Pętla for służy tylko do usuwania poziomów czynników. To nie ma znaczenia pod względem wydajności. –

Powiązane problemy