Jakiś czas temu pisałem o narzędziach Pythonowych służących do zaglądania do wnętrza modelu predykcyjnego. Poświęciłem temu tematowi trzy artykuły (ELI5 i czarne pudełka, Partial Dependence Plots, Co to jest SHapley Additive exPlanations (SHAP)?) i pewnie poświęcę jeszcze kilka. Ostatnio natrafiłem na podobne narzędzie, ale przygotowane dla języka R. Narzędzie to nazywa się auditor i chociaż nie jestem (jeszcze) specem od R, postaram się poniżej je przedstawić.
auditor
Pakiet auditor to zbiór funkcji pozwalających w bardzo prosty i szybki sposób przedstawić graficznie najbardziej interesujące i ważne cechy oraz właściwości modelu predykcyjnego. Idea jest taka, że tworzymy sobie jeden bądź kilka modeli i uruchamiamy auditora, żeby pokazał nam na porównaniach, co w tych modelach piszczy. Wtedy już my, korzystając z naszego doświadczenia i kontekstu, będziemy wybierać który model lepiej nam pasuje. Według autorki auditor nie oferuje niczego nowego, czego już nie da się uzyskać w R, ale zbiera wszystkie te wykresy i ustanawia jeden interfejs pracy z nimi. W ten sposób nie musimy używać, nie wiadomo ilu pakietów – bierzemy jeden i używamy go w jednolity sposób.
Przykłady?
Aktualnie (okres między wigilią a sylwestrem) stężenie ciasta w moim układzie krwionośnym jest takie duże, że ciężko mi się w ogóle zabrać do pisania. Pomyślałem więc, że może pójdę trochę na łatwiznę i omówię po polsku jeden z przykładów z dokumentacji auditora. Myślę, że może komuś się to przydać (szczególnie jeśli jeszcze dobrze nie śmiga po angielsku) a i temat nie będzie zbyt skomplikowany na ten dziwny okres w roku.
Przykład, który mi się najbardziej rzucił w oczy to wykresy radarowe porównujące wyniki poszczególnych modelów. Spodobał mi się dlatego, że pomaga w błyskawicznym wyborze modelu, a nie widziałem takiego czegoś jeszcze w Pythonie (owszem, można tam coś takiego zrobić, ale aktualnie zajmie to pewnie więcej kodu niż samo modelowanie :P).
Oryginalny przykład który przytaczam poniżej znajduje się w dokumentacji pod tytułem Model Performance Audit.
Przejdźmy więc do konkretów. Naszym celem będzie wyznaczenie czasu życia smoka, na podstawie danych (raczej fikcyjnych ;-)) archeologicznych. Nie jestem pewien dokładnej interpretacji tych danych, w każdym razie mamy w nich kilka kolumn niezależnych (year_of_birth, height, weight, scars, colour, year_of_discovery, number_of_lost_teeth) i jedną kolumnę zależną (life_length). Naszym zadaniem jest wyznaczenie precyzyjnej wartości kolumny zależnej, jest to więc problem typu uczenie nadzorowane – regresja.
Wczytajmy więc dane. Dane, których będziemy używać, znajdują się w pakiecie DALEX2. Nie udało mi się namierzyć wersji binarnej dla Anacondy, zainstalujemy go więc bezpośrednio z serwisu GitHub przy pomocy pakietu devtools.
devtools::install_github("ModelOriented/DALEX2")
Po zainstalowaniu wczytujemy dane i od razu wyświetlamy ich początek:
library(DALEX2) data("dragons") head(dragons)
year_of_birth | height | weight | scars | colour | year_of_discovery | number_of_lost_teeth | life_length |
---|---|---|---|---|---|---|---|
-1291 | 59.40365 | 15.32391 | 7 | red | 1700 | 25 | 1368.4331 |
1589 | 46.21374 | 11.80819 | 5 | red | 1700 | 28 | 1377.0474 |
1528 | 49.17233 | 13.34482 | 6 | red | 1700 | 38 | 1603.9632 |
1645 | 48.29177 | 13.27427 | 5 | green | 1700 | 33 | 1434.4222 |
-8 | 49.99679 | 13.08757 | 1 | red | 1700 | 18 | 985.4905 |
915 | 45.40876 | 11.48717 | 2 | red | 1700 | 20 | 969.5682 |
Widzimy, jak mniej więcej wyglądają kolumny, o których wspomniałem powyżej. Możemy od razu wytrenować model liniowy:
lm_model <- lm(life_length ~ ., data = dragons)
jak i las losowy:
library("randomForest") set.seed(59) rf_model <- randomForest(life_length ~ ., data = dragons)
Jak widać, nie zmieniałem tutaj domyślnych parametrów. Ale dzięki temu sytuacja jest bardziej klarowna i o to pewnie chodziło twórcom tego przykładu. Skoro mamy już modele, możemy przejść do ich audytu, czyli użyć modułu auditor:
library("auditor") lm_audit <- audit(lm_model, label = "lm", data = dragons, y = dragons$life_length) rf_audit <- audit(rf_model, label = "rf", data = dragons, y = dragons$life_length)
Uwaga, jeśli tak jak ja masz problemy z instalacją najnowszego wydania auditora, może to rozwiązanie Ci pomoże. W każdym razie tak jak widzisz, stworzenie audytu jest trywialne. Podajemy model i dane, na których chcemy pracować. Opcjonalnie dokładamy etykietkę, żeby się nie pogubić. W tym momencie możemy odpalać już całą masę różnych wykresów auditora. Ale sprawdźmy teraz ten wykres, o którym wspominam powyżej:
lm_mp <- modelPerformance(lm_audit, scores = c("MAE", "MSE", "REC", "RROC")) rf_mp <- modelPerformance(rf_audit, scores = c("MAE", "MSE", "REC", "RROC")) lm_mp
score | label | name |
---|---|---|
3.334652e+01 | lm | MAE |
1.656454e+03 | lm | MSE |
3.330139e+01 | lm | REC |
3.312907e+09 | lm | RROC |
Powyższy kawałek kodu przygotuje odpowiednią tabelkę różnych metod score dla poszczególnego modelu. Samo w sobie już jest to wygodne, bo możemy ją sobie podejrzeć „naocznie”. Dokonajmy odpowiedniej „radarowej” wizualizacji:
plot(lm_mp, rf_mp, table = FALSE)
Co na nim widać? Ano bardzo dużo. Mamy tutaj wyróżnione cztery kierunki. Każdy kierunek to jedna metryka score, znormalizowana do 1. Im dalej mamy linię w danym kierunku, tym wynik uzyskany przez dany model jest lepszy. Na pierwszy rzut oka widzimy, że model rf uzyskał dwa razy lepszy wynik, a pozostałe dwa wygrał model lm. Widzimy też, że model liniowy, jeśli był lepszy, to był lepszy niż las losowy nad modelem liniowym, gdy las „wygrywał”. Nie jest problemem dorzucenie własnej metryki do tych wyliczanych przez pakiet:
new_score <- function(object) sum(sqrt(abs(object$residuals))) lm_mp <- modelPerformance(lm_audit, scores = c("MAE", "MSE", "REC", "RROC"), new.score = new_score) rf_mp <- modelPerformance(rf_audit, scores = c("MAE", "MSE", "REC", "RROC"), new.score = new_score) plotModelRanking(lm_mp, rf_mp, table = FALSE)
Po dołożeniu naszej metryki las losowy okazał się dawać lepsze wyniki.
Powyższy trywialny wręcz przykład pokazuje jedno z wielu zastosowań pakietu auditor. Muszę przyznać, że z chęcią zobaczyłbym coś podobnego w Pythonie. Może jest już nawet odpowiedni moduł, ale jeszcze na niego nie natrafiłem. Wiem natomiast, że jeśli w przyszłości będę przygotowywał jakieś artykuły na bazie R, to pewnie będę korzystał również z Audytora.
auditor a sprawa polska
Z pakietem auditor zetknąłem się nie przypadkiem. Otóż miałem okazję uczestniczyć w spotkaniu organizowanym przez Michała Burdukiewicza we wrocławskiej siedzibie McKinsey (reprezentowanym przez Darię Szmurło). Na spotkaniu tym Alicja Gosiewska i Agnieszka Ciepielewska prezentowały (slajdy tutaj) właśnie pakiet auditor. Okazuje się bowiem, że Alicja jest współautorką i osobą aktualnie utrzymującą ten pakiet. Uczestnicy mieli więc okazję podpytać o ten i potencjalne następne projekty, nad którymi pracują dziewczyny.
Oprócz prezentacji Alicji i Agnieszki na temat możliwości auditora Michał miał też przyjemność (w imieniu fundacji Why R?) wręczyć Alicji pierwszy grant „Why R? supporting grant FOR WOMAN IN DATA SCIENCE”. Zdjęcia poniżej :D.
Według mnie jest to bardzo fajna inicjatywa, dzięki której fundacja ta (reprezentująca niejako polską społeczność R) może odwdzięczyć się za stworzenie otwartego, fajnego, ale przede wszystkim przydatnego narzędzia wpierającego pracę z R. Obyśmy byli świadkami większej ilości takich grantów i pakietów :).
Z tego, co udało mi się zorientować, to auditor jest efektem współpracy Uniwersytetu Warszawskiego i Politechniki Warszawskiej pod nazwą MI^2 Data Lab. Wygląda to na bardzo fajną sprawę i jeśli byłbym osobą studiującą w Warszawie, to na pewno zainteresowałbym się mocniej, co tam się dzieje ;).
Podsumowując – jeśli pracujesz na co dzień w języku R, to myślę, że auditor może Ci trochę pomóc w pracy. A jeśli masz jakiś pomysł na jego dalszy rozwój albo nawet już przygotowałeś jakieś pull requesty, to uderzaj od razu na GitHub.
Pełny kod użyty w artykule znajduje się tutaj.