Як ми брали участь у HR-хакатоне. Наші випускники діляться своїм рішенням і враженнями від участі

Всім привіт!
23-24 листопада в Digital October проходив хакатон з аналізу даних в HR-сфері, в якому перемогла команда випускників нашої програми "Фахівець з великим даними". Кирило Данилюк, Ігор Парфьонов, Єгор Андрєєв і Олександр Иваночкин діляться своїм рішенням і враженнями від участі.

Контекст
23-24 листопада в Digital October проходив хакатон з аналізу даних в HR-сфері — ми організувалися в команду (ai.at.work) і вирішили перейнятися завданнями у сфері HR. Ніхто з нас до цього на хакатони не ходив, тому інтерес був подвійний.
Пост вийшов довгий, тому давайте не будемо відволікатися на зайві деталі і відразу перейдемо до справи :) У змаганні, ми, до речі, перемогли. Отже, нам запропонували наступну ситуацію: дана компанія «Чайникофф», продає побутову техніку. «Чайникофф» — велика роздрібна мережа, присутня у багатьох регіонах, має понад 190 роздрібних магазинів. Компанія відома, працює на ринку давно (більше 20 років), у неї понад 2000 співробітників і розвинена система навчання персоналу. Компанія проводить очне навчання співробітників, так і онлайнове: у неї є корпоративний портал з бібліотекою, тестами для самоперевірки і вебінару.
Очевидно, що одна з конкурентних переваг компанії — це кваліфіковані і замотивовані на розвиток працівники, у тому числі продавці в роздрібних магазинах. Тому перед нами поставили два завдання:
  1. З урахуванням наявних даних, знайти оптимальний спосіб навчання співробітників.
  2. Знайти якісь цікаві патерни в даних, тобто, просто «намайнить» що-небудь корисне з датасета.
Дані
На жаль, дані, які нам надали, компанія публікувати у відкритий доступ не дозволила, тому доведеться описати всю структуру словами.
«Датасет», наданий нам, — це просто два Excel-файлу, в кожному з яких — близько десятка вкладок, що описують анкетні дані співробітників, пройдені ними курси, їх успішність з точки зору продажів і виконання плану, дані опитувань співробітників і т. д. Основна характеристика вихідних даних — їх низька якість. Для учасників змагань на Kaggle ситуація незвична: немає якої-небудь попередньої обробки даних, якість вихідних таблиць низьке, іноді за гранню. Ми отримали дані з усіма можливими проблемами з якістю:
  • Дані в одній колонці могли бути різних типів: числа, текст, порожні значення.
  • Висока розрідженість деяких таблиць, коли більша частина значень відсутня.
  • Явні дублікати в анкетних даних, коли ключі записів розрізняються, але самі записи ідентичні. Наприклад, може бути кілька анкетних записів одного і того ж охоронця з різними ключами user_id.
  • Структурні проблеми: в одній з таблиць частина колонок розташовувалася зі зміщенням, в інший (результати опитування співробітників) значення розташовувалися то вертикально, горизонтально.
  • Концептуальні проблеми: результати з першим опитуванням співробітників ми вважаємо некоректними, оскільки опитування не був анонимизирован.
Проте не потрібно боятися таких «брудних» та зашумлених даних, треба з ними працювати, препроцессить, трансформувати. Головна задача, яку ми собі поставили (і яка зайняла більшу частину часу хакатона) — це зібрати справжній датасет з того, що у нас є, і використовувати його для подальшої роботи. Власне, в цьому і проявилася наша перевага перед іншими командами. Коли з'являються якісні і грамотно агреговані дані, подальший їх аналіз стає набагато простіше.
Друга складність полягала в тому, що розмір вихідних даних виявився досить скромним. До цієї проблеми ми теж підійшли як до челленджу, адже якість підсумкового рішення сильно залежить від розміру даних, які можна використовувати. З іншого боку, від нас не вимагалося продакшен-рішення, а потрібно було продемонструвати робочий прототип.
У підсумку, ми зібрали два датасета:
  • Employees (співробітники). Набір функцій, що описують працівника: вік, стать, посаду, робочий стаж, загальна задоволеність роботою, виконання плану продажів, кількість пройдених курсів, середній бал за пройдені курси і інші подібні системи.
  • Courses (курси, семінари, документи з бібліотеки). Всі ті об'єкти, які описують навчання співробітника в компанії. Цей датасет — просто пари співробітник-курс з додатковими уточненнями: яку оцінку за курс співробітник отримав, скільки часу на курс витратив і т. д.
Рішення завдання #1
Ми підійшли до проблеми (підібрати оптимальний спосіб навчання кожного співробітника) з практичного боку: наше рішення повинно використовувати вже наявні матеріали, працювати в масштабах всієї компанії (застосовуватися не тільки для продавців) і не вимагати ручного програмування категорій.
Очевидно, що до всього сказаного добре підходить рекомендаційна система на базі колаборативної фільтрації — її прототип ми реалізували. Такі системи зараз повсюдні, нічого нового ми не зробили, однак зібрати її на наявних даних було цікаво.
Вся обробка даних велася стандартними інструментами Python: Jupyter, numpy, pandas, sklearn. Кілька важливих, хоча й очевидних речей:
  • Робота з Excel таблицями здійснювалася через xlrd, хоча, звичайно, ніщо не заважало нам скористатися стандартним імпортом Excel з pandas:
    pandas.read_excel
    .
  • One-hot encoding посад. Ми представили посаду співробітника у вигляді вектора довжиною в число унікальних посад. Всі значення цього вектора — нулі, крім однієї одиниці навпроти його посади. Відповідно, кодуючи посади всіх співробітників, ми отримуємо розріджену матрицю розмірності M x N, де M — це кількість унікальних посад, а N — кількість співробітників.
  • Нормалізація безперервних значень. В
    sklearn.preprocessing
    є клас
    MinMaxScaler
    , що дозволяє привести наші значення у потрібний діапазон, за замовчуванням в діапазон
    [0, 1]
    . В результаті ми отримали 173 ознаки, кожен з яких (у тому числі, one-hot encoded) може мати значення в інтервалі від нуля до одиниці.

