Advertisement
Guest User

Untitled

a guest
Jan 24th, 2017
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.31 KB | None | 0 0
  1. Сбор и сохранение статистики для портала.
  2. ========================================
  3.  
  4. Для хранения статистики портала используется только одна таблица
  5. `group_stats`. Данные в нее собираются с помощью fab таска (на данный
  6. момент ТОЛЬКО вручную).
  7.  
  8. Пример, `fab portal.aggregate_partner_stats:partner_space_id=<ps_id>`
  9. При запуске этого таска выполняется скрипт в `lib/util/group_stats.py`.
  10. Сурипт берет данные для каждого типа события из определенной таблицы БД:
  11.  
  12. Тип события (event_type) | Модель БД
  13. 'SIGNUP' | User
  14. 'AL' | ActivityStatus
  15. 'MAL' | MixpanelUserActivity
  16. 'HA' | QuizScore
  17. 'WA' | WorkAssessmentUserAnswer
  18. 'MEDAL' | ChallengeStatus
  19. 'RA' | TBD
  20. 'LD | TBD
  21.  
  22. Сохраняются данные только для тех пользователей, у который есть привязка к
  23. Partner Space (через `<ps_id>` в fab таске)
  24.  
  25.  
  26. Отображение графиков и метрик.
  27. =============================
  28.  
  29. Для всех графиков и метрик используется модель `GroupStats` (файл
  30. `models/group_stats.py`)
  31.  
  32. OVERVIEW
  33. --------
  34.  
  35. * TOTAL SIGNUP - метод `GroupStats.compare_signup(**kwargs)`
  36. Получить количество зарегистрированных пользователей в выбранном периоде и
  37. процент изменения по сравнению с предыдущим периодом.
  38. Параметры запроса (`kwargs`):
  39. ```
  40. {
  41. 'partner_id': 141,
  42. 'groups_id': [10,20],
  43. 'year': 2016,
  44. 'month': 12,
  45. 'enable_demo_portal': False,
  46. }
  47. ```
  48. Получение ответа:
  49. * На основе `year`, `month` - находим даты начала и конца ТЕКУЩЕГО периода
  50. (`first_event`, `last_event`) c помощью вспомогательной функции `get_date_range`
  51. * Получаем для ТЕКУЩЕГО периода кол-во записей GroupStats (уникальных по `user_id`),
  52. группы которых содержат `groups_id`,
  53. partner_id которых равен `partner_id`
  54. у которых `staff` = false,
  55. у которых `event_date` в интервале от `start_date` до
  56. `end_date`,
  57. у которых `event_type` = `SIGNUP`,
  58. у которых `demo` = `enable_demo_portal`
  59. * На основе `year`, `month` - находим даты начала и конца ПРЕДЫУЩЕГО периода
  60. (`first_event`, `last_event`) c помощью вспомогательной функции `get_date_range_previous`
  61. * Затем получаем для ПРЕДЫДУЩЕГО периода кол-во записей GroupStats,
  62. аналогично ТЕКУЩЕМУ, но только с другими `start_date`, `end_date`
  63. * Высчитываем изменение (`compare_percent`) сравнивая текущий и
  64. прошлый период.
  65. * возвращаем ответ
  66. ```
  67. {
  68. 'current_month': 12,
  69. 'current_year': 2016,
  70. 'current_count': 50,
  71. 'previous_year': 2016,
  72. 'previous_month': 11,
  73. 'previous_count': 40,
  74. 'compare_percent': 20 ## 20%
  75. 'triangle': 'up'
  76. }
  77. ```
  78.  
  79.  
  80. * TOTAL ACTIVE USERS - метод `GroupStats.compare_acvive_users(**kwargs)`
  81. Получить количество активных пользователей в выбранном периоде и
  82. процент изменения по сравнению с предыдущим периодом.
  83. Параметры запроса (`kwargs`):
  84. ```
  85. {
  86. 'partner_id': 141
  87. 'groups_id': [10,20],
  88. 'year': 2016,
  89. 'month': 12,
  90. 'enable_demo_portal': False,
  91. }
  92. ```
  93. Получение ответа:
  94. * На основе `year`, `month` - находим даты начала и конца ТЕКУЩЕГО периода
  95. (`first_event`, `last_event`) c помощью вспомогательной функции `get_date_range`
  96. * Получаем для ТЕКУЩЕГО периода кол-во записей GroupStats (уникальных по `user_id`),
  97. группы которых содержат `groups_id`,
  98. partner_id которых равен `partner_id`
  99. у которых `staff` = false,
  100. у которых `event_date` в интервале от `start_date` до
  101. `end_date`,
  102. у которых `event_type` любой
  103. у которых `demo` = `enable_demo_portal`
  104. * На основе `year`, `month` - находим даты начала и конца ПРЕДЫУЩЕГО периода
  105. (`first_event`, `last_event`) c помощью вспомогательной функции `get_date_range_previous`
  106. * Затем получаем для ПРЕДЫДУЩЕГО периода кол-во записей GroupStats,
  107. аналогично ТЕКУЩЕМУ, но только с другими `start_date`, `end_date`
  108. * Высчитываем изменение (`compare_percent`) сравнивая текущий и
  109. прошлый период.
  110. * возвращаем ответ
  111. ```
  112. {
  113. 'current_month': 12,
  114. 'current_year': 2016,
  115. 'current_count': 80,
  116. 'previous_year': 2016,
  117. 'previous_month': 11,
  118. 'previous_count': 40,
  119. 'compare_percent': 50 ## 50%
  120. 'triangle': 'up'
  121. }
  122. ```
  123.  
  124. * WEEK-2 RETENTION - `GroupStats.datasets_retention(**kwargs)`
  125. Получить процент пользователей, которые вернулись во 2 неделю
  126. после регистрации.
  127. Параметры запроса (`kwargs`):
  128. ```
  129. {
  130. 'days': 7,
  131. 'partner_id': 141
  132. 'groups_id': [10,20],
  133. 'year': 2016,
  134. 'month': 12,
  135. 'enable_demo_portal': False,
  136. }
  137. ```
  138. Получение ответа:
  139. * На основе `year`, `month` - находим даты начала и конца нужного периода (`first_event`, `last_event`) c помощью вспомогательной функции `get_date_range`
  140. * Получаем всех пользователей (`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`
  141. * Получаем все события из таблицы `group_stats` для которых `event_type` больше `start_date`, меньше `NOW`, которые состоят в `groups_id`, приписаны к `partner_id` и `staff=false` и `demo=enable_demo_portal`
  142. * Для каждого полученного события проставляем дополнительное поле `first_event` (дата первого события). Обозначаем эту выборку как `events`
  143. * Далее соединяем `users` и `events` на основе `users.user_id=events.user_id` c помощью хитрого подзапроса:
  144. ``` SQL
  145. SELECT x.cohort AS "Date",
  146. MAX(x.period_age) OVER (PARTITION BY x.cohort) AS cutoff_age,
  147. x.period_age,
  148. x.tally,
  149. x.tally/MAX(x.tally) OVER (PARTITION BY x.cohort)::FLOAT AS retention_rate,
  150. MAX(x.tally) OVER (PARTITION BY x.cohort) AS "New Users"
  151. FROM (
  152. SELECT DATE_TRUNC(:interval, u.created_at) AS cohort,
  153. FLOOR(EXTRACT('day' FROM e.event_date - e.first_event)/:days) AS period_age,
  154. COUNT(DISTINCT u.user_id) AS tally
  155. FROM users u
  156. LEFT JOIN events e
  157. ON e.user_id = u.user_id
  158. ```
  159. * TODO
  160.  
  161.  
  162. * MONTH-2 RETENTION - `GroupStats.datasets_retention(**kwargs)`
  163. Получить процент пользователей, которые вернулись во 2 месяц
  164. после регистрации.
  165. Параметры запроса (`kwargs`):
  166. ```
  167. {
  168. 'days': 30,
  169. 'partner_id': 141
  170. 'groups_id': [10,20],
  171. 'year': 2016,
  172. 'month': 12,
  173. 'enable_demo_portal': False,
  174. }
  175. ```
  176. Получение ответа:
  177. * АНАЛОГИЧНО week-2 retention, только для расчета даты СЛЕДУЮЩЕГО
  178. события вместо `days=7` (возврат в течение недели) используем `days=30` (возврат в течение месяца) здесь:
  179. `FLOOR(EXTRACT('day' FROM e.event_date - e.first_event)/:days) AS period_age`
  180.  
  181.  
  182.  
  183. * HAPPINESS INDEX - `GroupStats.timeseries_HA(**kwargs)`
  184. Получить значение Happiness index score для пользователей в выбранный период.
  185. Параметры запроса (`kwargs`):
  186. ```
  187. {
  188. 'partner_id': 142,
  189. 'groups_id': [10,20],
  190. 'interval': 'week', ## `week`, `month`, or `quarter`
  191. 'first_event': '2016-01-01',
  192. 'enable_demo_portal': False
  193. }
  194. ```
  195. Получение ответа:
  196. * Генерируем список дат, начаная с `first_event` и до текущего дня с шагом `interval`. То есть у нас получится список недель (если `interval=week`) ИЛИ список месяцев (если `interval=month`). Обозначаем этот список как `timeseries`
  197. * Получаем из `GroupStats` все события, у которых `event_type` = `HA`, нужный `partner_id`, `groups_id`, `staff=false`
  198. * Группируем их на основе `event_date`, понедельно или помесячно (в зависимости от `interval=week/month`). При группировке расчитываем средние значения для `score`, `score_positive`, `score_satisfaction` и количество пользователей. Обозначаем этоь список как `events`.
  199. * Затем сопоставляем `timeseries` и `events` на основе `timeseries.day=events.day`
  200. * В итоге получается список дат из `timeseries`:
  201. с нулевыми значениями `score`, `score_positive`, `score_satisfaction` если нет пересечения с `events` (т.е. когда за неделю/месяц нет событый `HA`)
  202. и со средними значениями `score`, `score_positive`, `score_satisfaction` если есть пересечение с `events` (т.е. когда за неделю/месяц есть события `HA`)
  203. * Из полученных `timeseries` получаем данные за нужный период (выбранный месяц или квартал в фильтре)
  204. * Из полученных `timeseries` получаем данные за прошлый период
  205. * возвращаем `score` для нужного периода и процент сравнения с прошлым периодом
  206.  
  207.  
  208.  
  209. * HAPPINESS SCORE COHORTS - `GroupStats.compare_HA(**kwargs)`
  210. Получить распределние пользователей на когорты, в зависимости от
  211. полученных score после прохождения Happiness Assessment.
  212. Параметры запроса (`kwargs`):
  213. ```
  214. {
  215. 'partner_id': partner_space_id,
  216. 'groups_id': groups_id,
  217. 'year': year,
  218. 'month': month,
  219. 'enable_demo_portal': enable_demo_portal,
  220. }
  221. ```
  222. Получение ответа:
  223. * Получаем все события из таблицы `group_stats` для которых `event_type=HA`, которые состоят в `groups_id`, приписаны к `partner_id` и `staff=false` и `demo=enable_demo_portal` и группируем по месяцам
  224. * Для каждого полученного события проставляем дополнительное поле `first_event` (дата первого события) и дополнительное поле `last_event` (дата последнего события). Обозначаем эту выборку как `events`
  225. * Затем выбираем из этих `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`
  226. * В итоге `z` должны содержать все события пользователей, которые МИНИМУМ 2 раза прошли `HA` с дополнительными полями `first_event` - дата 1 HA, `last_event` - дата последнего HA, `first_score` - кол-во очков в 1 HA, `last_score` - кол-во очков в последнем HA
  227. * Получаем СРЕДНЕЕ кол-во очков для INITIAL (данные 1 HA) пользователей в каждой группе:
  228. `score_initial_no_risk` >=56 (И это событие 1 HA И `last_score` его выросло)
  229. `score_initial_mild` <56 and >=44 (И это событие 1 HA И `last_score` его выросло)
  230. `score_initial_moderate` <44 and >=22 (И это событие 1 HA И `last_score` его выросло)
  231. `score_initial_severe` <22 (И это событие 1 HA И `last_score` его выросло)
  232. * TODO
  233.  
  234.  
  235. * TRACK TOPICS - `GroupStats.compare_tracks(**params)`
  236. Получить список трэков, для которых есть полученные медали в выбранный период.
  237. Параметры запроса (`kwargs`):
  238. ```
  239. {
  240. 'partner_id': partner_space_id,
  241. 'groups_id': groups_id,
  242. 'year': year,
  243. 'month': month,
  244. 'enable_demo_portal': enable_demo_portal,
  245. }
  246. ```
  247. Получение ответа:
  248. * На основе `year`, `month` - находим даты начала и конца ТЕКУЩЕГО периода
  249. (`first_event`, `last_event`) c помощью вспомогательной функции `get_date_range`
  250. * Получаем для выбранного периода записи GroupStats (все события с `MEDAL`),
  251. группы которых содержат `groups_id`,
  252. partner_id которых равен `partner_id`
  253. у которых `staff` = false,
  254. у которых `event_type` = `MEDAL`,
  255. у которых `event_date` в интервале от `start_date` до
  256. `end_date`,
  257. у которых `demo` = `enable_demo_portal`
  258. у которых в `PARAMS`: `{silver, value}' = 'true'` ИЛИ `{gold, value}' = 'true'`
  259. * Затем в цикле проходим по выбранным событиям
  260. подсчитываем сумму золотых и серебренных медалей
  261. * Возвращаем список полученных трэков (где название трэка берется на основе `PARAMS` `{gold,title}` или `{silver,title}`)
  262.  
  263.  
  264.  
  265.  
  266. ACTIVITY LEVELS
  267. ---------------
  268. Используется метод `GroupStats.timeseries_AL(partner_id, groups_id, interval, **kwargs)`
  269.  
  270. `interval` - равен `week` или `month`.
  271. `kwargs` - можно передать параметр
  272. `enable_demo_portal=true/false` - вкл/выкл demo данные
  273. `first_event='2016-01-01'` - дата начала событий.
  274.  
  275. Получение ответа:
  276. * Генерируем список дат, начаная с `first_event` и до текущего дня с шагом `interval`. То есть у нас получится список недель (если `interval=week`) ИЛИ список месяцев (если `interval=month`). Обозначаем этот список как `timeseries`
  277. * Получаем из `GroupStats` все события, у которых нужный `partner_id`, `groups_id`, `staff=false`
  278. * Группируем их на основе `event_date`, понедельно или помесячно (в зависимости от `interval=week/month`).
  279. * При группировке расчитываем значения для `gold_medals`, `silver_medals`, `signups`, `weekly_activities`, `users_count`
  280. * Затем сопоставляем `timeseries` и `events` на основе `timeseries.day=events.day`
  281. * В итоге получается список дат из `timeseries`:
  282. с нулевыми значениями для расчитанных параметров, если нет пересечения с `events` (т.е. когда за неделю/месяц нет событый)
  283. и со средними значениями для расчитанных параметров, если есть пересечение с `events` (т.е. когда за неделю/месяц есть события)
  284. И с показателем signup/active_users для прошлого периода
  285. * возвращаем сгенерированную последовательность дат
  286.  
  287.  
  288.  
  289. HAPPINESS INDEX
  290. ---------------
  291. Получить значения Happiness index понедельно или помесячно
  292.  
  293. Используется метод `GroupStats.timeseries_HA(partner_id, groups_id, interval, **kwargs)`
  294. `interval` - равен `week` или `month`.
  295. `kwargs` - можно передать параметр
  296. `enable_demo_portal=true/false` - вкл/выкл demo данные
  297. `first_event='2016-01-01'` - дата начала событий.
  298.  
  299. Получение ответа:
  300. * Генерируем список дат, начаная с `first_event` и до текущего дня с шагом `interval`. То есть у нас получится список недель (если `interval=week`) ИЛИ список месяцев (если `interval=month`). Обозначаем этот список как `timeseries`
  301. * Получаем из `GroupStats` все события, у которых `event_type` = `HA`, нужный `partner_id`, `groups_id`, `staff=false`
  302. * Группируем их на основе `event_date`, понедельно или помесячно (в зависимости от `interval=week/month`). При группировке расчитываем средние значения для `score`, `score_positive`, `score_satisfaction` и количество пользователей. Обозначаем этоь список как `events`.
  303. * Затем сопоставляем `timeseries` и `events` на основе `timeseries.day=events.day`
  304. * В итоге получается список дат из `timeseries`:
  305. с нулевыми значениями `score`, `score_positive`, `score_satisfaction` если нет пересечения с `events` (т.е. когда за неделю/месяц нет событый `HA`)
  306. и со средними значениями `score`, `score_positive`, `score_satisfaction` если есть пересечение с `events` (т.е. когда за неделю/месяц есть события `HA`)
  307. * возвращаем сгенерированную последовательность дат
  308.  
  309.  
  310.  
  311. Вспомогательные функции
  312. =======================
  313.  
  314. `get_date_range` - получить дату начала и конца периода
  315. `get_date_range_previous` - получить дату начала и конца предыдущего периода
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement