Тема 4: Основы моделирования

Лекция 7. Основы машинного
обучения в R

Большие данные и аналитика
Бизнес-информатика 38.03.05 (бакалавриат)

Обзор подходов к машинному обучению в R

Источник: Machine Learning for Everyone

Основные “фреймворки”




Основные “фреймворки”

📖 Tidy Modeling with R (Max Kuhn and Julia Silge)

📖 Applied Machine Learning Using mlr3 in R (Bernd Bischl, etc.)

📖 Deep Learning and Scientific Computing with R torch (Sigrid Keydana)

📖 Глубокое обучение с R и Keras (Ф. Шолле, Дж.Дж. Алиер)

Библиотеки для работы с LLMs

Источник: Large Language Model tools for R

Основы моделирования в R

Формулы в R


Символ Значение Пример
~ отделяет зависимые переменные (слева) от независимых (справа) y ~ x + z + w
+ разделяет независимые переменные
: взаимодействие между независимыми переменными y ~ x + z + x:z
* все возможные взаимодействия y ~ x * z * w эквивалентно y ~ x + z + w + x:z + x:w + z:w + x:z:w
^ взаимодействия до определенного порядка y ~ (x + z + w)^2 эквивалентно y ~ x + z + w + x:z + x:w + z:w
-1 подавляет свободный член уравнения y ~ x -1
. показывает зависимость от всех переменных y ~ . эквивалентно y ~ x + z + w

Пример данных

Рассмотрим модель прогноза массы пингвинов.

library(palmerpenguins)

penguins_df <- penguins |>
  filter(!is.na(sex)) |>
  select(-year, -island) %T>% print()
# A tibble: 333 × 6
   species bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex   
   <fct>            <dbl>         <dbl>             <int>       <int> <fct> 
 1 Adelie            39.1          18.7               181        3750 male  
 2 Adelie            39.5          17.4               186        3800 female
 3 Adelie            40.3          18                 195        3250 female
 4 Adelie            36.7          19.3               193        3450 female
 5 Adelie            39.3          20.6               190        3650 male  
 6 Adelie            38.9          17.8               181        3625 female
 7 Adelie            39.2          19.6               195        4675 male  
 8 Adelie            41.1          17.6               182        3200 female
 9 Adelie            38.6          21.2               191        3800 male  
10 Adelie            34.6          21.1               198        4400 male  
# ℹ 323 more rows

Линейная регрессия

model_penguins <- lm(body_mass_g ~ sex + species + 
                       bill_length_mm + bill_depth_mm + flipper_length_mm,
                     data = penguins_df)

summary(model_penguins)

Call:
lm(formula = body_mass_g ~ sex + species + bill_length_mm + bill_depth_mm + 
    flipper_length_mm, data = penguins_df)

Residuals:
    Min      1Q  Median      3Q     Max 
-779.65 -173.18   -9.05  186.61  914.11 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)       -1460.995    571.308  -2.557 0.011002 *  
sexmale             389.892     47.848   8.148 7.97e-15 ***
speciesChinstrap   -251.477     81.079  -3.102 0.002093 ** 
speciesGentoo      1014.627    129.561   7.831 6.85e-14 ***
bill_length_mm       18.204      7.106   2.562 0.010864 *  
bill_depth_mm        67.218     19.742   3.405 0.000745 ***
flipper_length_mm    15.950      2.910   5.482 8.44e-08 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 287.3 on 326 degrees of freedom
Multiple R-squared:  0.875, Adjusted R-squared:  0.8727 
F-statistic: 380.2 on 6 and 326 DF,  p-value: < 2.2e-16

Линейная регрессия

library(parameters)
model_parameters(model_penguins)
Parameter           | Coefficient |     SE |              95% CI | t(326) |      p
----------------------------------------------------------------------------------
(Intercept)         |    -1460.99 | 571.31 | [-2584.91, -337.08] |  -2.56 | 0.011 
sex [male]          |      389.89 |  47.85 | [  295.76,  484.02] |   8.15 | < .001
species [Chinstrap] |     -251.48 |  81.08 | [ -410.98,  -91.97] |  -3.10 | 0.002 
species [Gentoo]    |     1014.63 | 129.56 | [  759.75, 1269.51] |   7.83 | < .001
bill length mm      |       18.20 |   7.11 | [    4.22,   32.18] |   2.56 | 0.011 
bill depth mm       |       67.22 |  19.74 | [   28.38,  106.06] |   3.40 | < .001
flipper length mm   |       15.95 |   2.91 | [   10.23,   21.67] |   5.48 | < .001

