Результат мечта


Facebook опубликовал статью о так называемом aha-moment, в которой утверждалось, что если пользователь добавляет 7 друзей в течение 10 дней после регистрации, то этот пользователь остается на сервисе.

Почему этот результат (aha-момент) такой притягательный?
Потому что он:
а) простой
б) осмысленный
в) actionable


Когда есть такой результат, сервису остается просто сделать все, чтобы мотивировать пользователей добавлять 7 друзей в первые 10 дней, и тем самым идти к более высокой цели: “увеличению retention rate”.

А сможем ли мы повторить?




Конечно же, любой сервис хочет найти свой aha-moment. Причем желательно, чтобы вот такой же простой, как у Facebook: чтобы все просто и понятно, и без всяких абстракций аналитиков, латентных признаков и прочего.

Мы в Lingualeo попытались решить задачку: не стырить решение у Facebook, а придумать свое, о котором и расскажет ниже Константин Терешин (как жаль, что он уже не с Лео)

Постановка задачи


Сделаем одну оговорку: мы хотели, чтобы наш aha-moment был такой же простой и понятный, как и результат Facebook, и редуцировался до конкретных действий пользователя. Это было основным требованием к результату.

Теперь к задаче


В любой исследовательской задаче первое дело — это определиться с понятиями. Что вы будете иметь в виду под понятиями “пользователь останется”, “станет лояльным”, “не оттечет” и тому подобное. Здесь у каждого своя правда, каждый сервис понимает это по-своему. Ну, и мы ввели собственное определение лояльности. Не станем утомлять вас деталями этой дефиниции. Здесь важно то, как мы работали с этим признаком. Единственное, что нужно отметить, лояльность — это биноминальная переменная и принимает значение 0 — если пользователь не стал лояльным, 1 — если стал. Это наша целевая переменная.

Теперь, когда мы определились с целевым признаком, осталось формализовать, что же значит “найти aha-moment”?

Например, найти переменную и значение, при котором вероятность пользователей стать лояльными, максимальна.
Но это не вариант, поскольку так можно “закручивать гайки” до максимума. Понятное дело, что чем больше пользователь потренирует (выучит) слов, тем больше вероятность, что он стат лояльным. Но это непростой результат.

Или, например, можно пойти по логике ассоциативных правил и найти отранжированый по support список правил вида: значение переменной => событие лояльности.
Хороший вариант, НО, переменные у нас (о них позже) зачастую имеют широкий диапазон значений, и в результате словарь событий будет содержать десятки тысяч позиций. Следовательно, значимых результатов мы не получим.

В итоге мы остановились на следующей логике: найти переменную и ее значение, которое определяет границу смены тренда вероятности пользователя стать лояльным.
Например:
Пусть у нас есть переменная. Вероятность стать лояльным имеет следующее распределение:


На графике видно, что тренд кривой меняется на значении 5-6. После этого вероятность стать лояльным стремительно растет. То есть мы должны найти такую переменную и такое ее значение, после которого вероятность начинает максимально расти.

Немного о данных


Для нас было важно определить aha-moment на первых двух неделях после регистрации (каждый сам для себя определяет нужный период, исходя из специфики бизнеса). Поэтому мы внимально посмотрели на этот период и нагенерили порядка 750 переменных для анализа. Среди них: что делали пользователи, сколько раз делали, как часто делали, что делали в конкретный день после регистрации и прочее-прочее-прочее.

И еще несколько замечаний:
Анализ мы проводили только по пользователям мобильных приложений Lingualeo
Отдельно Android и iOS

В итоге:
Для Android получили выборку (количество пользователей 240 862 х количество переменных 751)
Для IOS получили выборку (количество пользователей 73 712 х количество переменных 751)

Как решали задачу


Понятное дело, что руками отсмотреть 750 переменных, найти из них лучшую и то самое значение — это занятие не для ленивых. Поэтому хотелось все это автоматизировать.

Мы разбили задачу на 2 этапа:
Отбор “важных” переменных
Поиск “верной” границы.

Начнем с поиска верной границы.
Пусть у нас есть признак 1 и целевой признак. Как найти значение, которое разделит выборку идеально таким образом, чтобы уловить смену тренда?
Когда мы думали над этой задачей, возникла идея построить дерево решения глубиной 1 и на одной переменной.
На самом деле, задача дерева решения — минимизировать сложность системы, т.е. подобрать такое расщепление по переменной, при котором уровень хаоса системы уменьшится, причем для оценки хаоса есть внятный критерий. Мы использовали Энтропию.
Какой в этом смысл для нашего случая? Так как мы имеем лишь два класса в целевом признаке (0 — не лояльный, 1 — лояльный), то при построении дерева решения глубиной 1 на признаке 1 (priznak_1) мы получим одно расщепление вида (данные фейковые):


В результате, граница подобрана таким образом, чтобы был соблюден идеальный баланс между вероятностью класса 1 по одну сторону расщепления и вероятностью класса 0 — по другую. Формально же мы получили максимальный “прирост информации” (information gain).

По сути это и есть граница, которая нам нужна.

Важный комментарий: в конечном итоге мы все же не решаем задачу классификации и нам не требуется строить более грубокое дерево, поэтому о переобучении говорить нет смысла, скорее об underfitting. Но это нас устраивает.

Теперь, когда мы понимаем, как искать границу, нужно отобрать и отранжировать переменные.
Здесь также ничего сверхъестественного: многие ансамблевые методы обучения имеют метод feature_importances_ в scikit-learn. Мы использовали random forest с 1000 деревьев глубиной 10, в качестве метрики использовали f1 score. На выходе мы получили отранжированный список переменных. Как это обыкновенно бывает, важность переменных имеет степенное распределение (наш случай не исключение), и самая важная переменная с отрывом уходит вперед. Мы решили остановиться на ней.

Что получили


Самая важная переменная — это количество дней, в течение которых пользователь получал опыт на сервисе.

Хороший ли это результат?
И да, и нет. С одной стороны, мы понимаем после скольких дней на сервисе происходит “переломный момент”, пользователь начинает им активно пользоваться, и можем это использовать, с другой — мы не понимаем, а что именно он делает.

И что нам делать дальше, ведь нужного результата мы не достигли?
А дальше все просто. После того, как у нас появилась “базовая” граница, остается понять, чем отличаются пользователи слева и справа от границы. И мы пошли тем же путем, что и ранее, так как задача опять же заключалась в поиске идеальной границы, но уже по тем фичам, которые отражают конкретные действия пользователей: тренировки слов, добавления слов, изучение тестов, тренировки грамматики и прохождения курсов. Но теперь у нас отличается целевой признак: 1 — справа от “базовой” границы, 0 — слева от нее.

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

Нам понравилось упражнение, надеемся, понравится и вам:)

Но следует добавить несколько комментариев по поводу результата, и как на него нужно реагировать.
1) Результат отражает текущую механику взаимодействия пользователей с сервисом. Если сервис изменится, может измениться и вся логика взаимодействия с ним.
2) На самом деле, наш результат — суть сильные гипотезы, так как, если мы внедрим продуктовую фичу или маркетинговую активность, мотивируем пользователей достигать границ, которые мы нашли, далеко не факт, что они сразу станут лояльными. Это придется тестировать.

P.S.: а еще у нас есть вакансии аналитиков! Приходите к нам работать!