#
Как воспроизвести отчеты из raw data
Эта статья описывает, как построить в BI расчеты, близкие к отчетам Gravity Field, используя только CSV из экспорта сырых данных.
Минимальный pipeline
- Загрузите CSV стандартным CSV-парсером.
- Приведите время, деньги и идентификаторы на staging-слое.
- Разверните
eventCartв отдельную таблицу строк заказа. - Считайте A/B и Strategies только по полям, которые есть в raw export.
#
Базовый staging
Перед расчетом отчетов загрузите CSV в staging-таблицу событий и приведите типы.
Минимальный набор нормализованных полей:
Тип поля type
В примерах ниже фильтры по type указаны числовыми ID. Если после импорта ваш CSV хранит type строками, используйте соответствующие названия: Variation Impression, Product Click, Event Hit и т.д.
Отдельно разверните eventCart в таблицу строк заказа:
Для покупок используйте только события:
type = 1eventType = 'purchase-v1'- непустой
uniqueTransactionId
Если один и тот же uniqueTransactionId встречается несколько раз, оставьте первую покупку по времени.
#
A/B report
#
Настройки, которые нужно взять из платформы
Перед расчетом зафиксируйте:
campaignId,experienceId,versionIdили списокvariationId- период отчета
- stickiness: по
uidили поsessionId - attribution window: session или N дней
- trigger атрибуции:
Variation ImpressionилиEvent is triggered - цель:
purchase-v1, revenue или custom event - включено ли исключение outliers в платформенном отчете
#
Алгоритм для purchase/revenue
- Отберите exposure-события:
type = 2- нужные
campaignId,experienceId,versionIdилиvariationId - непустой
uid - период отчета
- Если trigger =
Event is triggered, найдите trigger-событие после exposure:- тот же
uid - если attribution by session, тот же
sessionId trigger_time >= exposure_timeeventNameсоответствует настройке цели-триггера
- тот же
- Отберите покупки:
type = 1eventType = 'purchase-v1'- дедупликация по
uniqueTransactionId
- Привяжите покупки к exposure или trigger:
- тот же
uid - если attribution window = session, тот же
sessionId purchase_time >= attribution_start_time- для day window:
purchase_time <= attribution_start_time + N days
- тот же
- Для чистого сравнения исключите пользователей или сессии, где в рамках той же версии теста были разные
variationId. - Сгруппируйте результат по
variationId.
SQL-псевдокод:
with exposures as (
select
uid,
sessionId as session_id,
moscowTime as exposure_time,
campaignId as campaign_id,
experienceId as experience_id,
versionId as version_id,
variationId as variation_id
from raw_events
where type = 2
and campaignId = :campaign_id
and experienceId = :experience_id
and versionId = :version_id
),
purchases as (
select *
from (
select
uid,
sessionId as session_id,
moscowTime as purchase_time,
eventId as event_id,
uniqueTransactionId as transaction_id,
eventValue / 100.0 as revenue,
row_number() over (
partition by uniqueTransactionId
order by moscowTime
) as rn
from raw_events
where type = 1
and eventType = 'purchase-v1'
and uniqueTransactionId <> ''
)
where rn = 1
),
attributed as (
select
e.variation_id,
p.uid,
p.transaction_id,
p.revenue
from exposures e
join purchases p
on p.uid = e.uid
and p.purchase_time >= e.exposure_time
and p.purchase_time <= e.exposure_time + interval ':window_days day'
-- для session attribution добавьте:
-- and p.session_id = e.session_id
)
select
variation_id,
count(distinct uid) as users_with_purchase,
count(distinct transaction_id) as purchases,
sum(revenue) as revenue,
sum(revenue) / nullif(count(distinct transaction_id), 0) as aov
from attributed
group by variation_id;
Если в платформенном отчете включено исключение outliers, raw BI-расчет без такой же обработки будет отличаться. Минимально зафиксируйте это как причину расхождения. Для более близкого расчета примените тот же подход: значения ниже 5-го перцентиля и выше 95-го перцентиля заменяются на консервативное значение на основе среднего/медианы периода.
#
Strategies report
#
Что можно воспроизвести из raw data
Из raw export можно посчитать близкие к платформе:
ImpressionsVisible ImpressionsClicksCTRDirect Revenueпо точному SKUDirect Purchasesпо точному SKUDirect Revenue per 1000- дневную динамику и разрез по
strategyId
#
Настройки, которые нужно взять из платформы
- период отчета
- attribution window: session, 1, 7, 14 или 30 дней
- нужные
strategyId, если считаете не все стратегии - валюта и source-фильтры, если они применяются в платформенном отчете
#
Базовые метрики вовлечения
Считайте события по strategyId и дате события:
#
Direct Revenue и Direct Purchases
Платформенная логика direct attribution для точного SKU строится от Product Click к последующей покупке того же SKU.
Алгоритм:
- Отберите клики:
type = 6- непустой
uid - непустой
strategyId - разверните массив
skuв отдельные строкиclicked_sku
- Отберите покупки:
type = 1eventType = 'purchase-v1'- дедупликация по
uniqueTransactionId - разверните
eventCartв строки заказа
- Привяжите purchase line к click:
- тот же
uid purchase_time >= click_time- если attribution window = session, тот же
sessionId - если attribution window = N days,
purchase_time <= click_time + N days cart.product_id = clicked_sku
- тот же
- Для таблицы по стратегиям группируйте по
strategyIdи дате покупки. - Для summary дедуплицируйте заказ так, чтобы один
uniqueTransactionIdне увеличивал итог несколько раз из-за нескольких стратегий.
SQL-псевдокод:
with product_clicks as (
select
uid,
sessionId as session_id,
moscowTime as click_time,
strategyId as strategy_id,
clicked_sku
from raw_events
cross join unnest(sku) as clicked_sku
where type = 6
and strategyId <> ''
),
purchase_lines as (
select
p.uid,
p.sessionId as session_id,
p.moscowTime as purchase_time,
p.eventId as event_id,
p.uniqueTransactionId as transaction_id,
cart.product_id,
cart.quantity,
cart.item_price_minor,
cart.quantity * cart.item_price_minor / 100.0 as line_revenue
from deduplicated_purchases p
cross join unnest_event_cart(p.eventCart) as cart
)
select
c.strategy_id,
date(l.purchase_time) as date,
count(distinct l.transaction_id) as direct_purchases,
sum(l.line_revenue) as direct_revenue
from product_clicks c
join purchase_lines l
on l.uid = c.uid
and l.product_id = c.clicked_sku
and l.purchase_time >= c.click_time
and l.purchase_time <= c.click_time + interval ':window_days day'
-- для session attribution добавьте:
-- and l.session_id = c.session_id
group by c.strategy_id, date(l.purchase_time);
Direct Revenue per 1000:
Direct Revenue per 1000 = Direct Revenue / (Visible Impressions / 1000)
CR click -> purchase:
CR click -> purchase = Direct Purchases / Clicks
#
Почему сумма по стратегиям может быть больше summary
Summary и таблица
В таблице по стратегиям один заказ может быть атрибутирован нескольким стратегиям, если пользователь кликал товары в нескольких виджетах/стратегиях перед покупкой. Это ожидаемо.
В summary платформенный отчет дедуплицирует покупки. В BI повторите это правило: для итогового блока оставляйте один вклад на uniqueTransactionId, а для таблицы по стратегиям показывайте вклад каждой стратегии отдельно.
#
FAQ по расхождениям
Почему BI-выручка отличается от платформы?
Проверьте timezone, период отчета, attribution window, дедупликацию по uniqueTransactionId, outliers в A/B-отчете и late events. Также проверьте, не нужна ли метрика, которая использует неэкспортируемые поля.
Что считать выручкой: gross, net, с НДС или без?
Gravity Field считает то значение, которое было отправлено в eventValue и eventCart.itemPrice. Платформа не выводит gross/net из каталога и не пересчитывает НДС или промо-скидки.
Учитываются ли возвраты и отмены заказов?
Автоматически нет. Если возвраты или отмены не передаются отдельными событиями/данными и не настроены в проекте, purchase-событие остается в расчете.
Почему Direct Revenue (All Variants) нельзя посчитать из raw CSV?
Для этой метрики нужен group_id кликнутого товара и купленных товаров. В текущем raw export этих полей нет.
Можно ли использовать eventId для дедупликации покупок?
Нет. Для заказов используйте uniqueTransactionId. eventId идентифицирует конкретное событие и может отличаться у повторно отправленных событий одного заказа.
Можно ли заменить Product Click событием add-to-cart?
Нет. Product Click (type = 6) — это engagement с рекомендательным товаром. Add-to-cart или другой сайт-клик является отдельным custom event и не равен клику по рекомендации.
See also
Эта статья поможет вам анализировать эффективность рекомендательных стратегий в платформе Gravity Field.
Эта статья описывает логику атрибуции в двух случаях:
Эта статья описывает CSV-файлы с сырыми событиями Gravity Field: где они лежат, какие поля есть в выгрузке и какие технические ограничения важно...