Линейная регрессия в {broom}

Библиотека {broom} позволяет создавать tidy-таблицы для моделей.

tidy создает таблицу, которая суммирует статистические результаты модели;
augment добавляет столбцы к исходным данным, например, прогнозы и остатки;
glance строит краткое однострочное резюме модели.

library(broom)

glance(model_penguins)
# A tibble: 1 × 12
  r.squared adj.r.squared sigma statistic   p.value    df logLik   AIC   BIC
      <dbl>         <dbl> <dbl>     <dbl>     <dbl> <dbl>  <dbl> <dbl> <dbl>
1     0.875         0.873  287.      380. 6.82e-144     6 -2354. 4724. 4754.
# ℹ 3 more variables: deviance <dbl>, df.residual <int>, nobs <int>

Линейная регрессия в {broom}

augment(model_penguins)
# A tibble: 333 × 12
   body_mass_g sex    species bill_length_mm bill_depth_mm flipper_length_mm
         <int> <fct>  <fct>            <dbl>         <dbl>             <int>
 1        3750 male   Adelie            39.1          18.7               181
 2        3800 female Adelie            39.5          17.4               186
 3        3250 female Adelie            40.3          18                 195
 4        3450 female Adelie            36.7          19.3               193
 5        3650 male   Adelie            39.3          20.6               190
 6        3625 female Adelie            38.9          17.8               181
 7        4675 male   Adelie            39.2          19.6               195
 8        3200 female Adelie            41.1          17.6               182
 9        3800 male   Adelie            38.6          21.2               191
10        4400 male   Adelie            34.6          21.1               198
# ℹ 323 more rows
# ℹ 6 more variables: .fitted <dbl>, .resid <dbl>, .hat <dbl>, .sigma <dbl>,
#   .cooksd <dbl>, .std.resid <dbl>

Линейная регрессия в {broom}

Рассмотрим коэффициенты (terms) регрессионной модели для прогнозирования массы тела.

Переменная estimate — предполагаемое влияние коэффициентов на прогноз.

model_penguins |>
  tidy(conf.int = TRUE) |>
  mutate(term = fct_reorder(term, estimate)) |>  
  arrange(estimate) |>
  filter(!(term == "(Intercept)")) |>
  ggplot(aes(estimate, term)) +
  geom_point() +
  geom_vline(lty = 2, xintercept = 0, color = "red") +
  geom_errorbar(aes(xmin = conf.low , 
                    xmax = conf.high))

Линейная регрессия в {broom}

Диагностика модели в {performance}

Для диагностики модели можно использовать библиотеку {performance}.

Проверим, соответствует ли тип модели (семейство распределений) исходным данным: линии, предсказанные моделью, должны быть похожи на наблюдаемые линии данных.

Синие линии на следующем графике — это смоделированные данные на основе модели, если бы модель была истинной и распределительные предположения были выполнены.

Зеленая линия представляет фактические наблюдаемые данные переменной отклика.

library(performance)

plot(check_model(model_penguins, panel = FALSE))[[1]]

Диагностика модели в {performance}

Диагностика модели в {performance}

Следующий график помогает проверить могут ли предикторы иметь нелинейную связь с результатом, в этом случае опорная линия может приблизительно указывать на эту связь.

Прямая и горизонтальная линия указывает на то, что спецификация модели в порядке.

plot(check_model(model_penguins, panel = FALSE))[[2]]

Диагностика модели в {performance}

Диагностика модели в {performance}

В линейной регрессии остатки должны быть нормально распределены. Данное условие можно проверить с помощью так называемого QQ-графика (квантиль-квантильного графика), который показывает квантили стьюдентизированных остатков по сравнению с подобранными значениями.

Точки должны располагаться вдоль зеленой референтной линии. Если это не происходит, выводные статистики, такие как p-значение или покрытие доверительных интервалов, могут быть неточными.

plot(check_model(model_penguins, panel = FALSE))[[6]]

Диагностика модели в {performance}

Диагностика модели в {performance}

Выбросы можно определить как особенно влиятельные наблюдения с помощью расстояния Кука (Кук 1977, Кук и Вайсберг 1982).

Любая точка на следующем графике, которая находится за пределами расстояния Кука (пунктирные линии), считается влиятельным наблюдением.

plot(check_model(model_penguins, panel = FALSE))[[4]]

Диагностика модели в {performance}

Tidymodels

Основные библиотеки Tidymodels

Библиотека Описание
{tidymodels} метабиблиотека, которая устанавливает и загружает основные библиотеки, перечисленные ниже
{rsample} инфраструктура для эффективного разделения данных и повторной выборки данных
{parsnip} унифицированный интерфейс для моделей, который позволяет указывать модель без необходимости запоминать различные имена аргументов функций или вычислительных движков
{recipes} интерфейс для инструментов предварительной обработки данных для проектирования признаков (feature engineering steps)
{workflows} объединяет предварительную обработку, моделирование и постобработку в единый объект
{tune} помогает оптимизировать гиперпараметры модели
{yardstick} измеряет эффективность моделей с помощью метрик

Этапы работы в tidymodels

Подготовка данных

Рассмотрим данные palmerpenguins, для прогноза выберем пол пингвинов,

Загрузка библиотек.

library(tidyverse)
library(tidymodels)
library(magrittr)

# данные
library(palmerpenguins)

Данные необходимо подготовить, возможно выполнить преобразования.

penguins_df <- penguins |>
  filter(!is.na(sex)) |>
  select(-year, -island)

Визуализация

Разбиение на выборки

Ресамплинг состоит в разбиении всей выборки на обучающую и тестовую в библиотеке {rsample}.

strata — переменная для проведения стратифицированного разбиения, это может помочь гарантировать, что повторные выборки имеют эквивалентные пропорции с исходным набором данных.

# задает начальное число для генератора случайных чисел, 
# что помогает улучшить воспроизводимость кода
set.seed(2025)

# разбиение
penguin_split <- initial_split(penguins_df, 
                               strata = sex,
                               prop = 0.8)

Выборки

Формула

Инициализируем рецепт в библиотеке {recipes}, используя формулу:

penguin_rec <-
  recipe(sex ~ ., data = penguin_train)
  • Формула заявляет, что столбец sex является результатом (так как он находится слева от тильды).

  • Точка справа указывает, что все столбцы (переменные) в penguin_train, кроме результата, следует рассматривать как предикторы.

Конструирование признаков

Конструирование признаков (Feature engineering) — это процесс выбора, обработки и преобразования необработанных данных в признаки, которые можно использовать в машинном обучении.

penguin_rec <-
  recipe(sex ~ ., data = penguin_train) |>
  step_YeoJohnson(all_numeric_predictors()) |>
  step_normalize(all_numeric_predictors()) |>
  step_dummy(species)
  • step_YeoJohnson() — применяет преобразование Йео-Джонсона ко всем числовым предикторам в данных. Это преобразование может помочь нормализовать данные, сделав их более симметричными и уменьшив влияние выбросов.

  • step_normalize()нормализует все числовые предикторы, масштабируя данные так, чтобы они имели среднее значение 0 и стандартное отклонение 1.

  • step_dummy() — создает фиктивные переменные (бинарные переменные, которые используются для представления категориальных переменных) для переменной species.

Конструирование признаков

Указание модели

Определим модели с помощью библиотеки {parsnip}, указав движок (set_engine) для модели и режим модели (set_mode), если требуется.

Рабочий процесс

Рабочий процесс объединяет набор моделей и список спецификаций моделирования в аргументе models, workflow_map позволяет указать одни и те же параметры для всех моделей.

На этом этапе происходит обучение моделей.

# future! 🚀 - параллельные вычисления
library(future)
plan(sequential)

workflow_set <-
  workflow_set(
    preproc = list(penguin_rec),
    models = list(
      glm = glm_spec,
      tree = tree_spec)
  ) |>
  workflow_map(resamples = penguin_folds)

Эффективность моделей

Дать первичную оценку эффективности моделей можно рассмотрев метрики.

rank_results(workflow_set,
             select_best = TRUE)
