R
August 13, 2022

Визуализация рейтинга кандидатов

Сейчас завершается приёмная кампания в вузы. Как правило, результаты конкурсных испытаний представлены на сайтах учебных заведений в виде таблиц, в которых заявители (поступающие на ту или иную специальность) расположены порядке убывания их конкурсного балла. Таблицы — один из распространенных способов представления данных.

Для примера рассмотрим таблицу с конкурсными баллами абитуриентов, поступающих на одно из направлений подготовки (специальность) в магистратуре УрФУ [1]. Отличный повод, чтобы рассказать о визуализации рейтингов кандидатов, хоть и на примере абитуриентов, но это не имеет принципиального значения.

Так выглядит таблица в разделе «Конкурсные списки»:

Конкурсный балл — сумма баллов за вступительное компьютерное тестирование (от 0 до 100 баллов) и индивидуальные достижения абитуриента (от 0 до 20 баллов).

Конечно, не забываем, когда хорошо работают таблицы, а когда графики [2]. Таблицу можно сделать более удобной и наглядной, убрав всё лишнее [3]. Я люблю таблицы, а красивые и аккуратные таблицы — ещё больше. Данный пост не о таблицах (о них в другой раз), а о графиках.

Мы можем по-разному визуализировать распределение конкурсного рейтинг-балла, а каждый вариант визуализации будет рассказывать свою историю на основе одних и тех же данных, но с разным уровнем детализации и для решения разных задач. Например, можно построить гистограмму распределения конкурсного балла, либо показать распределение в виде пугающих многих ящика с усами (боксплота):

Классическая гистограмма

Ящик с усами (боксплот), пугающий всех своей "непонятностью":

Ящик с усами

Помимо боксплотов и различных графиков «семейства» гистограмм, существует много других одномерных графиков. Ранее я писал про преимущества точечных графиков [4]. Попробуем представить результаты конкурсных испытаний по одному из произвольных направлений магистратуры в виде точечного графика — графика-«улей» (bee swarm plot — одномерный точечный график). График-«улей» отражает не только плотность распределения значений выборки, но и то, как расположены сами эти значения (точки). Каждая точка на графике — индивидуальный результат конкретного абитуриента (кандидата). При этом точки, представляющие одинаковые результаты (равные конкурсные баллы), не перекрываются на самом графике:

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

Проходной балл — показатель, от которого зависят шансы абитуриента на поступление и находится в прямой зависимости от плана набора на специальность, количества поданных заявлений, суммы конкурсных баллов каждого из абитуриентов. В случае, если число лиц с одинаковыми баллами (полупроходной балл) превышает количество вакантных мест, часть абитуриентов зачисляется, а часть нет. Приёмная комиссия определяет абитуриентов, у которых есть преимущественное право на зачисление при равном количестве баллов.

Точки создают впечатление индивидуальности, чего не могут достичь рейтинг-таблица с конкурсными баллами, гистограмма или боксплот. График-улей позволяет нам сосредоточиться на индивидуальности, когда мы видим каждого человека, а не объединяем людей в столбики или линии, показывая, например, 5-числовую сводку Тьюки (двух крайних значений: максимального и минимального, нижнего и верхнего квартилей и медианы)[6]. Наша визуализация в первую очередь рассказывает о людях, а не о данных. У нас получился своеобразный стоп-кадр, или фотофиниш 130 участников, показывающий насколько сильной была «борьба» за 24 бюджетных места. Если вы когда-нибудь участвовали в конкурсе, то знаете, что это не утренняя гимнастика с бегом на месте, когда:

«Не страшны дурные вести Начинаем бег на месте В выигрыше даже начинающий Красота, — среди бегущих Первых нет и отстающих Бег на месте общепримиряющий»

(В. Высоцкий, Утренняя гимнастика, 1978)

За каждой точкой на графике своя судьба и переживания: от горечи поражения до радости победы. Напомню третью заповедь HR-аналитика [5]:

«Numbers matter, but remember that there are people behind the numbers» [«Числа имеют значение, но помните, что за числами стоят люди»].

