Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Сбор и сохранение статистики для портала.
- ========================================
- Для хранения статистики портала используется только одна таблица
- `group_stats`. Данные в нее собираются с помощью fab таска (на данный
- момент ТОЛЬКО вручную).
- Пример, `fab portal.aggregate_partner_stats:partner_space_id=<ps_id>`
- При запуске этого таска выполняется скрипт в `lib/util/group_stats.py`.
- Сурипт берет данные для каждого типа события из определенной таблицы БД:
- Тип события (event_type) | Модель БД
- 'SIGNUP' | User
- 'AL' | ActivityStatus
- 'MAL' | MixpanelUserActivity
- 'HA' | QuizScore
- 'WA' | WorkAssessmentUserAnswer
- 'MEDAL' | ChallengeStatus
- 'RA' | TBD
- 'LD | TBD
- Сохраняются данные только для тех пользователей, у который есть привязка к
- Partner Space (через `<ps_id>` в fab таске)
- Отображение графиков и метрик.
- =============================
- Для всех графиков и метрик используется модель `GroupStats` (файл
- `models/group_stats.py`)
- OVERVIEW
- --------
- * TOTAL SIGNUP - метод `GroupStats.compare_signup(**kwargs)`
- Получить количество зарегистрированных пользователей в выбранном периоде и
- процент изменения по сравнению с предыдущим периодом.
- Параметры запроса (`kwargs`):
- ```
- {
- 'partner_id': 141,
- 'groups_id': [10,20],
- 'year': 2016,
- 'month': 12,
- 'enable_demo_portal': False,
- }
- ```
- Получение ответа:
- * На основе `year`, `month` - находим даты начала и конца ТЕКУЩЕГО периода
- (`first_event`, `last_event`) c помощью вспомогательной функции `get_date_range`
- * Получаем для ТЕКУЩЕГО периода кол-во записей GroupStats (уникальных по `user_id`),
- группы которых содержат `groups_id`,
- partner_id которых равен `partner_id`
- у которых `staff` = false,
- у которых `event_date` в интервале от `start_date` до
- `end_date`,
- у которых `event_type` = `SIGNUP`,
- у которых `demo` = `enable_demo_portal`
- * На основе `year`, `month` - находим даты начала и конца ПРЕДЫУЩЕГО периода
- (`first_event`, `last_event`) c помощью вспомогательной функции `get_date_range_previous`
- * Затем получаем для ПРЕДЫДУЩЕГО периода кол-во записей GroupStats,
- аналогично ТЕКУЩЕМУ, но только с другими `start_date`, `end_date`
- * Высчитываем изменение (`compare_percent`) сравнивая текущий и
- прошлый период.
- * возвращаем ответ
- ```
- {
- 'current_month': 12,
- 'current_year': 2016,
- 'current_count': 50,
- 'previous_year': 2016,
- 'previous_month': 11,
- 'previous_count': 40,
- 'compare_percent': 20 ## 20%
- 'triangle': 'up'
- }
- ```
- * TOTAL ACTIVE USERS - метод `GroupStats.compare_acvive_users(**kwargs)`
- Получить количество активных пользователей в выбранном периоде и
- процент изменения по сравнению с предыдущим периодом.
- Параметры запроса (`kwargs`):
- ```
- {
- 'partner_id': 141
- 'groups_id': [10,20],
- 'year': 2016,
- 'month': 12,
- 'enable_demo_portal': False,
- }
- ```
- Получение ответа:
- * На основе `year`, `month` - находим даты начала и конца ТЕКУЩЕГО периода
- (`first_event`, `last_event`) c помощью вспомогательной функции `get_date_range`
- * Получаем для ТЕКУЩЕГО периода кол-во записей GroupStats (уникальных по `user_id`),
- группы которых содержат `groups_id`,
- partner_id которых равен `partner_id`
- у которых `staff` = false,
- у которых `event_date` в интервале от `start_date` до
- `end_date`,
- у которых `event_type` любой
- у которых `demo` = `enable_demo_portal`
- * На основе `year`, `month` - находим даты начала и конца ПРЕДЫУЩЕГО периода
- (`first_event`, `last_event`) c помощью вспомогательной функции `get_date_range_previous`
- * Затем получаем для ПРЕДЫДУЩЕГО периода кол-во записей GroupStats,
- аналогично ТЕКУЩЕМУ, но только с другими `start_date`, `end_date`
- * Высчитываем изменение (`compare_percent`) сравнивая текущий и
- прошлый период.
- * возвращаем ответ
- ```
- {
- 'current_month': 12,
- 'current_year': 2016,
- 'current_count': 80,
- 'previous_year': 2016,
- 'previous_month': 11,
- 'previous_count': 40,
- 'compare_percent': 50 ## 50%
- 'triangle': 'up'
- }
- ```
- * WEEK-2 RETENTION - `GroupStats.datasets_retention(**kwargs)`
- Получить процент пользователей, которые вернулись во 2 неделю
- после регистрации.
- Параметры запроса (`kwargs`):
- ```
- {
- 'days': 7,
- 'partner_id': 141
- 'groups_id': [10,20],
- 'year': 2016,
- 'month': 12,
- 'enable_demo_portal': False,
- }
- ```
- Получение ответа:
- * На основе `year`, `month` - находим даты начала и конца нужного периода (`first_event`, `last_event`) c помощью вспомогательной функции `get_date_range`
- * Получаем всех пользователей (`user_id`, `event_date as created_at`), из таблицы `group_stats`, у которых `created_at` больше `start_date`, меньше `end_date`, которые состоят в `groups_id`, приписаны к `partner_id` и `staff=false` и `demo=enable_demo_portal` и `event_type=SIGNUP`. То есть все зарегистрированные пользователи за нужный период. Обозначаем эту выборку как `users`
- * Получаем все события из таблицы `group_stats` для которых `event_type` больше `start_date`, меньше `NOW`, которые состоят в `groups_id`, приписаны к `partner_id` и `staff=false` и `demo=enable_demo_portal`
- * Для каждого полученного события проставляем дополнительное поле `first_event` (дата первого события). Обозначаем эту выборку как `events`
- * Далее соединяем `users` и `events` на основе `users.user_id=events.user_id` c помощью хитрого подзапроса:
- ``` SQL
- SELECT x.cohort AS "Date",
- MAX(x.period_age) OVER (PARTITION BY x.cohort) AS cutoff_age,
- x.period_age,
- x.tally,
- x.tally/MAX(x.tally) OVER (PARTITION BY x.cohort)::FLOAT AS retention_rate,
- MAX(x.tally) OVER (PARTITION BY x.cohort) AS "New Users"
- FROM (
- SELECT DATE_TRUNC(:interval, u.created_at) AS cohort,
- FLOOR(EXTRACT('day' FROM e.event_date - e.first_event)/:days) AS period_age,
- COUNT(DISTINCT u.user_id) AS tally
- FROM users u
- LEFT JOIN events e
- ON e.user_id = u.user_id
- ```
- * TODO
- * MONTH-2 RETENTION - `GroupStats.datasets_retention(**kwargs)`
- Получить процент пользователей, которые вернулись во 2 месяц
- после регистрации.
- Параметры запроса (`kwargs`):
- ```
- {
- 'days': 30,
- 'partner_id': 141
- 'groups_id': [10,20],
- 'year': 2016,
- 'month': 12,
- 'enable_demo_portal': False,
- }
- ```
- Получение ответа:
- * АНАЛОГИЧНО week-2 retention, только для расчета даты СЛЕДУЮЩЕГО
- события вместо `days=7` (возврат в течение недели) используем `days=30` (возврат в течение месяца) здесь:
- `FLOOR(EXTRACT('day' FROM e.event_date - e.first_event)/:days) AS period_age`
- * HAPPINESS INDEX - `GroupStats.timeseries_HA(**kwargs)`
- Получить значение Happiness index score для пользователей в выбранный период.
- Параметры запроса (`kwargs`):
- ```
- {
- 'partner_id': 142,
- 'groups_id': [10,20],
- 'interval': 'week', ## `week`, `month`, or `quarter`
- 'first_event': '2016-01-01',
- 'enable_demo_portal': False
- }
- ```
- Получение ответа:
- * Генерируем список дат, начаная с `first_event` и до текущего дня с шагом `interval`. То есть у нас получится список недель (если `interval=week`) ИЛИ список месяцев (если `interval=month`). Обозначаем этот список как `timeseries`
- * Получаем из `GroupStats` все события, у которых `event_type` = `HA`, нужный `partner_id`, `groups_id`, `staff=false`
- * Группируем их на основе `event_date`, понедельно или помесячно (в зависимости от `interval=week/month`). При группировке расчитываем средние значения для `score`, `score_positive`, `score_satisfaction` и количество пользователей. Обозначаем этоь список как `events`.
- * Затем сопоставляем `timeseries` и `events` на основе `timeseries.day=events.day`
- * В итоге получается список дат из `timeseries`:
- с нулевыми значениями `score`, `score_positive`, `score_satisfaction` если нет пересечения с `events` (т.е. когда за неделю/месяц нет событый `HA`)
- и со средними значениями `score`, `score_positive`, `score_satisfaction` если есть пересечение с `events` (т.е. когда за неделю/месяц есть события `HA`)
- * Из полученных `timeseries` получаем данные за нужный период (выбранный месяц или квартал в фильтре)
- * Из полученных `timeseries` получаем данные за прошлый период
- * возвращаем `score` для нужного периода и процент сравнения с прошлым периодом
- * HAPPINESS SCORE COHORTS - `GroupStats.compare_HA(**kwargs)`
- Получить распределние пользователей на когорты, в зависимости от
- полученных score после прохождения Happiness Assessment.
- Параметры запроса (`kwargs`):
- ```
- {
- 'partner_id': partner_space_id,
- 'groups_id': groups_id,
- 'year': year,
- 'month': month,
- 'enable_demo_portal': enable_demo_portal,
- }
- ```
- Получение ответа:
- * Получаем все события из таблицы `group_stats` для которых `event_type=HA`, которые состоят в `groups_id`, приписаны к `partner_id` и `staff=false` и `demo=enable_demo_portal` и группируем по месяцам
- * Для каждого полученного события проставляем дополнительное поле `first_event` (дата первого события) и дополнительное поле `last_event` (дата последнего события). Обозначаем эту выборку как `events`
- * Затем выбираем из этих `events` события, которые находятся в нужном периоде (между `start_date` и `end_date`) и при чем `first_event` не равно `last_event` (т.е. нам нужны события тех пользователей, которые МИНИМУМ 2 раза проходили Happiness assessmet), также вычисляем `score`, `first_score` и `last_score` для каждого события (т.е. если пользователь первый раз прошел HA, то для этого события его `score=first_score`, соответственно для последнего события `score=last_score`). обозначаем эту выборку как `z`
- * В итоге `z` должны содержать все события пользователей, которые МИНИМУМ 2 раза прошли `HA` с дополнительными полями `first_event` - дата 1 HA, `last_event` - дата последнего HA, `first_score` - кол-во очков в 1 HA, `last_score` - кол-во очков в последнем HA
- * Получаем СРЕДНЕЕ кол-во очков для INITIAL (данные 1 HA) пользователей в каждой группе:
- `score_initial_no_risk` >=56 (И это событие 1 HA И `last_score` его выросло)
- `score_initial_mild` <56 and >=44 (И это событие 1 HA И `last_score` его выросло)
- `score_initial_moderate` <44 and >=22 (И это событие 1 HA И `last_score` его выросло)
- `score_initial_severe` <22 (И это событие 1 HA И `last_score` его выросло)
- * TODO
- * TRACK TOPICS - `GroupStats.compare_tracks(**params)`
- Получить список трэков, для которых есть полученные медали в выбранный период.
- Параметры запроса (`kwargs`):
- ```
- {
- 'partner_id': partner_space_id,
- 'groups_id': groups_id,
- 'year': year,
- 'month': month,
- 'enable_demo_portal': enable_demo_portal,
- }
- ```
- Получение ответа:
- * На основе `year`, `month` - находим даты начала и конца ТЕКУЩЕГО периода
- (`first_event`, `last_event`) c помощью вспомогательной функции `get_date_range`
- * Получаем для выбранного периода записи GroupStats (все события с `MEDAL`),
- группы которых содержат `groups_id`,
- partner_id которых равен `partner_id`
- у которых `staff` = false,
- у которых `event_type` = `MEDAL`,
- у которых `event_date` в интервале от `start_date` до
- `end_date`,
- у которых `demo` = `enable_demo_portal`
- у которых в `PARAMS`: `{silver, value}' = 'true'` ИЛИ `{gold, value}' = 'true'`
- * Затем в цикле проходим по выбранным событиям
- подсчитываем сумму золотых и серебренных медалей
- * Возвращаем список полученных трэков (где название трэка берется на основе `PARAMS` `{gold,title}` или `{silver,title}`)
- ACTIVITY LEVELS
- ---------------
- Используется метод `GroupStats.timeseries_AL(partner_id, groups_id, interval, **kwargs)`
- `interval` - равен `week` или `month`.
- `kwargs` - можно передать параметр
- `enable_demo_portal=true/false` - вкл/выкл demo данные
- `first_event='2016-01-01'` - дата начала событий.
- Получение ответа:
- * Генерируем список дат, начаная с `first_event` и до текущего дня с шагом `interval`. То есть у нас получится список недель (если `interval=week`) ИЛИ список месяцев (если `interval=month`). Обозначаем этот список как `timeseries`
- * Получаем из `GroupStats` все события, у которых нужный `partner_id`, `groups_id`, `staff=false`
- * Группируем их на основе `event_date`, понедельно или помесячно (в зависимости от `interval=week/month`).
- * При группировке расчитываем значения для `gold_medals`, `silver_medals`, `signups`, `weekly_activities`, `users_count`
- * Затем сопоставляем `timeseries` и `events` на основе `timeseries.day=events.day`
- * В итоге получается список дат из `timeseries`:
- с нулевыми значениями для расчитанных параметров, если нет пересечения с `events` (т.е. когда за неделю/месяц нет событый)
- и со средними значениями для расчитанных параметров, если есть пересечение с `events` (т.е. когда за неделю/месяц есть события)
- И с показателем signup/active_users для прошлого периода
- * возвращаем сгенерированную последовательность дат
- HAPPINESS INDEX
- ---------------
- Получить значения Happiness index понедельно или помесячно
- Используется метод `GroupStats.timeseries_HA(partner_id, groups_id, interval, **kwargs)`
- `interval` - равен `week` или `month`.
- `kwargs` - можно передать параметр
- `enable_demo_portal=true/false` - вкл/выкл demo данные
- `first_event='2016-01-01'` - дата начала событий.
- Получение ответа:
- * Генерируем список дат, начаная с `first_event` и до текущего дня с шагом `interval`. То есть у нас получится список недель (если `interval=week`) ИЛИ список месяцев (если `interval=month`). Обозначаем этот список как `timeseries`
- * Получаем из `GroupStats` все события, у которых `event_type` = `HA`, нужный `partner_id`, `groups_id`, `staff=false`
- * Группируем их на основе `event_date`, понедельно или помесячно (в зависимости от `interval=week/month`). При группировке расчитываем средние значения для `score`, `score_positive`, `score_satisfaction` и количество пользователей. Обозначаем этоь список как `events`.
- * Затем сопоставляем `timeseries` и `events` на основе `timeseries.day=events.day`
- * В итоге получается список дат из `timeseries`:
- с нулевыми значениями `score`, `score_positive`, `score_satisfaction` если нет пересечения с `events` (т.е. когда за неделю/месяц нет событый `HA`)
- и со средними значениями `score`, `score_positive`, `score_satisfaction` если есть пересечение с `events` (т.е. когда за неделю/месяц есть события `HA`)
- * возвращаем сгенерированную последовательность дат
- Вспомогательные функции
- =======================
- `get_date_range` - получить дату начала и конца периода
- `get_date_range_previous` - получить дату начала и конца предыдущего периода
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement