Я пытался вычислить 7-дневный коэффициент возврата (также известный как классический коэффициент удержания, как описано здесь: https://www.braze.com/blog/calculate-retention-rate/), а затем взял среднее значение за 30 дней, чтобы уменьшить шум в Postgresql.
Тем не менее, я уверен, что я делаю что-то не так. Во-первых, цифры выглядят намного выше, чем интуитивно я думаю, что они должны быть (обычно около 5% для остальной части сектора). Кроме того, я считаю, что первые 7дни должны показывать 0, так как теоретически пользователям должно потребоваться не менее 7 дней, чтобы считаться «возвратом». Однако я получаю около 40-70%, как показано ниже.
Не возражает ли кто-нибудь взглянуть наПриведенный ниже код и выяснение, есть ли какие-либо ошибки? 7-дневная норма возврата - это действительно распространенная метрика для приложений, и я не нашел никаких вопросов, используя postgresql, чтобы вычислить его до этого уровня сложности в Stack Exchange (или даже в остальной части), поэтому я чувствую, что твердый ответ может быть очень полезен для многих людей.
Пример данных
Wednesday, August 1, 2018 12:00 AM 71.14
Thursday, August 2, 2018 12:00 AM 55.44
Friday, August 3, 2018 12:00 AM 50.09
Saturday, August 4, 2018 12:00 AM 45.81
Sunday, August 5, 2018 12:00 AM 43.27
Monday, August 6, 2018 12:00 AM 40.61
Tuesday, August 7, 2018 12:00 AM 39.38
Wednesday, August 8, 2018 12:00 AM 38.46
Thursday, August 9, 2018 12:00 AM 36.81
Friday, August 10, 2018 12:00 AM 35.94
with
user_first_event as (
select distinct id, min(timestamp)::date as first_event_date
from log
where
timestamp <= current_date
and timestamp >= {{start_date}} and timestamp <= {{end_date}}
group by id),
event as (
select distinct id, timestamp::date as user_event_date
from log
where timestamp <= current_date and timestamp >= {{start_date}}),
gap as (
select
user_first_event.id,
user_first_event.first_event_date,
event.user_event_date,
event.user_event_date - user_first_event.first_event_date as days_since_signup
from user_first_event
join event on user_first_event.id = event.id
where user_first_event.first_event_date <= event.user_event_date),
conversion_rate as (
select
first_event_date,
(sum(case when days_since_signup = 7 then 1 else 0 end) * 100.0 /
count(distinct id)
) as seven_day_retention_rate
from gap
group by first_event_date
)
SELECT first_event_date,
AVG(seven_day_retention_rate)
OVER(ORDER BY first_event_date ROWS BETWEEN 29 PRECEDING AND CURRENT ROW) AS rolling_avg_retention_rate
FROM conversion_rate