Поэтому я часто предлагал коллегам исправить те или иные графики. Например, для визуализации результатов оценочных мероприятий мы использовали одномерные точечные графики, которые очень нравились ЛПР за их наглядность и возможность сравнения. В HR-аналитике, как и в оценке персонала, не следует забывать об индивидуальном подходе. Особенно, когда мы визуализируем HR-данные.

Ссылки:

  1. https://magister.urfu.ru/ru/ratings
  2. https://revealthedata.com/blog/all/tablica-ili-grafik-kak-ubedit-zakazchika/
  3. https://www.storytellingwithdata.com/blog/2020/9/24/what-is-a-table
  4. https://t.me/People_Analytics/336
  5. https://t.me/People_Analytics/150
  6. https://en.wikipedia.org/wiki/Five-number_summary

Код на языке R для воспроизведения графиков:

Исходный файл с данными в формате RDS: https://disk.yandex.ru/d/psKfaC6T64yx_A

library(tidyverse)
library(glue)
library(ragg)
library(ggbeeswarm)
library(showtext)
# Загружаем данные
rating <- readRDS("rating.Rds") # https://disk.yandex.ru/d/psKfaC6T64yx_A
# Гистограмма
ggplot(rating) + 
  geom_histogram(aes(x = `Сумма конкурсных баллов`), binwidth = 10) +
  scale_x_continuous(breaks = seq(45,110,10)) + 
  labs(title = "Распределение конкурсного рейтинг-балла",
       x = "Конкурсный балл", y = "Частота") 
# Боксплот
ggplot(rating) + 
  geom_boxplot(aes(y = `Сумма конкурсных баллов`)) + 
  scale_x_discrete( ) +
  scale_y_continuous(breaks = seq(45,110,10)) + 
  labs(title = "Распределение конкурсного рейтинг-балла",
       y = "Конкурсный балл") +
  coord_flip()
# График-улей
cut_point <- 90 # Полупроходной балл
applicants <- 130
vacancies <- 24
font_add_google("Istok Web", family = "Istok Web")
font <- "Istok Web"
set.seed(123)
ggplot(rating, aes(x = "", y = `Сумма конкурсных баллов`)) +
  geom_hline(yintercept = cut_point, color = "#fb8072") +
  geom_beeswarm(size = 6, cex = 5,
                colour = rating$col,
                priority = "random") +
  scale_y_continuous(breaks = c(seq(30, 110,5))) +
  coord_flip() + 
  labs(
    y = "Сумма конкурсных баллов",
    title = glue(
      "Распределение конкурсного рейтинг-балла\nдля {applicants} заявителей на {vacancies} бюджетных места"),
    subtitle = "",
    caption = "Источник данных: https://magister.urfu.ru/ru/ratings/\nВизуализация: Юрий Тукачев, 2022"
    
  ) +
  theme_light(base_size = 20, base_family = font) +
  theme(
    panel.background = element_blank(),
    axis.title.y = element_blank(),
    axis.ticks.y = element_blank(),
    panel.border = element_blank(),
    panel.grid = element_blank(),
    axis.title = element_text(size = 18),
    text = element_text(
      family = font,
      color = "#53565A",
      size = 18
    ),
    plot.title.position = "plot",
    plot.caption.position = "plot",
    plot.caption = element_text(
      color = "gray50",
      size = 13,
      hjust = 1
    ),
    plot.margin = margin(25, 25, 10, 25),
    plot.subtitle = element_markdown(hjust = 0,
                                     # size = rel(0.95), 
                                     family = font),
    plot.title = element_text(
      size = rel(1.3),
      family = font,
      face = "bold",
      color = "gray20"
    )
  )
# Сохраняем график-улей
ggsave(
  here("ratings.png"),
  device = agg_png,
  width = 6.5,
  height = 6,
  dpi = 120,
  scale = 1.25
)

Мой телеграм-канал: https://t.me/People_Analytics
People analytics is a data-driven approach to managing people at work || Канал про HR-аналитику: оценка персонала, психометрика, использование R для анализа и визуализации HR-данных.