# A tibble: 6 × 9
  wflow_id    .config      .metric   mean std_err     n preprocessor model  rank
  <chr>       <chr>        <chr>    <dbl>   <dbl> <int> <chr>        <chr> <int>
1 recipe_tree Preprocesso… accura… 0.913  0.0127     10 recipe       rand…     1
2 recipe_tree Preprocesso… brier_… 0.0744 0.00408    10 recipe       rand…     1
3 recipe_tree Preprocesso… roc_auc 0.972  0.00508    10 recipe       rand…     1
4 recipe_glm  Preprocesso… accura… 0.902  0.0178     10 recipe       logi…     2
5 recipe_glm  Preprocesso… brier_… 0.0680 0.00957    10 recipe       logi…     2
6 recipe_glm  Preprocesso… roc_auc 0.970  0.00752    10 recipe       logi…     2

Эффективность моделей

workflow_set |> autoplot() +
  theme_bw()

Эффективность моделей

workflow_set |> autoplot(select_best = TRUE) +
  theme_bw()

Выбор наилучшей модели

# выбор наилучшей модели
best_model_id <- "recipe_tree" # из workflow_set

best_fit <-
  workflow_set |>
  extract_workflow_set_result(best_model_id) |>
  select_best(metric = "accuracy")

# рабочий процесс наилучшей модели
final_workflow <-
  workflow_set |>
  extract_workflow(best_model_id) |>
  finalize_workflow(best_fit)

Дообучение модели

Распространим модель на все данные и сравним метрики.

# дообучение на всех данных
final_fit <-
  final_workflow |>
  last_fit(penguin_split)

# финальные метрики
collect_metrics(final_fit)
# A tibble: 3 × 4
  .metric     .estimator .estimate .config             
  <chr>       <chr>          <dbl> <chr>               
1 accuracy    binary        0.896  Preprocessor1_Model1
2 roc_auc     binary        0.952  Preprocessor1_Model1
3 brier_class binary        0.0763 Preprocessor1_Model1

brier_classоценка Брайера аналогичная средней квадратичной ошибке в регрессионных моделях. Разница между бинарным индикатором для класса и его соответствующей вероятностью класса возводится в квадрат и усредняется.

Прогнозирование

Распространим модель на исходное множество.

# модель для исходных данных
final_model <- fit(final_workflow, penguins_df)

Создадим новые данные.

# искусственно созданные данные
new_penguin <- tribble(~species, 
                       ~bill_length_mm, ~bill_depth_mm, ~flipper_length_mm, 
                       ~body_mass_g,
  "Adelie", 38.5, 19.4, 185, 3700)

Найдем прогноз с помощью модели. 🎉

# прогноз на искусственно созданных данных
predict(final_model, new_data = new_penguin)
# A tibble: 1 × 1
  .pred_class
  <fct>      
1 male       

Диагностика модели

Один из известных видов диагностики модели — ROC-кривая (Receiver operator curve).

final_fit |>
  collect_predictions() |>
  roc_curve(truth = sex, 
            .pred_female) |>
  autoplot()

Матрица ошибок

Матрица ошибок (Confusion matrix) также служит для оценки качества работы алгоритмов в машинном обучении.

conf_matrix <- 
collect_predictions(final_fit) |>
  conf_mat(sex, .pred_class)

# тепловая карта
model_heatmap <- 
  conf_matrix |>
  autoplot(type = "heatmap")

# мозаичный график
model_mosaic <-
  conf_matrix |>
  autoplot(type = "mosaic")

library(patchwork)

model_heatmap + model_mosaic

Матрица ошибок

Развертывание модели

Библиотека {vetiver} предоставляет набор инструментов для создания, развертывания и управления моделями машинного обучения.

Она позволяет пользователям легко создавать, версионировать, развертывать и мониторить модели машинного обучения на различных хостинговых платформах, таких как Posit Connect или облачный хостинговый сервис, такой как Azure.

R in Production (автор Hadley Wickham) дает основы развертывания современных проектов на R.

Развертывание модели

Что мы изучили

Рассмотренные вопросы

  • Возможности для машинного обучения в R
  • Диагностика линейной регрессии с помощью broom и performance
  • Основные библиотеки tidymodels
  • Пошаговый пример работы в tidymodels

Спасибо за внимание!