
Data collection: fondamenti e strategia
Come progettare una strategia di raccolta dati robusta: event tracking, ETL, qualità alla fonte.
Cosa imparerai
- Progettare un tracking plan con eventi, proprietà obbligatorie e owner
- Scegliere il canale client, server o database per ogni evento
- Applicare validazione, deduplicazione e controlli di qualità alla fonte
Collegamenti
Data collection: fondamenti e strategia
In questa lezione lavoriamo con modelli tabellari: eventi, proprietà e identità che finiscono in tabelle interrogabili con SQL. Ma prima di parlare di query, partiamo da un problema più sottile. Una dashboard può sembrare precisa e restare inutile. Succede quando nessuno ha deciso prima quali comportamenti osservare, con quale dettaglio e per quale decisione. La raccolta non comincia dal tool. Comincia da un tracking plan: il contratto che distingue eventi necessari, proprietà critiche e rumore. Questa lezione costruisce quella base verificabile.
La raccolta parte da una decisione
Una strategia di raccolta dati seleziona eventi, canali e controlli di qualità prima che dashboard e modelli amplifichino errori invisibili a monte. In una frase: decidi prima cosa osservare, poi accendi il tracking.
Cinque passi per costruire la base
-
Definisci la decisione da supportare con soglia e
ownerespliciti. -
Seleziona eventi, proprietà ed entità con criteri di inclusione scritti.
-
Assegna ogni evento al canale corretto tra
client,serveredatabase. -
Applica validazione, deduplicazione e controlli di qualità alla fonte.
-
Verifica la base con una vista settimanale e un controllo di stabilità.
Perché la raccolta decide tutto il resto
Un errore di definizione non resta confinato al tracking. Due team chiamano purchase in modo diverso. Un user_id cambia tra web e app. Un ad-blocker cancella parte degli eventi. Tutto si propaga a metriche, esperimenti e modelli, dove diventa difficile da diagnosticare. Se non sai dire quale decisione cambia grazie a un evento, quale proprietà serve davvero e quale errore vuoi evitare, quell’evento non è pronto. Il segnale tipico è noto: CRM, analytics e warehouse riportano numeri diversi per ordini o iscrizioni quasi sempre per divergenze a monte.
Verdetto: decisione esplicita più contratto di misura batte raccolta totale per sicurezza.
Cosa raccogliere e cosa lasciare perdere
Si parte dai requisiti di business, non da ciò che l’SDK può catturare. Un evento è un fatto accaduto in un istante, con nome, tempo e soggetto. Le proprietà dell’evento descrivono cosa è successo. Le proprietà dell’entità descrivono a chi è successo.
| Campo del plan | Cosa chiarire | Esempio |
|---|---|---|
| Nome evento | Azione osservabile stabile | purchase completato lato server |
| Proprietà richieste | Senza queste l’evento è inutilizzabile | order_id, amount, currency, user_id |
| Proprietà contestuali | Servono per segmentare | channel, device, country |
| Identità | Come si attribuisce al soggetto | user_id autenticato, fallback anonymous_id |
| Validazione | Regole di accettazione | amount > 0, currency in ISO 4217 |
Due errori tornano sempre. Primo: nomi ambigui come click senza oggetto. Secondo: proprietà di entità copiate in ogni evento invece di risolverle con un join su user_id.
Verdetto: pochi eventi con proprietà obbligatorie battono molti eventi ambigui senza consumatore.
Client, server o database: dove nasce il dato
Il client-side usa SDK nel browser o nell’app. È facile da avviare ed è ricco di contesto comportamentale. Per questo è utile per funnel e test. Il prezzo è la fragilità: ad-blocker, consenso negato e connettività producono buchi sistematici che distorcono i confronti. Il server-side invia dal backend via API o webhook su fatti autorevoli come pagamenti e rinnovi. È affidabile ed è immune al browser, ma non vede i segnali visuali. La terza sorgente è il database interno, letto con CDC o ETL per riconciliare fatti utente e stati di sistema. CDC significa Change Data Capture: cattura le modifiche del database.
| Aspetto | Client-side | Server-side |
|---|---|---|
| Come funziona | SDK invia eventi al collector | Il backend invia eventi via API o webhook |
| Punti di forza | Implementazione rapida, contesto ricco | Affidabilità, immunità ad ad-blocker |
| Limiti | Dati mancanti, qualità variabile | Sviluppo backend, nessun segnale visuale |
| Adatto a | Comportamento web, test, funnel | Transazioni, eventi critici |
Un’architettura matura combina i due: client per il comportamento e server per le transazioni, con regola di precedenza scritta. Distingui sempre event time da arrival time. Il primo è quando il fatto accade. Il secondo è quando il dato arriva. Senza questa distinzione, batch e ritardi spostano gli eventi tra giorni e sfasano le coorti.
Verdetto: server fa fede per i conteggi e client serve per il percorso, con precedenza scritta nel plan.
Il tracking plan come contratto
Il plan trasforma intenzioni sparse in contratto tra prodotto, ingegneria, dati e marketing. Fissa eventi, proprietà, entità e granularità temporale. È versionato, ha un owner per dominio e prevede review per ogni modifica. Ogni scheda fissa definizione, trigger tecnico, esempio di payload, validazioni e casi esclusi come rimborsi, doppi click e anonimi poi autenticati.
{
// Esempio di contratto per l'evento purchase (versione 2)
"event": "purchase",
"version": 2,
"trigger": "conferma pagamento lato server, non click sul pulsante",
"required": ["order_id", "user_id", "amount", "currency", "event_time"],
"optional": ["coupon_code", "channel", "device"],
"rules": ["amount > 0", "currency in ISO 4217", "order_id univoco"],
"identity": "user_id autenticato; anonymous_id solo come fallback pre-login",
"exclusions": "rimborsi emessi come evento separato refund_issued"
}
Resta vivo con changelog motivato, mapping tra nomi storici e correnti ed elenco di eventi deprecati con data di spegnimento.
Verdetto: contratto versionato con esclusioni esplicite batte documentazione sparsa senza owner.
La qualità si applica alla fonte
Validazione, schema enforcement e deduplicazione si applicano all’ingestione. Correggere dopo costa di più. I controlli minimi sono cinque: completezza, unicità su chiavi di idempotenza, coerenza semantica, copertura dei percorsi alternativi e tempestività entro la soglia decisionale.
-- Controlli di qualità giornalieri sulla tabella eventi grezzi
-- Ogni SELECT restituisce le righe anomale: se è vuota, il controllo passa
-- 1) Eventi senza identificativo utilizzabile
SELECT event_name, COUNT(*) AS righe_anonime
FROM raw_events
WHERE event_date = CURRENT_DATE - INTERVAL '1 day'
AND user_id IS NULL AND anonymous_id IS NULL
GROUP BY event_name;
-- 2) Duplicati su chiave di idempotenza (order_id per purchase)
SELECT order_id, COUNT(*) AS occorrenze
FROM raw_events
WHERE event_name = 'purchase'
AND event_date = CURRENT_DATE - INTERVAL '1 day'
GROUP BY order_id
HAVING COUNT(*) > 1;
-- 3) Valori fuori dominio: importi non positivi o valute non standard
SELECT order_id, amount, currency
FROM raw_events
WHERE event_name = 'purchase'
AND event_date = CURRENT_DATE - INTERVAL '1 day'
AND (amount <= 0 OR currency NOT IN ('EUR', 'USD', 'GBP'));
Queste query diventano test schedulati con soglie e proprietari. Ogni alert dichiara chi riceve, entro quando interviene e quando si blocca la promozione verso le tabelle modellate.
Verdetto: test schedulati con owner battono alert senza responsabile.
Una vista settimanale per leggere i trend
Stabilizzata la base, serve una vista riproducibile. Stessa metrica, stessi segmenti e stesse finestre per osservare trend e formulare ipotesi.
-- Vista settimanale per fonte e dispositivo: base per trend e segmenti
-- Giorni attivi e diversità degli eventi misurano engagement, l'outcome l'efficacia
SELECT
DATE_TRUNC('week', event_time) AS settimana, -- settimana di accadimento (event time)
channel, -- segmento di acquisizione
device, -- segmento tecnico
COUNT(DISTINCT user_id) AS utenti, -- ampiezza della base attiva
COUNT(*) AS eventi_totali, -- volume grezzo, sensibile ai duplicati
COUNT(DISTINCT DATE(event_time)) AS giorni_attivi_totali,
COUNT(DISTINCT event_name) AS diversita_eventi,
-- Tasso di utenti con almeno un purchase nella settimana
ROUND(100.0 * COUNT(DISTINCT CASE WHEN event_name = 'purchase' THEN user_id END)
/ NULLIF(COUNT(DISTINCT user_id), 0), 2) AS tasso_purchase_pct
FROM raw_events
WHERE event_time >= NOW() - INTERVAL '180 days'
GROUP BY 1, 2, 3
ORDER BY 1, 2, 3;
Se il tasso sale, la prima ipotesi è la composizione. Verifica mix di canali cambiato, peso dei segmenti e definizione cambiata a metà periodo. Separa le coorti prima di commentare la media.
Stabilità senza inseguire il rumore
Una metrica utile è stabile per decidere e sensibile per segnalare cambiamenti reali. Il controllo standard combina variazione settimana su settimana e z-score su finestra mobile, con banda calibrata per segmento.
import pandas as pd # elaborazione tabellare delle serie settimanali
# df: colonne settimana, segmento, utenti, tasso_purchase_pct
df = df.sort_values(["segmento", "settimana"])
# Media mobile a 4 settimane: livello atteso al netto del rumore recente
df["media_4s"] = df.groupby("segmento")["tasso_purchase_pct"].transform(
lambda s: s.rolling(4, min_periods=4).mean()
)
# Deviazione mobile: ampiezza normale dell'oscillazione per quel segmento
df["std_4s"] = df.groupby("segmento")["tasso_purchase_pct"].transform(
lambda s: s.rolling(4, min_periods=4).std()
)
# z-score: distanza dal livello atteso in unità di oscillazione normale
df["z_score"] = (df["tasso_purchase_pct"] - df["media_4s"]) / df["std_4s"]
# Anomalie: scostamento ampio (|z| > 2) su base sufficiente di utenti
anomalie = df[(df["z_score"].abs() > 2) & (df["utenti"] >= 200)]
Sotto soglia osservi, sopra soglia indaghi prima la qualità del dato e poi le cause di business.
Errori che ritornano
Il primo sbaglio è aggregare troppo presto: la media globale nasconde canali opposti. Il secondo è trascurare la qualità e trattare ogni variazione come fenomeno reale. Il terzo è confondere correlazione e causalità. La difesa è una checklist per ogni analisi: metrica con numeratore e denominatore, confronto per almeno un segmento, verifica contro il periodo precedente e assunzione invalidante dichiarata.
Verdetto: checklist applicata sempre batte analisi brillante senza controlli.
Il caso che ha cambiato le regole
Nel novembre 2017 Strava pubblica la heatmap globale degli allenamenti costruita su miliardi di punti GPS dei suoi utenti. Nel gennaio 2018 il ricercatore Nathan Ruser scopre che nella mappa sono visibili basi militari in Siria, Afghanistan e Antartide: i soldati con fitness tracker avevano disegnato i perimetri correndo. Strava raccoglieva posizioni senza essersi chiesta chi altro le avrebbe lette una volta aggregate e pubblicate. È la dimostrazione più citata del principio della lezione: la strategia di raccolta si decide prima di accendere il tracking perché ogni evento raccolto per sicurezza diventa un rischio da governare per anni.
Scrivi una query che conti quanti ordini ha effettuato ogni utente e mostri nome, email e numero di ordini. Ordina per numero di ordini decrescente.
Mettiti alla prova
-
Quale decisione cambia grazie a ogni evento che tracci?
-
Quando usi il canale
cliente quando il canaleserverper un evento? -
Quali tre controlli di qualità applichi prima di promuovere i dati grezzi?
-
Come distingui un miglioramento reale da uno spostamento di mix?
Bloccato su questo argomento o vuoi applicarlo al tuo caso? Prenota una call di 15 minuti con un analista esperto.
Percorso collegato
Lezioni da leggere insieme
Questi collegamenti portano la lezione dentro il resto del corso: basi da riprendere, passaggi successivi e connessioni tematiche tra moduli.