Як ми використовуємо ланцюги Маркова в оцінці рішень та пошуку багів. Зі скриптом на Python

Нам важливо розуміти, що відбувається з нашими студентами під час навчання, і як ці події впливають на результат, тому ми вибудовуємо Customer Journey Map карту клієнтського досвіду. Адже процес навчання — не щось безперервне і цільне, це ланцюжок взаємопов'язаних подій та дій студента, причому ці дії можуть відрізнятися у різних учнів. Ось він пройшов урок: що він зробить далі? Чи піде в домашнє завдання? Запустить мобільний додаток? Змінить курс, попросить змінити вчителя? Відразу зайде наступного уроку? Чи просто піде розчарованим? Чи можна, проаналізувавши цю карту, виявити закономірності, що призводять до успішного закінчення курсу чи навпаки, «відвалення» студента?

Як ми використовуємо ланцюги Маркова в оцінці рішень та пошуку багів. Зі скриптом на Python

Зазвичай для будівництва CJM використовують спеціалізовані, дуже дорогі інструменти із закритим кодом. Але нам хотілося вигадати щось просте, що потребує мінімальних зусиль і по можливості опенсорсне. Так з'явилася ідея скористатися ланцюгами Маркова і в нас вийшло. Ми збудували карту, інтерпретували дані про поведінку студентів у вигляді графа, побачили зовсім неочевидні відповіді на глобальні питання бізнесу і навіть знайшли глибоко заховані баги. Все це ми зробили за допомогою пенсійних рішень Python-скрипту. У цій статті я розповім про два кейси з тими неочевидними результатами і поділюся скриптом з усіма бажаючими.

Отже, ланцюги Маркова показують можливість переходів між подіями. Ось примітивний приклад із Вікіпедії:

Як ми використовуємо ланцюги Маркова в оцінці рішень та пошуку багів. Зі скриптом на Python

Тут "E" і "A" - події, стрілочки - переходи між ними (у тому числі і перехід з події в нього ж), а ваги стрілочок - ймовірність переходу ("зважений орієнтований граф").

Що використовували

Ланцюг навчався стандартним функціоналом Python, якому згодовувалися логи активності студентів. Граф на отриманій матриці будувався бібліотекою NetworkX.

Лог виглядає так:

Як ми використовуємо ланцюги Маркова в оцінці рішень та пошуку багів. Зі скриптом на Python

Це csv-файл, що містить таблицю з трьох стовпців: id студента, найменування події, час, коли вона сталася. Цих трьох полів достатньо, щоб простежити рух клієнта, побудувати карту і в результаті отримати ланцюг Маркова.

Бібліотека повертає збудовані графи у форматі .dot або .gexf. Для візуалізації перших можна скористатися безкоштовним пакетом Graphviz (інструмент gvedit), ми працювали з .gexf та Gephi, теж безкоштовною.

Далі хочу навести два приклади використання ланцюгів Маркова, які дозволили нам по-новому поглянути на наші цілі, навчальні процеси та саму екосистему Skyeng. Та й підправити баги.

Перший кейс: мобільний додаток

Для початку ми дослідили шлях студента за найпопулярнішим продуктом — курсом General. На той момент я працював у дитячому департаменті Skyeng і ми хотіли подивитися, наскільки ефективно працює мобільний додаток з нашою дитячою аудиторією.

Взявши логи та прогнавши їх через скрипт, я отримав щось таке:

Як ми використовуємо ланцюги Маркова в оцінці рішень та пошуку багів. Зі скриптом на Python

