Задача: исследовать данные о прохождении игроками уровней match3-игры и выполнить следующие задания:
1. Определить DAU (Daily active users).
2. Определить распределение игроков по уровням.
3. Предложить метрику, описывающую сложность уровней и рассчитать ее.
4. Если в процессе исследования будут обнаружены любые интересные факты - будет плюсом, если они будут указаны и визуализированы

Файл с иходными данными содержит 147,893,968 наблюдений по 4 параметра в каждом: идентификатор игрока, результат раунда, уровень раунда и дата. Всего в датасете присутствует 1,178,906 уникальных пользователей за период в 33 дня, количество уровней – 525.

1. Определить DAU (Daily active users)

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

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

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

2. Определить распределение игроков по уровням

Всего в датасете 525 уровней. В зависимости от того, как разбивать данные по столбцами (количество уровней в столбце) гистограмма может выглядеть по-разному. Здесь представлены гистограммы по 25 уровней в столбце, а уровнем игрока считается его максимальный уровень за день.

Если рассматривать распределение игроков по уровням в разрезе суток, то для каждого из дней гистограмма имеет один и тот же вид с модой на 25-50 уровнях. Например, для 19/01/2016:

Если рассматривать рапределение игроков за весь доступный период, то гистограмма имеет другой вид, здесь уже наибольшая группа игроков та, которая не преодолела 25 уровень:

Ширина столбца съедает некоторые особенности распределения, такие как резкие перепады от уровня к уровню. Например, данные по количеству игроков с 25 по 35 уровень).

##     lvl      n
##  1:  25  10437
##  2:  26 140087
##  3:  27   2581
##  4:  28   4004
##  5:  29 101133
##  6:  30   1481
##  7:  31   5935
##  8:  32  41463
##  9:  33   2259
## 10:  34   1879
## 11:  35   9846

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

Пики и спады связаны, скорее всего, со сложностью уровней. Так, на 26 уровне застряло более 140 тысяч игроков, а на 27-28 по несколько тысяч, т.е. их оказлось легче пройти. На 29 опять резкий пик в 100 тысяч и т.д. Действительно, если посчитать корреляцию между количеством игроков, которые остались на своих уровнях и число попыток, которое было приложено для прохождения каждого уровня, то окажется, что связь очень сильная, а сам коэффициент статистически значим (здесь вычислялась корреляция Спирмена, она устойчива к выбросам и интерес представляет именно соотношение рангов этих величин).

## 
##  Spearman's rank correlation rho
## 
## data:  tbl_lvl$n and dif$n
## S = 794750, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##      rho 
## 0.967046

3. Предложить метрику, описывающую сложность уровней и рассчитать ее

При имеющихся данных логично оценить сложность уровней как отношение количества неуспешных попыток прохождения к их общему числу. Тогда график сложности от уровня будет выглядеть так:

##     level       rate      n      f
##  1:     1 0.02582849 668448  17265
##  2:     2 0.08157874 676414  55181
##  3:     3 0.10002781 665115  66530
##  4:     4 0.03793129 607625  23048
##  5:     5 0.19318605 701091 135441
##  6:   521 0.49062500    320    157
##  7:   522 0.26976744    215     58
##  8:   523 0.34745763    236     82
##  9:   524 0.21649485    194     42
## 10:   525 0.34934498    229     80

Полученное значение можно трактовать, как 1-вероятность прохождения уровня. Недостаток такой метрики видится в том, что разное количество игроков и попыток приходится на каждый уровень, поэтому границы в которых может изменяться доля – разные. Для примера можно сравнить 17 и 524 уровень. У них близкая доля завершения уровня (0.26 и 0.22 соответственно). Наблюдений достаточно, чтобы сделать вывод о статистической значимости полученных значений, p-value очень мало (а т.к. 524 уровню в данных соответствует наименьшее количество наблюдений, то значения всех долей можно считать статистически значимыми). Ширины доверительных интервалов для обеих долей сильно отличаются:

##    level      f      n      rate
## 1:    17 135870 513926 0.2643766
## 2:   524     42    194 0.2164948
## 
##  1-sample proportions test with continuity correction
## 
## data:  as.matrix(dif[level == 17, .(f, n - f)]), null probability 0.5
## X-squared = 114130, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 99 percent confidence interval:
##  0.2627941 0.2659651
## sample estimates:
##         p 
## 0.2643766
## 
##  1-sample proportions test with continuity correction
## 
## data:  as.matrix(dif[level == 524, .(f, n - f)]), null probability 0.5
## X-squared = 61.242, df = 1, p-value = 5.047e-15
## alternative hypothesis: true p is not equal to 0.5
## 99 percent confidence interval:
##  0.1482092 0.3041503
## sample estimates:
##         p 
## 0.2164948

