Partager des données peut accélérer la recherche, l’innovation et la coordination entre équipes. Mais mal fait, cela expose des personnes et détruit la confiance. La bonne approche: publier moins mais mieux, avec des définitions claires, une anonymisation sérieuse, un niveau d’agrégation adapté et une licence simple qui dit ce qui est permis.
prérequis
- Un inventaire des champs sensibles (directs et indirects).
- Un dictionnaire de données court et public.
- Un processus de revue (juridique + data) avant publication.
aperçu rapide
- Définir le périmètre: pourquoi publier, pour qui, pour quel usage.
- Supprimer ou pseudonymiser les identifiants directs et quasi-identifiants.
- Agréger au bon niveau (temps, géographie, catégorie) pour éviter la ré-identification.
- Contrôler la qualité et documenter les corrections.
- Publier un changelog et des limites d’interprétation.
- Choisir une licence claire et compatible avec les usages visés.
tutoriel pas-à-pas
étape 1: cadrer le périmètre et les risques
Lister les champs à risque et les usages attendus. Choisir le niveau d’agrégation minimal qui reste utile.
objectif: permettre le suivi hebdo des tendances de demande
périmètre: FR, 12 derniers mois, hebdomadaire
exclusions: identifiants directs (email, téléphone), adresses exactes
agrégation: département + semaine ISO
étape 2: anonymiser proprement
Supprimer les identifiants directs, pseudonymiser ce qui doit rester relia ble, et vérifier k-anonymat.
# pseudonymisation simple et salée
import hashlib, os
SALT = os.environ.get("SALT","static-salt-change-me")
def pseudo_id(x: str) -> str:
return hashlib.sha256((SALT + x).encode()).hexdigest()[:12]
-- contrôle k-anonymat basique: chaque groupe doit avoir au moins k lignes
WITH g AS (
SELECT dep, date_trunc('week', ts)::date AS semaine, COUNT(*) AS n
FROM flux_nettoye
GROUP BY 1,2
)
SELECT dep, semaine, n
FROM g
WHERE n < 15; -- k = 15
étape 3: agréger et documenter
Agréger par semaine et département, décrire les champs, les unités et les limites.
CREATE MATERIALIZED VIEW public.demande_hebdo AS
SELECT
date_trunc('week', ts)::date AS semaine,
dep,
SUM(nb_demandes) AS demandes
FROM flux_nettoye
GROUP BY 1,2;
dictionnaire:
- semaine: date du lundi de la semaine ISO (UTC)
- dep: code département (INSEE)
- demandes: nombre total d’événements agrégés sur la semaine
limites: données incomplètes week-ends; corrections publiées le lundi
étape 4: publier avec un changelog et un contact
Fournir un README, une licence et un fichier de changements.
ts=$(date +%F)
mkdir -p releases && cp export/demande_hebdo.csv "releases/demande_hebdo_${ts}.csv"
cat >> CHANGELOG.md <<EOF
${ts} v1.2: correction de doublons, seuil k=15 relevé sur 3 départements
EOF
echo "contact: data@example.fr" > README.md
echo "licence: Etalab 2.0" >> README.md
étape 5: publier des exemples d’usage
Réduire le temps de prise en main avec 2 à 3 requêtes prêtes à copier.
-- top 10 départements par croissance 4 semaines glissantes
WITH w AS (
SELECT dep, semaine, demandes,
SUM(demandes) OVER (PARTITION BY dep ORDER BY semaine ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS d4
FROM public.demande_hebdo
)
SELECT dep, semaine, ROUND(100.0*(d4 - LAG(d4) OVER (PARTITION BY dep ORDER BY semaine))/NULLIF(LAG(d4) OVER (PARTITION BY dep ORDER BY semaine),0),1) AS croissance_pct
FROM w
QUALIFY ROW_NUMBER() OVER (PARTITION BY semaine ORDER BY croissance_pct DESC) <= 10;
exemples
cas: publication responsable d’un indicateur de service
- quoi: délais de réponse hebdos par région
- agrégation: semaine x région, médiane + p90
- limites: volume faible sur 3 régions -> prudence
- licence: Etalab 2.0
- contact: support-data@example.fr
-- calcul médiane et p90 par semaine et région
SELECT
date_trunc('week', ts)::date AS semaine,
region,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY delai_minutes) AS delai_med,
PERCENTILE_CONT(0.9) WITHIN GROUP (ORDER BY delai_minutes) AS delai_p90
FROM tickets
GROUP BY 1,2
ORDER BY semaine DESC, region;
erreurs courantes et solutions
- agrégation trop fine -> risque de ré-identification -> remonter d’un cran (région au lieu de commune, semaine au lieu du jour)
- dictionnaires multiples -> incompréhension -> un dictionnaire public, court, versionné
- corrections silencieuses -> perte de confiance -> changelog visible et version du dataset
- fuseau horaire implicite -> erreurs d’interprétation -> timestamps en UTC, conversion explicite côté client
- licence floue -> blocages juridiques -> choisir une licence standard et compatible avec l’usage cible
- seuil k trop faible -> fuite -> élever k ou regrouper les catégories rares
faq
- faut-il rendre les données brutes publiques ? Non. Publiez le minimum utile, agrégé et documenté. Gardez les bruts en interne, audités.
- comment choisir la licence ? Prendre une licence ouverte reconnue (par ex. Etalab 2.0) et la citer dans chaque fichier et page.
- que faire si un champ devient sensible a posteriori ? Retirer, régénérer, republier avec un changelog clair, et prévenir les principaux consommateurs.