Construcción de un Modelo de Atribución Multi-Touch sobre Eventos Raw de GA4 en BigQuery
Consultas SQL paso a paso con funciones analíticas de ventana para calcular pesos First-Touch, Lead-Creation y Opportunity-Creation (W-Shaped) sobre datos sin muestrear.
La interfaz gráfica de Google Analytics 4 impone restricciones de muestreo, umbrales de privacidad y ventanas de conversión arbitrarias. Al habilitar la exportación nativa diaria y continua de GA4 a Google BigQuery, obtenemos acceso a cada evento individual sin muestreo. Con SQL podemos diseñar un modelo de atribución que asigne pesos exactos a cada canal en función de su rol en el ciclo comercial B2B.
1. Extracción de Puntos de Contacto desde ga4_events_*
El primer paso consiste en desanidar los parámetros de sesión (`ga_session_id`, `source`, `medium`, `campaign`) y filtrar únicamente los eventos que representen interacción real de tráfico.
-- Extracción y normalización de puntos de contacto de marketingWITH parsed_events AS (SELECTuser_pseudo_id,event_timestamp,TIMESTAMP_MICROS(event_timestamp) AS event_time,event_name,(SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS session_id,COALESCE((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'source'), traffic_source.source) AS utm_source,COALESCE((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'medium'), traffic_source.medium) AS utm_medium,COALESCE((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'campaign'), traffic_source.name) AS utm_campaignFROM `tu_proyecto.analytics_123456789.events_*`WHERE _TABLE_SUFFIX BETWEEN '20260801' AND '20260831'),sessions_summary AS (SELECTuser_pseudo_id,session_id,MIN(event_time) AS session_start,ARRAY_AGG(utm_source IGNORE NULLS ORDER BY event_time ASC LIMIT 1)[OFFSET(0)] AS session_source,ARRAY_AGG(utm_medium IGNORE NULLS ORDER BY event_time ASC LIMIT 1)[OFFSET(0)] AS session_medium,ARRAY_AGG(utm_campaign IGNORE NULLS ORDER BY event_time ASC LIMIT 1)[OFFSET(0)] AS session_campaign,LOGICAL_OR(event_name = 'generate_lead') AS has_lead_conversion,LOGICAL_OR(event_name = 'opportunity_created') AS has_deal_conversionFROM parsed_eventsWHERE session_id IS NOT NULLGROUP BY 1, 2)SELECT * FROM sessions_summary;
2. Cálculo de Pesos W-Shaped con Funciones de Ventana
El modelo W-Shaped asigna un 30% del valor de conversión a la primera sesión (First Touch), un 30% a la sesión en que se creó el Lead, un 30% a la sesión en que se creó la Oportunidad en el CRM y reparte el 10% restante equitativamente entre las sesiones intermedias.
-- Cálculo de pesos W-Shaped por punto de contactoWITH user_journey AS (SELECTuser_pseudo_id,session_id,session_start,CONCAT(COALESCE(session_source, '(direct)'), ' / ', COALESCE(session_medium, '(none)')) AS channel_grouping,has_lead_conversion,has_deal_conversion,ROW_NUMBER() OVER(PARTITION BY user_pseudo_id ORDER BY session_start ASC) AS touch_rank_asc,ROW_NUMBER() OVER(PARTITION BY user_pseudo_id ORDER BY session_start DESC) AS touch_rank_desc,COUNT(*) OVER(PARTITION BY user_pseudo_id) AS total_touchesFROM sessions_summary)SELECTuser_pseudo_id,session_id,channel_grouping,session_start,CASE-- Viaje de 1 solo toque recibe el 100%WHEN total_touches = 1 THEN 1.0-- Primer toque (First Touch)WHEN touch_rank_asc = 1 THEN 0.30-- Hito de conversión / Oportunidad finalWHEN touch_rank_desc = 1 THEN 0.30-- Toque de creación de LeadWHEN has_lead_conversion THEN 0.30-- Toques intermedios se reparten el 10% restanteELSE 0.10 / NULLIF(total_touches - 3, 0)END AS attribution_weightFROM user_journey;
Optimización de Costes en BigQuery
Particiona siempre las tablas intermedias por session_start (DAY) y clusteriza por user_pseudo_id para reducir el volumen de datos escaneados de gigabytes a solo megabytes.
3. Comparativa de Retorno por Canal: Last-Click vs. W-Shaped
Al ejecutar la consulta sobre un trimestre de datos reales B2B, los resultados revelan discrepancias radicales: canales como LinkedIn Paid y Contenido Orgánico aumentan su contribución en más de un 120%, mientras que Brand Search se reduce a su proporción justa.
| Canal de Marketing | Ingresos Last-Click | Ingresos W-Shaped | Diferencia |
|---|---|---|---|
| LinkedIn Ads (Demanda Temprana) | $24,000 | $68,500 | +185% (Invisibilizado en last-click) |
| SEO Técnico & Blog Pilares | $38,000 | $79,200 | +108% (Crucial en captación inicial) |
| Google Ads (Brand Search) | $142,000 | $56,300 | -60% (Sobrevalorado en last-click) |
| Email Nurturing & Webinars | $18,000 | $35,000 | +94% (Acelerador de oportunidad) |
Controles Técnicos
Muestra telemetría y especificaciones de verificación en producción.