Стартовий вузол — Start General, а внизу три вихідні ноди: учень заснув, змінив курс, закінчив курс.

  • Fell asleep, «Заснув» - значить, більше не проходить заняття, швидше за все, він відвалився. Ми оптимістично називаємо цей стан заснув, т.к. теоретично у нього зберігається можливість продовжити навчання. Найгірший результат для нас.
  • Dropped general, Змінив курс - перейшов з General на щось інше і загубився для нашого ланцюга Маркова.
  • Finished course, Закінчив курс - ідеальний стан, людина пройшла 80% уроків (не всі уроки обов'язкові).

Попадання в ноду successfull class означає успішне проходження уроку на нашій платформі разом із учителем. Вона фіксує просування курсом і наближення до бажаного результату — «Закінчив курс». Нам важливо, щоб студенти відвідували її якнайбільше.

Щоб отримати більш точні кількісні висновки для мобільного додатка (нода app session), ми побудували окремі ланцюги для кожного з фінальних вузлів і далі порівнювали поваги ваги ребер:

  • з app session назад до неї;
  • з app session у successful class;
  • з успішного класу в app session.

Як ми використовуємо ланцюги Маркова в оцінці рішень та пошуку багів. Зі скриптом на Python
Зліва – студенти, які завершили курс, праворуч – «заснули»

Ці три ребра показують зв'язок між успішністю студента та використанням ним мобільного додатка. Ми очікували побачити, що у студентів, що закінчили курс, зв'язок з додатком буде сильнішим, ніж у «заснулих». Однак насправді отримали рівно протилежні результати:

  • ми переконалися, що різні групи користувачів по-різному взаємодіють із мобільним додатком;
  • успішні студенти менш інтенсивно використовують мобільний додаток;
  • студенти, що засипають, активніше використовують мобільний додаток.

Це означає, що студенти, що «засипають», починають все більше часу проводити в мобільному додатку і врешті-решт залишаються в ньому назавжди.

Як ми використовуємо ланцюги Маркова в оцінці рішень та пошуку багів. Зі скриптом на Python

Спочатку ми здивувалися, але, подумавши, зрозуміли, що це цілком закономірний ефект. Свого часу я самостійно вивчав французьку, використовуючи два інструменти: мобільний додаток та лекції з граматики на YouTube. Спочатку я ділив час між ними в пропорції 50 на 50. Але програма веселіша, там гейміфікація, там все просто, швидко і зрозуміло, а в лекції треба вникати, щось записувати, практикуватися в зошиті. Поступово я став більше часу проводити в смартфоні, поки його частка не доросла до 100%: якщо провисіти в ньому три години, створюється хибне відчуття виконаної роботи, через яке йти і щось слухати нема ніякого бажання.

Але як так? Адже ми спеціально створювали мобільний додаток, вбудовували в нього криву Еббінгауза, Гейміфікували, робили його привабливим, щоб люди проводили в ньому час, а виявляється, воно їх тільки відволікає? Насправді причина в тому, що команда мобільного додатка дуже добре впоралася зі своїми завданнями, внаслідок чого вона стала класним самодостатнім продуктом та почала вивалюватися з нашої екосистеми.

У результаті дослідження прийшло розуміння, що мобільний додаток треба якось змінювати, щоб він менше відтягував від основного курсу навчання. Причому і дитяче та доросле. Нині ця робота ведеться.

Другий кейс: баги онбордингу

Онбординг - необов'язкова додаткова процедура під час реєстрації нового учня, що позбавляє потенційних технічних проблем у майбутньому. Базовий сценарій має на увазі, що людина зареєструвалася на лендингу, отримала доступ до особистого кабінету, з ним зв'язуються і проводять вступний урок. При цьому ми відзначаємо великий відсоток технічних труднощів під час вступного уроку: не та версія браузера, не працює мікрофон чи звук, вчитель не може відразу підказати рішення, і все це особливо складно, якщо йдеться про дітей. Тому ми розробили додатковий додаток в особистому кабінеті, де можна виконати чотири прості кроки: перевірити браузер, камеру, мікрофон і підтвердити, що батьки будуть поруч під час вступного уроку (адже саме вони платять за навчання дітей).

Ці кілька сторінок онбордингу демонстрували таку вирву:

Як ми використовуємо ланцюги Маркова в оцінці рішень та пошуку багів. Зі скриптом на Python
1: стартовий блок з трьома трохи різняться (залежно від клієнта) формами введення логіна-паролю.
2: галка згоди на додаткову процедуру онбордингу.
2.1-2.3: перевірка присутності батька, версії Chrome та звуку.
3: фінальний блок.

Виглядає вона дуже природно: на перших двох кроках більшість відвідувачів зливається, зрозумівши, що тут треба щось заповнювати, перевіряти, а часу немає. Якщо клієнт дійшов до третього кроку, далі він уже майже напевно дійде до фіналу. На вирві не видно жодної причини, щоб щось запідозрити.

Все ж таки ми вирішили проаналізувати наш онбординг не на класичній одновимірній вирві, а за допомогою ланцюга Маркова. Включили трохи більше подій, запустили скрипт і отримали таке:

Як ми використовуємо ланцюги Маркова в оцінці рішень та пошуку багів. Зі скриптом на Python

Однозначно зрозуміти у цьому хаосі можна лише одне: щось пішло не так. Процес онбордингу - лінійний, це закладено дизайном, в ньому не повинно бути такої мережі зв'язків. А тут відразу видно, що користувача кидає між кроками, між якими взагалі не повинно бути переходів.

Як ми використовуємо ланцюги Маркова в оцінці рішень та пошуку багів. Зі скриптом на Python

Причини такої дивної картини може бути дві:

  • косяки закралися в основу логів;
  • косяки присутні у самому продукті – онбордингу.

Перша причина, швидше за все, має місце, але перевірити її досить трудомістко і виправлення логів ніяк не допоможе поліпшити UX. А ось із другої, якщо вона є, треба було терміново щось робити. Тому ми вирушили розглядати вузли, виявляти ребра, яких не повинно бути, шукати причини їх виникнення. Побачили, що деякі користувачі зациклювалися і ходили по колу, інші — вивалювалися з середини на початок, треті не могли вибратися з перших двох кроків. Передали дані в QA - і так, з'ясувалося, що в онбордингу вистачало багів: це такий побічний, трохи милий продукт, його не тестували досить глибоко, т.к. не чекали жодних проблем. Нині вже весь процес запису змінився.

Ця історія показала нам несподіване застосування ланцюгів Маркова у сфері QA.

Спробуйте самі!

Я виклав свій Python-скрипт для навчання ланцюгів Маркова у відкритий доступ – користуйтеся на здоров'я. Документація на GitHub, питання можна ставити тут, постараюся на все відповісти.

Ну і корисні посилання: бібліотека NetworkX, візуалізатор Graphviz. А ось тут на Хабрі є стаття ланцюги Маркова. Графи у статті зроблені за допомогою Гефі.

Джерело: habr.com

Додати коментар або відгук