Событийная аналитика

By | 2015-01-15

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

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

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

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

“Игрок Вася Пупкин в такое-то время совершил такое-то действие вот таким образом, находясь вот в в таком состоянии”.

Но когда машина общается с машиной, как правило, применяется особый формализованный язык. Часто это XML или JSON. Мы будем использовать второй, его достаточно легко читать и человеку.

Любое событие должно быть представлено в виде одномерного массива пар ключ:значение.

Посмотрим на следующий пример:

{

  • “event”: “inapp_purchase”,
  • “user”: “Vasya Pupkin”,
  • “time”: “2015-01-14 18:00:00”
  • “object”: “coins”,
  • “coin_value”: 1000,
  • “price”: 100,
  • “sex”:”m”,
  • “age”:40,
  • “level”:10,
  • “install_date”:  “2015-01-13  00:00:00”

}

Произошло событие – внутриигровая покупка, кто совершил – Вася Пупкин, в какое время – “2015-01-14 18:00:00”, что купил – монетки, сколько монеток – 1000, сколько рублей потратил – 100, пол – мужик, возраст – 40, уровень игрока – 10,  день установки игры Васей –  “2015-01-13  00:00:00”. Ничего сложного на первый взгляд.

Но дьявол в деталях, а именно в следующем. Иногда происходит желание вместить в название ключа (то есть в название измеряемого параметра) смысл значения и наоборот. Старайтесь ни в коем случае не допускать этого!

Классический пример: в паре object: “coins” в значении мы могли бы сразу указать объем лота (т.е. кол-во купленных монеток, который у нас выделен в отдельный параметр coin_value). Получилась бы в нашем случае такая пара:

object: “coins_1000”

Не говоря уже о простом неудобстве, проблемы могут начаться сразу, как только мы захотим изменить кол-во монеток в данном лоте.  Нам придется менять значения параметра object на, скажем,  “coins_1300”. Но тогда в статистике это уже будет отдельная сущность, что может привести к плохим последствиям.

 

Проектирование структуры событий

Структура событий должна быть представлена в виде иерархической системы. Я рекомендую использовать Excel-таблицы, получается удобно. Рассмотрим пример с таким простым событием, как трата виртуальной валюты.

Итак,  у нас уже есть первая пара: event: “currency_spend”. Далее мы должны спросить себя, а что мы хотим узнать об этом событии? В игре есть два типа виртуальной валюты – hard (кристаллы) и soft (монетки). Ага, значит ключ здесь – тип виртуальной валюты, а значения – “diamonds” и “coins”:

1 

Думаем дальше. Что еще мы хотим знать? Конечно, сколько валюты потратил игрок. Ключом пусть будет “amount”, а в ячейку значения вставим тег %n%, где n  – это переменная, означающая объем потраченной валюты.

Разумеется нужно указать, на что именно была потрачена валюта. Будем считать, что в игре у каждого объекта, на который можно потратить валюту, есть уникальный id. Итак, ключ target_id, значение – %id%.

2

На этом можно было бы остановиться. Но мы ведь аналитики, нам нужно больше данных! Target_id сам по себе нам ничего не даст. Копаем дальше. Какие типы трат существуют в игре?  Мы можем купить конкретную “вещь” (семена, домик, лейку, украшение и т.д.), можем ускорить что-то в игре (постройку здания, выращивание растения или животного и т.д.), можем пропустить сложный квест, а еще можем разблокировать к покупке что-то, что доступно только “эльфам 80-уровня”. Добавляем ключ target_type и 4 возможных значения: buy, accelerate, skip, unlock.

Но у каждого из этих типов есть подтипы! Как быть? В этом случае для каждого нового “уровня вложенности” в таблице создаем еще два столбца для пары ключ-значение (ниже будет скрин).

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

Теперь accelerate – ускорение. Ускорить можно рост растения или животного, производство чего-либо в определенной постройке или процесс апгрейда здания. Но у апгрейда и производства есть разные уровни. Хотелось бы знать, например, производство какого уровня было ускорено.

Итоговая структура данного конкретного “события” будет выглядеть так:

3

Таким образом, событие “произошла трата монеток в кол-ве 100 штук на объект – молочная ферма с целью ускорить производство 5 уровня” будет выглядеть так:

{

  • “event”: “currency_spend”,
  • “type”:”coins”,
  • “amount”: 100,
  • “target_id”: “milky_farm”,
  • “target_type”: “accelerate”,
  • “subtype”:”production”,
  • “prod_lvl”:5

}

Чего-то не хватает… Точно, куда делся Вася Пупкин? Мы обязательно должны включить информацию о Васе. Но нет смысла указывать эти параметры именно внутри currency_spend, так как знать, с кем связано событие надо всегда, какое бы событие мы ни отправляли.

Параметры, которые отправляются в любом событии независимо от его типа, иногда называются суперпараметрами. Часть мы уже упоминали в первом примере.

Таким образом полное событие будет выглядеть следующим образом:

{

  • “event”: “currency_spend”,
  • “type”:”coins”,
  • “amount”: 100,
  • “target_id”: “milky_farm”,
  • “target_type”: “accelerate”,
  • “subtype”:production,
  • “prod_lvl”:5
  • “user”: “Vasya Pupkin”,
  • “time”: “2015-01-14 18:00:00”
  • “sex”:”m”,
  • “age”:40,
  • “level”:10,
  • “install_date”:  “2015-01-13  00:00:00”,
  • “paying_status”: “whale”,
  • “referer”: “ad_facebook_target”

}

 

По похожему принципу создаются все остальные события. Стоит отметить, что достаточно отправлять всего лишь три типа события: “установка”, “вход в игру” и “покупка за реал”, чтобы можно было создать собственную систему аналитики со всеми стандартными базовыми метриками (DAU, retention, ARPU и т.д.)

Пример с currency_spend характеризует так называемые custom events (“пользовательские” события), анализ которых позволяет понять работу игровой механики.

В этой статье я не стану рассказывать о технологиях. Скажу лишь, что по большей части это дело вкуса. Возможность отправки custom events существует во многих платных (Upsight, Mixpanel и др) и бесплатных системах аналитики (Flurry, Google Analytics). Во многих есть серьезные ограничения, как на кол-во параметров в событии, так на само кол-во событий. Многие предпочитают создавать собственные системы на основе различных технологий. Я так или иначе работал с MongoDB, ElasticSearch и обычной MySQL, которая вполне справлялась со своей задачей. Для анализа записанных данных существует целый ряд отдельных инструментов, как платных и так и бесплатных. Kibana, Splunk, Tablue или самописные.

Огромным плюсом при анализе сырых данных будет владение языком программирования R. Рекомендую пройти набор курсов Data Sceince на Coursera

Похожая статья есть в блоге GoPractice. Я во многом согласен с автором, кроме похода к построению структуры событий.

 

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *