Чтобы получить лучшее (и более существенное) понимание черных ящиков моделей, графики разбивки чрезвычайно полезны и интуитивно понятны. Пакет {фонарик} упрощает создание этих графиков, но у него есть один недостаток: не интуитивно понятно, как настроить метки ваших объектов (по крайней мере, я не нашел простого ответа). В этом посте показан обходной путь, который я использовал, и я надеюсь, что он поможет другим сэкономить время на поиске решения в Google.
Я буду использовать набор данных Палмера, чтобы показать свои шаги.
# Load the packages library(flashlight) # Shed Light on Black Box ML Models library(palmerpenguins) # Palmer Archipelago Penguin Data library(dplyr) # A Grammar of Data Manipulation library(magrittr) # A Forward-Pipe Operator for R library(ggplot2) # Create Elegant Data Visualizations Using # the Grammar of Graphics # Load the data data("penguins")
Подробное описание работы {фонарика} и графики разбивки можно прочитать здесь. Я буду использовать аналогичный пример, представленный в руководстве. На первом этапе я покажу вам результат общего графика разбивки.
Код для создания графика разбивки
# Fit model fit <- lm(bill_length_mm ~ ., data = penguins) # Make flashlight fl <- flashlight( model = fit, data = penguins, y = "bill_length_mm", label = "ols", metrics = list(rmse = MetricsWeighted::rmse, `R-squared` = MetricsWeighted::r_squared) ) # Plot the breakdown plot plot(light_breakdown(fl, new_obs = penguins[3, ], digits = 2))
На графике показаны вклады отдельных переменных (или функций). Иными словами, он визуализирует, какой вклад в прогноз вносит каждая отдельная переменная. Он начинается со среднего значения зависимой переменной (или target) в данных. Значение 44 указывает на то, что средняя длина клюва пингвинов в данных составляет 44 мм. Красные столбцы показывают отрицательный вклад, а синие столбцы — положительный вклад (также обозначаемый знаком перед значением переменной). Это означает, что если пингвин относится к виду Адели, длина клюва короче, тогда как большая глубина клюва (здесь 18 мм) с большей вероятностью будет способствовать увеличению длины клюва. Порядок переменных отсортирован по размеру вклада. Это означает, что переменные с большим вкладом идут первыми, а переменные с меньшим вкладом — наименее.
Хотя эта цифра уже говорит о многом, она еще не готова к публикации. Чтобы сделать внешний вид визуально более привлекательным, мы хотели бы настроить метки так, чтобы они были легко читаемыми, и, возможно, также изменить некоторые другие эстетические аспекты.
Для этого мы отклоняемся от процедуры и подготавливаем данные до того, как приступим к работе. Я пробовал разные способы (маркировка данных, добавление меток позже и т. д.), и только способ, который я покажу вам, работал у меня. Насколько я понимаю, это происходит потому, что функция light_breakdown
генерирует метки на графике внутри перед его построением. Для генерации меток функция использует имена переменных, а также их значения.
Подробнее о выводе, произведенном light_breakdown
light_breakdown(fl, new_obs = penguins[3, ], digits = 2)
I am an object with class(es) light_breakdown, light, list
data.frames (maximum 6 rows shown):
data
# A tibble: 6 x 6
step variable after before label description
<int> <chr> <dbl> <dbl> <chr> <chr>
1 0 baseline 44.0 44.0 ols average in data: 44
2 1 species 39.7 44.0 ols species = Adelie: -4.3
3 2 sex 38.6 39.7 ols sex = female: -1
4 3 body_mass_g 37.5 38.6 ols body_mass_g = 3250: -1.1
5 4 flipper_length_mm 37.2 37.5 ols flipper_length_mm = 195: -0.34
6 5 bill_depth_mm 37.5 37.2 ols bill_depth_mm = 18: +0.28
Все, что хранится в description
, позже будет нанесено на ваш график в виде меток.
Чтобы получить осмысленные метки, я перекодирую значения переменных (здесь для sex
я хочу видеть «женщина» вместо «женщина») и имена переменных (например, переменная bill_length_mm
неудобна для чтения, а Length of bill (in mm)
— легко читается).
penguins %<>% # First adjust the labels dplyr::mutate( sex = case_when(sex == "female" ~ "Female", sex == "male" ~ "Male")) %>% dplyr::rename( `Penguin species` = species, `Island` = island, `Length of bill (in mm)` = bill_length_mm, `Depth of bill (in mm)` = bill_depth_mm, `Length of flipper (in mm)` = flipper_length_mm, `Body mass (in g)` = body_mass_g, `Sex` = sex, `Year` = year)
И все готово. Теперь снова подгоним модель и сгенерируем фонарик.
# Fit model fit <- lm(`Length of bill (in mm)` ~ ., data = penguins) # Make flashlight fl <- flashlight( model = fit, data = penguins, y = "Length of bill (in mm)", label = "ols", metrics = list(rmse = MetricsWeighted::rmse, `R-squared` = MetricsWeighted::r_squared) )
Мы можем использовать объект фонарика fl
и построить график разбивки.
plot(light_breakdown(fl, new_obs = penguins[3,], digits = 2)) + theme_classic() + theme( axis.text.y = element_blank(), axis.ticks.y = element_blank(), axis.title.y = element_blank() ) + scale_fill_grey()
theme()
, theme_classic()
и scale_fill_grey()
являются дополнительными корректировками, чтобы рисунок можно было опубликовать в более поздней рукописи, но есть бесконечные возможности, и вы можете выбрать то, что лучше для вас.
Первоначально опубликовано на https://cosimameyer.rbind.io 18 апреля 2021 г.