Наступна задача — визначення міри схожості різних співробітників один з одним. Схожим співробітникам ми рекомендуємо схожі курси. У термінах рекомендаційних систем, це коллаборативная фільтрація User-User. Найпростіший спосіб — використовувати косинусную міру. Ми представляємо кожного співробітника як вектор у 173-мірному просторі і попарно для кожних двох співробітників вважаємо косинус кута між векторами:

Фактично, знаючи скалярний добуток і норму векторів, ми можемо порахувати, наскільки два співробітника «схожі». В рамках sklearn це робиться в один рядок:
sklearn.metrics.попарно.cosine_similarity(df_profiles.iloc[:,1:])

Ми отримуємо матрицю розмірністю N x N, де N — число співробітників. Кожне значення у матриці — міра подібності двох співробітників. Нам хотілося додати нелінійності до цієї міри, щоб сильніше підкреслити подібність або відмінність двох співробітників:
def norm_cos(x):
if $ x < 0.25: return x / 10
if $ x < 0.5: return x / 5
if $ x < 0.75: return x / 2
return x

Далі ми взялися за датасет з курсами. Фактично, потрібно зробити нормалізацію оцінок курсів з допомогою базових предикторів співробітників (users) і курсів (items). «Оцінка» курсу — це просто сума кількості разів, що кожен співробітник пройшов даний курс (або вебінар, або переглянув електронний документ на порталі). Порахувавши базові предиктори, ми можемо прибрати зміщення оцінки. Наприклад, якщо один співробітник проходить багато курсів, його оцінка буде домінувати і сильно спотворювати рекомендації. Такі спотворення добре виявляються і знижуються базовими предикторами.
Одержавши дві матриці: матрицю подібності співробітників і нормалізовану базовими предикторами матрицю оцінок курсів, ми можемо їх перемножити і, таким чином, отримати оцінку кожного курсу (item) для кожного співробітника (user). Для рекомендації курсів, ми можемо взяти потрібну кількість курсів з найвищими оцінками:

Як ми бачимо, рекомендацій курсів для комірника у нас, фактично, немає. Зате для керуючого ми можемо щось порадити.
Рішення завдання #2
Зібравши датасет з співробітниками, нам захотілося спробувати розв'язати другу задачу: розкопати цікаву закономірність даних і, в ідеалі, теж перетворити її в продукт. Ми сформулювали тезу — якщо співробітник за сукупністю своїх характеристик веде себе так, як співробітник більш високої посади (наприклад, продавець, старший продавець), то було б цікаво це визначити і дати сигнал його керівнику.
Ми вирішили використовувати техніку зниження розмірності на основі методу головних компонент (PCA), залишивши дві компоненти. Такі результати PCA легше візуалізувати і їх можна показати керівництву.
Після трансформації, ми кластеризовали результати PCA за допомогою K-Means. Число кластерів підбирали за допомогою середнього silhouette score кластерів. Чим вище даний показник, тим краще кластери невід'ємні один від одного.

K-Means виділив 10 кластерів в цьому датасете. Як бачимо, кластер #3 розташовується далі всіх інших і чітко відділити від інших — тому його silhouette score вище інших. Червона вертикальна лінія на лівій діаграмі — середній показник.
Що нам дає така кластеризація? Виявилося, що наша кластеризація вийшла фактично з посад і «трохи чогось ще». Наприклад, кластер #0 — це здебільшого продавці-касири, а кластер #5 — старші продавці-касири. Але іноді в кластері #5 ми бачимо і простих касирів.
У вихідному датасете у нас було багато інформації про продуктивності співробітників та їх навчання. Тому при зменшенні розмірності і кластеризації ця інформація дозволила віднести двох різних за посадою людей до одного кластера.


Замість висновку
Які висновки особисто ми зробили після хакатона?
По-перше, не можна недооцінювати час на обробку даних. У нас пішло колосальну кількість часу на конвертацію, обробку, генерацію функцій, нормалізацію і обробку ознак з пропущеними значеннями. Без попередньої обробки повноцінний аналіз даних був би проблематичний. Ми порахували невдоволення початковими даними непрофесійним і зробили все що могли препроцессингу.
По-друге, ми не винайшли нічого нового. PCA, K-Means, item-item, user-user коллаборативная фільтрація — всі ці техніки давно відомі. PCA і K-Means працюють практично «з коробки» в sklearn. Однак, якщо накласти їх на конкретну задачу, вони здатні здивувати людей, які до цього нічого подібного не бачили.
В-третіх, дуже важливо вміти презентувати свій проект. Пам'ятайте, що працюючий прототип, зроблений на коліні і навчений на кускових даних, краще, ніж будь-теоретично коректне рішення або аналіз, але без демонстрації справжнього, живого продукту, який можна помацати.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.