Из-за большого количества попыток пройти 17 уровень доля его прохождения определена уверенно, но для 524 уровня это не так: сама доля равно 0.22, но ее доверительный интервал от 0.15 до 0.30 и в сравнении нет определенности какой из уровней сложнее.

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

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

Таким образом, можно ввести коэффициент коррекции исходной метрики (доли) используя рассчитаные параметры. Этот коэффициент должен зависеть от следующих параметров: * от уровня, чем дальше уровень, тем в целом игра становится сложнее (level), его большие значения зажимают начальные уровни (компенсируется шириной); * от количества игроков, которые не смогли пройти на следующий уровень (1 - pass_rate), т.к. не все игроки в датасете находятся на одном уровне сначала; * от ширины доверительного интервала посчитаной доли для уровня (хотя использование этого парамета спорно, он работает, если выполняется предпосылка, что сложность уровней, в целом, растет с течением игры), с его помощью можно корректировать общий тренд сложности уровней и корректировать разброс для соседних уровней.

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

\[metric = complete\_rate \cdot \frac {a \cdot level + b \cdot width + c \cdot (1-pass\_rate ) + d}{a+b+c+d}\]

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

Если подобрать коэффициенты, то график скорректированного коэффициента сложности выглядит так (для a=0.02, b=100, c=10, d=10):

Параметры a, b, c, d скорее выбраны из эстетических соображений. Такую метрику можно откалибровать и сделать более объективной, если использовать оценки эксперта: например, рейтинги гейм-дизайнера/тестеров или рассчитать ранги сложности алгоритма (скажем, насколько часто на данном уровнем выпадают удачные комбинации уже может объяснять сложность). Имея экспертную оценку мера сложности можно уточнить используя машинное обучения или ориентируясь на ранговые методы (например, корреляцию Спирмена/Кендалла).

Возможно, имеет смысл дискретизировать полученную метрику и свести его к узкому интервалу значений, пусть от 1 до 20 (коэффициент все равно перестал быть интерпретируемым), тогда уровни удобнее сравнивать между собой, легко найти уровни одинаковой сложности, немного сложнее, существенно сложнее и т.д. В этом случае график примет вид:

В зависимости от значения метрики сложности, уровни игры распределены следующим образом:

Резюмируя, доля проигранных игр хорошо описывает сложность уровней, а главное – это величина интерпретируема. Ее недостаток кроется в том, что с возрастанием уровня, его точность доли может существенно упасть. Поэтому для доли можно рассчитать коэффициент корректировки, который зависит от номера уровня, доли игроков, прошедших уровень и ширины доверительного интервала, но в этом случае желательна калибровка метрики.

***

Используя данные по пользователям можно выявить тех из них, кто сильно отличается от основной массы. Здесь в небольшом примере применялся метод опорных векторов, где в качестве ядра использовалась радиальная базисная функция. В качестве исходных данных по каждому пользователю была обрабатывалас следующая информация: level – уровень игрока (за все время), progress – сколько уровней прошел игрок, n – количество игровых раундов (попыток), comlete_rate – доля успешно пройденных раундов, days – количество дней в игре и speed – среднее число уровней, проходимых игроком в день. Данные об одиннадцати наиболее отличающихся игроков приведены в таблице. Этих пользователей можно разделить на три группы:

Для визуализации все данные отображены в координатах главных компонент (первые 2 компоненты описывают 80% дисперсии). “Аномальные” пользователи имеют более темный цвет.

uid level progress n complete_rate days speed
6b55c6812ceabcd81033a1c3b2925134 334 333 18 0.667 1 333.000
b3e3c7f8ec3e4b68dd7a4476ec996a41 235 234 33 0.758 1 234.000
9b73922d26b85f772421931e84bf3c17 235 234 86 0.547 1 234.000
16cad53f6d2a41d9841d0ff5d4bf06a7 525 524 527 0.996 28 18.714
6f772664f3a50e16fbf72860bbb46626 498 489 533 0.919 31 15.774
2b9c230218e3ace1fc3204dda60110c1 525 519 551 0.944 31 16.742
72ef1fc53014a5674693810f3727dc90 525 524 643 0.816 27 19.407
70b19b3eeccfe948f2a300ae6c64dbda 277 151 3129 0.041 32 4.719
9f8081062efffbe549a00aecdea6b90f 345 121 3155 0.054 33 3.667
2c86585d0477cf06d68265dfc3b19133 261 218 3743 0.041 32 6.812
3fe5aa956570f92b105629ee08e5c724 438 222 4459 0.050 33 6.727

Перевод в главные компоненты, как видно из графика не дает внятного разделения пользователей на группы, а продвинутый метод, например, tSNE будет работать относительно долго, хотя слишком плавное изменение данных не позволяет надеяться на “красивое” разделение пользователей на кластеры. Тем не менее, как можно судить по таблице выше, каждой из групп игроков соответствуют свои особенные, отличительные значения параметров, которые можно использовать в качестве отправных точек для дальнейшей кластеризации пользователей.