Attaching package: 'dplyr'
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
La fiche pratique présente comment appliquer le Target Record Swapping
à un jeu de données individuelles afin d’assurer une protection optimale des informations confidentielles des individus (ou ménages ou entreprises) qui le composent.
La première partie s’attache à présenter les différentes étapes à suivre pour que cette application soit pertinente au regard des données utilisées.
La seconde partie montre comment utiliser la fonction sdcMicro::recordSwap()
pour appliquer la méthode à un jeu de données dont on aura repérer les individus à risque préalablement.
Pour reproduire les résultats et réaliser les exercices, il est possible de travailler directement sur le datalab
de l’Insee. Si vous disposez d’un compte, vous pouvez Ouvrir un service RStudio ou Ouvrir un service vscode R-Python, à votre convenance. Ces services installeront automatiquement les packages nécessaires pour réaliser les exercices de l’ensemble des fiches pratiques.
Le Target Record Swapping (TRS)
est une méthode s’appliquant directement sur un jeu de données individuelles pour réduire principalement les risques de ré-identification. Il ciblera donc les individus pour lesquels ce risque est jugé trop élevé, c’est-à-dire
ceux partageant des caractéristiques trop rares sur un ensemble de variables dites quasi-identifiantes. Les variables quasi-identifiantes sont celles qui sont susceptibles d’être déjà publiques ou du moins à la disposition d’un attaquant.
D’où son nom: le swapping, c’est-à-dire l’échange, va concerner des unités de la base (les records) détectés à l’avance, devenant ainsi les cibles (target) sur lesquelles on va se concentrer.
Bien qu’elle soit appliquée sur des microdonnées, la méthode a principalement vocation à protéger la diffusion de données tabulées (Hundepool et al. 2024, section 5.6). Dans ce type d’utilisation, en tant que méthode pré-tabulée, elle permet de produire des tableaux parfaitement additifs.
Après avoir détecté un individu dont le risque de ré-identification est jugé trop élevé, un autre individu est tiré aléatoirement parmi les individus au risque de ré-identification les plus faibles et certaines des caractéristiques de ces deux individus sont échangées (swapped).
Après l’échange, la ré-identification de l’individu est rendue beaucoup plus difficile et ne permet plus d’obtenir d’informations pertinentes à son sujet.
Soit un territoire donné découpé en six zones où résident un certain nombre d’individus. Avec les informations disponibles à leur sujet, on considère qu’un seul individu a un risque de ré-identification trop élevé (croix rouge sur la Figure 1).
On tire alors au hasard un autre individu présent sur le territoire pour échanger certaines de leurs caractéristiques. Ce tirage pourrait être purement aléatoire. Mais, cela conduirait à détruire certaines statistiques bien utiles. Par exemple, en trouvant un individu d’une autre zone partageant certaines caractéristiques (par exemple le sexe, l’âge et la catégorie sociale, Figure 2), on s’assure de conserver les marges sur ces variables au niveau géographique le plus fin.
En revanche, les autres caractéristiques sont bruitées de façon non contrôlée.
Ainsi, l’éventuelle ré-identification de l’individu à risque ne pourrait conduire l’attaquant qu’à obtenir des informations très probablement fausses à son sujet.
La méthode est très souple puisqu’elle permet de s’adapter aux données dont on dispose et aux besoins en termes de diffusion. Les variables de similarité entre individus échangés peuvent ainsi être choisies parmi les variables dont on veut conserver le mieux possible l’information marginale. En effet, en échangeant des individus parfaitement similaires sur certaines caractéristiques (les variables de similarité), l’échange ne produira aucune perte d’information sur celles-ci.
Si l’objectif est de réduire le risque de ré-identification, sélectionner toutes les variables quasi-identifiantes comme variables de similarité ne perturberait aucunement la capacité de l’attaquant à ré-identifier les individus. Ce choix produirait en revanche du bruit sur les autres variables: donc en ré-identifiant, l’attaquant ne serait pas en mesure d’obtenir des informations supplémentaires fiables.
Les données contiennent généralement des informations géographiques. Or, la géographie, en particulier à des niveaux fins, est très identifiante. On choisira en général d’échanger des individus résidant à des endroits différents, en tenant compte du niveau géographique auquel un individu est facilement ré-identifiable.
Par exemple, si un individu est facilement ré-identifiable dans sa commune mais pas dans son département de résidence, alors on privilégiera l’échange avec un autre individu du département en dehors de la commune de notre individu à risque. Si le niveau départemental posait lui aussi problème on remonterait au niveau régional, etc.
Ainsi, en général, la méthode consistera à échanger la localisation d’individus ou de ménages (Longhurst, Tromans, and Young, n.d.).
Une autre souplesse de la méthode est de pouvoir prendre en compte des structures hiérarchiques entre les individus. Par exemple, lorsque le fichier d’individus contient également des informations sur la composition des ménages.
Dans ce cas, l’échange d’individus risque de déstabiliser la composition des ménages concernés, en termes d’âge en particulier: on pourrait voir se créer des ménages où il n’y a aucun individu majeur par exemple.
Une solution consisterait à échanger des ménages entiers plutôt que des individus. Mais cette solution n’est à retenir que si on dispose de suffisamment d’informations sur les ménages pour détecter des ménages similaires de bonne qualité. Si ce n’est pas le cas, il peut être préférable d’échanger des individus et de contrôler d’une autre manière, car un choix judicieux de variables de similarité peut limiter ces désagréments.
Le taux d’échange ou taux de swapping est la part d’individus du jeu de données qui a pris part aux échanges, soit \(s=\frac{E+D}{N}\), où \(E\) est le nombre d’individus à échanger, \(D\) le nombre de donneurs (\(D=E\)) et \(N\) le nombre d’individus dans la base.
En pratique, on fixe un taux de swapping \(s\) de telle sorte que l’algorithme procède à un minimum d’échanges. Si le nombre d’individus à risque ne permet pas d’atteindre ce seuil, des individus supplémentaires seront également échangés pour atteindre \(s\). Sinon, le taux de swapping étant atteint ou dépassé, aucun individu additionnel n’est ajouté.
TRS
TRS
est une méthode adaptéeL’avantage de la méthode est sa grande capacité d’adaptation aux données dont on dispose. Même si cette fiche va présenter comment l’appliquer avec le package sdcMicro
, il est en réalité tout à fait possible de développer son propre algorithme pour affiner la façon de tirer les individus ou les ménages à échanger.
On pourra se reporter à la fiche sur les mesures de risque pour en savoir plus sur les risques et la façon de les mesurer.
Pour installer les packages nécessaires, vous trouverez les instructions à suivre dans la fiche Ressources / Installer les packages et les outils sur R.
Attaching package: 'dplyr'
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
REG DEP ARR SEXE AGE AGE6 ACTEU DIP7 PCS1Q ANCCHOM HHID
<fctr> <fctr> <fctr> <fctr> <int> <fctr> <fctr> <fctr> <fctr> <fctr> <int>
1: 28 76 761 1 53 50 1 4 30 99 3558
2: 28 76 761 2 43 25 1 7 52 99 3558
3: 28 76 761 2 17 15 3 5 99 99 3558
4: 28 76 761 1 17 15 3 4 99 99 3558
5: 11 92 922 1 42 25 1 7 62 99 5973
6: 11 92 922 2 54 50 1 7 62 99 5973
HH_TAILLE HH_AGE HH_DIP HH_PCS IS_CHOM
<fctr> <fctr> <fctr> <fctr> <int>
1: 4 53 4 30 0
2: 4 53 4 30 0
3: 4 53 4 30 0
4: 4 53 4 30 0
5: 2 54 7 62 0
6: 2 54 7 62 0
Pour plus d’informations sur les données, on pourra se reporter à la fiche “Présentation des données”.
On définit les variables selon les différentes catégories suivantes:
key_vars
)sens_vars
)hhid_vars
)Pour cet exercice, nous ferons les choix suivants:
Les comptages par croisement des modalités des variables quasi-identifiantes:
Le tableau ci-dessous présente le nombre et la part d’individus du fichier ne répondant pas au critère du \(k\)-anonymat, en fonction de la valeur de \(k\).
k | nb_ind_risk | part_ind_risk |
---|---|---|
2 | 77 | 0.2 |
3 | 267 | 0.8 |
4 | 465 | 1.4 |
5 | 825 | 2.4 |
6 | 1105 | 3.2 |
7 | 1387 | 4.1 |
8 | 1723 | 5.1 |
9 | 2075 | 6.1 |
10 | 2498 | 7.3 |
On dénombre 77 individus uniques et jusqu’à 7.3% d’individus à risque si nous nous fixons comme objectif de respecter un \(10\)-anonymat dans notre fichier.
Pour traiter les individus à risque, on se propose d’utiliser un targeted record swapping.
risk_variables <- c("DEP", "AGE6","SEXE","DIP7") # les variables permettant de mesurer le risque de ré-identification
hierarchy <- c("REG", "DEP") # permet de renseigner l'existence d'une hiérarchie entre les var géographiques
carry_along <- c("ARR")
similar <- list( # Contraintes de similarité sur les individus échangés
c("REG","AGE6","SEXE"), # priorité 1
c("REG","SEXE"), # priorité 2 ...
c("REG","AGE6"),
c("AGE6","SEXE"),
"REG",
"SEXE"
)
hid <- "ID" # swapping d'individus
La fonction de swapping implémentée dans sdcMicro
nécessite de transformer toutes les variables en integer
.
On choisit de nous fixer comme objectif de traiter tous les individus ne respectant pas le \(5\)-anonymat et d’échanger au moins \(1\)% des individus.
Recordswapping was successful!
Le taux de swapping réel est légèrement inférieur au taux de swapping attendu (c’est-à-dire \(2\times2.4=4.8\%\)):
En réalité, un certain nombre d’individus à risque ont été échangés entre eux :
[1] 85
# A tibble: 4 × 2
REG `mean(ID != ID_swapped)`
<int> <dbl>
1 1 0.0239
2 2 0.0587
3 3 0.0671
4 4 0.295
REG DEP ARR SEXE AGE AGE6 ACTEU DIP7 PCS1Q ANCCHOM HHID
<int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
1: 1 27 79 2 17 1 3 5 10 10 3558
2: 2 19 53 2 23 1 3 2 10 10 7043
HH_TAILLE HH_AGE HH_DIP HH_PCS IS_CHOM ID ID_swapped
<int> <int> <int> <int> <int> <int> <int>
1: 4 39 4 4 0 3 20669
2: 8 43 3 10 0 20669 3
On peut remarquer que ces individus sont similaires sur la région, le sexe et l’âge (AGE6
).
Classes 'data.table' and 'data.frame': 34053 obs. of 18 variables:
$ REG : int 2 2 1 2 1 1 1 1 1 3 ...
$ DEP : int 19 19 27 19 25 25 26 21 21 9 ...
$ ARR : int 53 53 79 53 73 73 75 62 62 27 ...
$ SEXE : int 1 2 2 1 1 2 2 1 2 1 ...
$ AGE : int 53 43 17 17 42 54 57 20 17 28 ...
$ AGE6 : int 3 2 1 1 2 3 3 1 1 2 ...
$ ACTEU : int 1 1 3 3 1 1 1 3 3 1 ...
$ DIP7 : int 4 7 5 4 7 7 7 7 7 5 ...
$ PCS1Q : int 4 7 10 10 9 9 7 10 10 8 ...
$ ANCCHOM : int 10 10 10 10 10 10 10 10 10 10 ...
$ HHID : int 3558 3558 3558 3558 5973 5973 6779 4906 4906 1135 ...
$ HH_TAILLE : int 4 4 4 4 2 2 1 2 2 3 ...
$ HH_AGE : int 39 39 39 39 40 40 43 6 6 14 ...
$ HH_DIP : int 4 4 4 4 7 7 7 7 7 5 ...
$ HH_PCS : int 4 4 4 4 9 9 7 10 10 8 ...
$ IS_CHOM : int 0 0 0 0 0 0 0 0 0 0 ...
$ ID : int 1 2 3 4 5 6 7 8 9 10 ...
$ ID_swapped: int 1 2 20669 4 5 6 7 8 9 10 ...
- attr(*, ".internal.selfref")=<externalptr>
On procède à l’échange des géographies entre les individus:
hid <- "HHID" # swapping de ménages
similar <- list(c("HH_TAILLE", "HH_AGE"), c("HH_TAILLE"), c("HH_AGE"))
lfs_swapped_hh <- recordSwap(
data = lfs_2023_pr_swap,
hid = hid,
hierarchy = hierarchy,
similar = similar,
risk_variables = risk_variables,
carry_along = carry_along,
k_anonymity = k_anonymity,
swaprate = swaprate,
return_swapped_id = TRUE,
seed = 123456
)
Recordswapping was successful!
Joining with `by = join_by(REG, SEXE, AGE6)`
Mesure de l’écart absolu moyen :
Visualisation des distributions:
Joining with `by = join_by(DEP, SEXE, AGE6)`
[1] 0.1311475
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.0000 0.0000 0.0000 0.1311 0.0000 3.0000
On se propose de comparer les intervalles de confiance des coefficients d’un modèle logistique pour évaluer la perte d’information engendrée par le swapping.
Étudions la stabilité d’un modèle relativement simple, cherchant à expliquer le fait d’être au chômage par différentes variables à notre disposition: l’âge, le diplôme et le sexe.
On entraînera ce modèle uniquement sur la population active. On retire donc notamment la population étudiante et retraitée.
lfs_2023_pr_glm <- lfs_2023_pr_swap |> mutate(across(-IS_CHOM, as.character))
lfs_pert_pr_glm <- lfs_swapped |> mutate(across(-IS_CHOM, as.character))
m_original <- glm(IS_CHOM ~ REG + SEXE + AGE6 + DIP7, data = lfs_2023_pr_glm |> filter(ACTEU != 3))
m_swapped <- glm(IS_CHOM ~ REG + SEXE + AGE6 + DIP7, data = lfs_pert_pr_glm |> filter(ACTEU != 3))
mes_modeles <- list(
"original" = m_original,
"swapped" = m_swapped
)
all_cios <- get_all_confints(mes_modeles)
Joining with `by = join_by(vars)`
Comparer la perte d’information de différents taux de swapping. Vous utiliserez la mesure de perte d’information que vous souhaitez.
---
title: Appliquer le Target Record Swapping
href: pratique/fiches/proteger-micro-swapping.html
code-block-bg: true
code-block-border-left: "#bf9aff"
code-fold: show
---
# Objectif:
La fiche pratique présente comment appliquer le `Target Record Swapping` à
un jeu de données individuelles afin d'assurer une protection optimale
des informations confidentielles des individus (ou ménages ou entreprises) qui
le composent.
La première partie s'attache à présenter les différentes étapes à suivre pour
que cette application soit pertinente au regard des données utilisées.
La seconde partie montre comment utiliser la fonction `sdcMicro::recordSwap()`
pour appliquer la méthode à un jeu de données dont on aura repérer les
individus à risque préalablement.
::: {.callout-tip}
# Pour s'exercer
Pour reproduire les résultats et réaliser les exercices, il est possible de travailler
directement sur le [`datalab` de l'Insee](datalab.sspcloud.fr). Si vous disposez d'un compte, vous pouvez [Ouvrir un service RStudio](https://datalab.sspcloud.fr/launcher/ide/rstudio?name=rstudio-formation-protection&version=2.3.1&s3=region-ec97c721&init.personalInit=«https%3A%2F%2Fraw.githubusercontent.com%2FInseeFrLab%2Fformation_protection_donnees%2Frefs%2Fheads%2Fmain%2Finit-scripts%2Frstudio.sh») ou [Ouvrir un service vscode R-Python](https://datalab.sspcloud.fr/launcher/ide/vscode-r-python-julia?name=vscode-formation-protection&version=2.3.5&s3=region-ec97c721&init.personalInit=«https%3A%2F%2Fraw.githubusercontent.com%2FInseeFrLab%2Fformation_protection_donnees%2Frefs%2Fheads%2Fmain%2Finit-scripts%2Fvscode-r-python.sh»), à votre convenance. Ces services installeront automatiquement les packages
nécessaires pour réaliser les exercices de l'ensemble des fiches pratiques.
:::
# Rappels sur la méthode:
Le `Target Record Swapping (TRS)` est une méthode s'appliquant directement sur un jeu
de données individuelles pour réduire principalement les risques de ré-identification.
Il ciblera donc les individus pour lesquels ce risque est jugé trop élevé, c'est-à-dire
ceux partageant des caractéristiques trop rares sur un ensemble
de variables dites quasi-identifiantes. Les variables quasi-identifiantes sont celles
qui sont susceptibles d'être déjà publiques ou du moins à la disposition d'un attaquant.
D'où son nom: le *swapping*, c'est-à-dire
l'échange, va concerner des unités de la base (les *records*) détectés à l'avance,
devenant ainsi les cibles (*target*) sur lesquelles on va se concentrer.
Bien qu'elle soit appliquée sur des microdonnées, la méthode a principalement vocation à
protéger la diffusion de données tabulées [@hundepool_handbook_2024, [section 5.6](https://sdctools.github.io/HandbookSDC/05-frequency-tables.html#sec-TRS)]. Dans ce type d'utilisation, en tant que méthode pré-tabulée,
elle permet de produire des tableaux parfaitement additifs.
## En quoi consiste la méthode ?
Après avoir détecté un individu dont le risque de ré-identification est jugé trop
élevé, un autre individu est tiré aléatoirement parmi les individus au risque de ré-identification
les plus faibles et certaines des caractéristiques de ces deux individus sont échangées (*swapped*).
Après l'échange, la ré-identification de l'individu est rendue beaucoup plus difficile et
ne permet plus d'obtenir d'informations pertinentes à son sujet.
::: {.callout-note}
### Un exemple très simple.
Soit un territoire donné découpé en six zones où résident un certain nombre d'individus.
Avec les informations disponibles à leur sujet, on considère qu'un seul individu a un risque
de ré-identification trop élevé (croix rouge sur la @fig-swap-avant).
::: {#fig-swap-avant}

:::
On tire alors au hasard un autre individu présent sur le territoire pour échanger
certaines de leurs caractéristiques. Ce tirage pourrait être purement aléatoire. Mais, cela
conduirait à détruire certaines statistiques bien utiles. Par exemple, en trouvant
un individu d'une autre zone partageant certaines caractéristiques (par exemple
le sexe, l'âge et la catégorie sociale, @fig-swap-apres), on s'assure de conserver les marges
sur ces variables au niveau géographique le plus fin.
En revanche, les autres caractéristiques sont bruitées de façon non contrôlée.
::: {#fig-swap-apres}

:::
Ainsi, l'éventuelle ré-identification de l'individu à risque ne pourrait conduire
l'attaquant qu'à obtenir des informations très probablement fausses à son sujet.
:::
## Les variables de similarité
La méthode est très souple puisqu'elle permet de s'adapter aux données dont on dispose et
aux besoins en termes de diffusion. Les **variables de similarité** entre individus échangés
peuvent ainsi être choisies parmi les variables dont on veut conserver
le mieux possible l'information marginale. En effet, en échangeant des individus
parfaitement similaires sur certaines caractéristiques (**les variables de similarité**),
l'échange ne produira aucune perte d'information sur celles-ci.
::: {.callout-warning}
### Similarité et ré-identification
Si l'objectif est de réduire le risque de ré-identification, sélectionner toutes les variables
quasi-identifiantes comme variables de similarité ne perturberait aucunement
la capacité de l'attaquant à ré-identifier les individus. Ce choix produirait
en revanche du bruit sur les autres variables: donc en ré-identifiant, l'attaquant
ne serait pas en mesure d'obtenir des informations supplémentaires fiables.
:::
::: {.callout-tip}
### Utiliser la hiérarchie des emboîtements géographiques
Les données contiennent généralement des informations géographiques. Or, la géographie,
en particulier à des niveaux fins, est très identifiante. On choisira en général
d'échanger des individus résidant à des endroits différents, en tenant compte
du niveau géographique auquel un individu est facilement ré-identifiable.
Par exemple, si un individu est facilement ré-identifiable dans sa commune mais
pas dans son département de résidence, alors on privilégiera l'échange avec
un autre individu du département en dehors de la commune de notre individu à risque.
Si le niveau départemental posait lui aussi problème on remonterait au niveau régional, etc.
Ainsi, en général, la méthode consistera à échanger la localisation d'individus ou de ménages [@longhurst_statistical_nodate].
:::
### Comment définir des individus similaires ?
La **similarité** entre deux individus peut être envisagée de deux manières:
- en cherchant la **correspondance exacte** sur les variables de similarité, quitte à relâcher
des contraintes quand il n'y pas de donneur: un donneur est tiré aléatoirement parmi la liste
des prétendants.
- en calculant une **distance** entre le receveur et l'ensemble des donneurs: un donneur est
tiré parmi les individus avec lesquels la distance est la plus faible.
La première option nécessite d'utiliser uniquement des variables catégorielles,
quitte à créer des classes pour les variables continues qu'on souhaiterait inclure
dans la liste.
Dans la pratique, cette première option est la moins gourmande en ressources de calcul,
car elle ne nécessite pas de calculer une distance entre chaque receveur et chaque donneur potentiel.
Elle est probablement la seule envisageable si le jeu de données contient plusieurs millions de lignes.
::: {.callout-tip}
### Une astuce pour gérer la présence de poids de sondage
Si nous disposons d'un échantillon, chaque individu dispose d'un poids de sondage.
Avec le `Target Record Swapping`, on prend le risque d'échanger deux individus avec des poids très différents et
de déséquilibrer des agrégats importants. Pour éviter ce genre de désagrément, il est possible
d'ajouter le poids parmi les variables de similarité, sous la forme d'un arrondi à l'unité
ou bien de tranches de valeurs. On pourra également exclure des donneurs potentiels,
les individus ayant des poids très élevés comparés aux autres. Ceci permettra de limiter
les déformations des distributions.
:::
### Individus ou ménages ?
Une autre souplesse de la méthode est de pouvoir prendre en compte des
structures hiérarchiques entre les individus. Par exemple, lorsque le fichier
d'individus contient également des informations sur la composition des ménages.
Dans ce cas, l'échange d'individus risque de déstabiliser la composition des
ménages concernés, en termes d'âge en particulier: on pourrait voir se créer des
ménages où il n'y a aucun individu majeur par exemple.
Une solution consisterait à échanger des ménages entiers plutôt que des individus.
Mais cette solution n'est à retenir que si on dispose de suffisamment d'informations
sur les ménages pour détecter des ménages similaires de bonne qualité.
Si ce n'est pas le cas, il peut être préférable d'échanger des individus et de contrôler
d'une autre manière, car un choix judicieux de variables de similarité peut limiter ces
désagréments.
<!-- La @tbl-exemple-ind-men présente un exemple de données individuelles contenant une information
sur la composition des ménages. Ici, les individus sont répartis en deux ménages de trois individus, dont deux adultes.
Pour chaque individu, une mesure de risque de ré-identification est fournie. Le premier individu
est le seul dont le risque de ré-identification est très élevé.
| ID | Géo. | Sexe | Age | Statut | Diplome | Catégorie<br>Sociale | Risque | Ménage |
|-----|------|------|-----|-----------|---------|----------------------|-------:|--------|
| ID1 | C1 | H | 35 | Chômage | Bac+2 | Employé | 1 | MEN1 |
| ID2 | C1 | F | 40 | En emploi | Bac+5 | Cadre | 0,05 | MEN1 |
| ID3 | C1 | F | 12 | Inactif | | Elève | 0,05 | MEN1 |
| ID4 | C2 | H | 55 | En emploi | Bac+5 | Cadre | 0,05 | MEN2 |
| ID5 | C2 | F | 53 | En emploi | Bac+5 | Cadre | 0,05 | MEN2 |
| ID6 | C2 | H | 17 | Inactif | BEP | Ouvrier | 0,05 | MEN2 |
: Table indiviudelle et composition des ménages {.striped #tbl-exemple-ind-men}
:::: {.columns}
::: {.column width="45%"}
:::
::: {.column width="5%"}
:::
::: {.column width="45%"}
:::
::::
-->
### Le taux de *swapping*
Le __taux d'échange__ ou __taux de *swapping*__ est la part d'individus du jeu de données
qui a pris part aux échanges, soit $s=\frac{E+D}{N}$, où $E$ est le nombre d'individus à échanger,
$D$ le nombre de donneurs ($D=E$) et $N$ le nombre d'individus dans la base.
En pratique, on fixe un taux de swapping $s$ de telle sorte que l'algorithme procède à un minimum
d'échanges. Si le nombre d'individus à risque ne permet pas d'atteindre ce seuil, des individus
supplémentaires seront également échangés pour atteindre $s$. Sinon, le taux de swapping étant atteint ou dépassé,
aucun individu additionnel n'est ajouté.
## Les grandes étapes à suivre pour appliquer le `TRS`
1. De quels risques cherche-t-on à se protéger ?
1. Si c'est du risque de ré-identification, le `TRS` est une méthode adaptée
2. Sinon, il faut peut-être aller voir ailleurs.
2. Quelles sont les variables quasi-identifiantes dans mes données ?
3. Mesurer le risque de ré-identification basé sur ces variables ?
4. Choisir un seuil de risque de ré-identification maximal acceptable, au-delà duquel les individus devront être traités.
5. Quelles sont les marges que la méthode devrait conserver intactes en priorité ?
6. Un *swapping* des ménages est-il préférable à un swapping d'individus ?
7. Sélection des paramètres de la méthode:
1. Les variables de similarités, en tenant compte des risques et des objectifs de diffusion.
2. Le taux de swapping.
8. Procéder au swapping
9. Mesurer la perte d'information
10. Reprendre les étapes 4. à 9. si la perte d'information s'avère trop grande ou la protection trop faible
L'avantage de la méthode est sa grande capacité d'adaptation aux données dont on dispose.
Même si cette fiche va présenter comment l'appliquer avec le package `sdcMicro`,
il est en réalité tout à fait possible de développer son propre algorithme pour
affiner la façon de tirer les individus ou les ménages à échanger.
On pourra se reporter à la
[fiche sur les mesures de risque](pratique/fiches/mesurer-risque.html)
pour en savoir plus sur les risques et la façon de les mesurer.
# En pratique
Pour installer les packages nécessaires, vous trouverez les instructions à suivre
dans la fiche [Ressources / Installer les packages et les outils sur R](../../ressources/fiches/outils-install.html).
## Les packages
```{r}
#| eval: false
#| echo: false
setwd("./pratique/fiches")
```
```{r}
#| echo: false
library(readr)
library(purrr)
library(dplyr)
library(ggplot2)
library(sdcMicro)
```
## Les données
```{r}
source("../R/fun_import_data.R")
lfs_2023 <- import_lfs()
```
```{r}
head(lfs_2023)
```
Pour plus d'informations sur les données, on pourra se reporter à la fiche
["Présentation des données"](description-data.html).
## Mesurons les risques du fichier
### Les types de variables
On définit les variables selon les différentes catégories suivantes:
- les variables quasi-identifiantes (`key_vars`)
- les variables sensibles (`sens_vars`)
- les variables identifiant la composition des ménages (`hhid_vars`)
Pour cet exercice, nous ferons les choix suivants:
```{r}
key_vars <- c("AGE6","SEXE","DEP","DIP7")
sens_vars <- c("ACTEU","ANCCHOM","IS_CHOM")
hhid_vars <- c("HHID")
```
Les comptages par croisement des modalités des variables quasi-identifiantes:
```{r}
lfs_sdc <- sdcMicro::createSdcObj(
lfs_2023,
keyVars = key_vars
)
```
Le tableau ci-dessous présente le nombre et la part d'individus du fichier ne répondant pas
au critère du $k$-anonymat, en fonction de la valeur de $k$.
```{r}
ks <- 2:10
data.frame(
k = ks,
nb_ind_risk = sapply(ks, \(k) sum(lfs_sdc@risk$individual[,"fk"] < k))
) |>
mutate(part_ind_risk = nb_ind_risk / nrow(lfs_2023) * 100) |>
knitr::kable(digits=1)
```
On dénombre 77 individus uniques et jusqu'à 7.3% d'individus à risque si nous nous fixons comme objectif de
respecter un $10$-anonymat dans notre fichier.
Pour traiter les individus à risque, on se propose d'utiliser un targeted record swapping.
## Préparation pour le swapping
```{r}
risk_variables <- c("DEP", "AGE6","SEXE","DIP7") # les variables permettant de mesurer le risque de ré-identification
hierarchy <- c("REG", "DEP") # permet de renseigner l'existence d'une hiérarchie entre les var géographiques
carry_along <- c("ARR")
similar <- list( # Contraintes de similarité sur les individus échangés
c("REG","AGE6","SEXE"), # priorité 1
c("REG","SEXE"), # priorité 2 ...
c("REG","AGE6"),
c("AGE6","SEXE"),
"REG",
"SEXE"
)
hid <- "ID" # swapping d'individus
```
La fonction de swapping implémentée dans `sdcMicro` nécessite de transformer toutes les variables en `integer`.
```{r}
lfs_2023_pr_swap <- lfs_2023 |>
mutate(across(everything(), as.integer))|>
mutate(ID = 1:n())
```
## Swapper les individus
On choisit de nous fixer comme objectif de traiter tous les individus ne respectant pas
le $5$-anonymat et d'échanger au moins $1$% des individus.
```{r}
k_anonymity <- 5
swaprate <- .01
```
```{r}
lfs_swapped <- recordSwap(
data = lfs_2023_pr_swap,
hid = hid,
hierarchy = hierarchy,
similar = similar,
risk_variables = risk_variables,
carry_along = carry_along,
k_anonymity = k_anonymity,
swaprate = swaprate,
return_swapped_id = TRUE,
seed = 123456 # pour la reproductibilité
)
```
Le taux de swapping réel est légèrement inférieur au taux de swapping attendu (c'est-à-dire $2\times2.4=4.8\%$):
```{r}
lfs_swapped %>% summarise(mean(ID != ID_swapped)) * 100
```
En réalité, un certain nombre d'individus à risque ont été échangés entre eux :
```{r}
ind_risk <- which(lfs_sdc@risk$individual[,"fk"] < 5)
lfs_swapped |>
slice(ind_risk) |>
filter(ID_swapped %in% ind_risk) |>
nrow() /2
```
```{r}
lfs_swapped %>%
group_by(REG) %>%
summarise(mean(ID != ID_swapped))
```
### Un exemple d'échange
```{r}
premier_couple <- lfs_swapped |> slice(ind_risk[1]) |>
bind_rows(lfs_swapped |> filter(ID_swapped == ind_risk[1]))
```
```{r}
premier_couple
```
On peut remarquer que ces individus sont similaires sur la région, le sexe et l'âge (`AGE6`).
<!--
#### Vérifier que les individus à risque ont bien été swappés
```{r}
lfs_swapped
```
#### Intégrité de la composition des ménages
-->
## La base swappée
```{r}
str(lfs_swapped)
```
On procède à l'échange des géographies entre les individus:
```{r}
lfs_pert <- lfs_swapped |>
select(-REG, -DEP, -ARR, -ID_swapped)|>
full_join(
lfs_swapped |> select(REG, DEP, ARR, ID=ID_swapped),
by = "ID"
)
```
## Swapper les ménages
```{r}
hid <- "HHID" # swapping de ménages
similar <- list(c("HH_TAILLE", "HH_AGE"), c("HH_TAILLE"), c("HH_AGE"))
lfs_swapped_hh <- recordSwap(
data = lfs_2023_pr_swap,
hid = hid,
hierarchy = hierarchy,
similar = similar,
risk_variables = risk_variables,
carry_along = carry_along,
k_anonymity = k_anonymity,
swaprate = swaprate,
return_swapped_id = TRUE,
seed = 123456
)
```
#### Taux de swapping des ménages vs taux de swapping des individus
```{r}
lfs_swapped_hh %>% summarise(mean(HHID != HHID_swapped))
```
## Mesurer la perte d'utilité
```{r}
reg_sex_age <- lfs_swapped |> count(REG, SEXE, AGE6, name="n_p") |>
left_join(lfs_2023_pr_swap |> count(REG, SEXE, AGE6, name = "n_o"))|>
mutate(n_p = ifelse(is.na(n_p), 0, n_p))|>
mutate(n_o = ifelse(is.na(n_o), 0, n_o))
```
Mesure de l'écart absolu moyen :
```{r}
mean(abs(reg_sex_age$n_p - reg_sex_age$n_o))
```
Visualisation des distributions:
```{r}
reg_sex_age |> mutate(cl = 1:n()) |>
tidyr::pivot_longer(n_p:n_o, names_to = "type", values_to = "n") |>
ggplot() +
geom_bar(aes(x=cl, y=n, fill=type), stat = "identity", position = "dodge")
```
```{r}
dep_sex_age <- lfs_swapped |> count(DEP, SEXE, AGE6, name="n_p") |>
left_join(lfs_2023_pr_swap |> count(DEP, SEXE, AGE6, name = "n_o")) |>
mutate(n_p = ifelse(is.na(n_p), 0, n_p))|>
mutate(n_o = ifelse(is.na(n_o), 0, n_o)) |>
mutate(diff_abs = abs(n_p - n_o))
mean(dep_sex_age$diff_abs)
```
```{r}
summary(dep_sex_age$diff_abs)
```
On se propose de comparer les intervalles de confiance des coefficients d'un modèle logistique
pour évaluer la perte d'information engendrée par le swapping.
```{r}
source("../R/fun_cio.R")
```
Étudions la stabilité d'un modèle relativement simple, cherchant à expliquer
le fait d'être au chômage par différentes variables à notre disposition:
l'âge, le diplôme et le sexe.
On entraînera ce modèle uniquement sur la population active. On retire donc notamment
la population étudiante et retraitée.
```{r}
lfs_2023_pr_glm <- lfs_2023_pr_swap |> mutate(across(-IS_CHOM, as.character))
lfs_pert_pr_glm <- lfs_swapped |> mutate(across(-IS_CHOM, as.character))
m_original <- glm(IS_CHOM ~ REG + SEXE + AGE6 + DIP7, data = lfs_2023_pr_glm |> filter(ACTEU != 3))
m_swapped <- glm(IS_CHOM ~ REG + SEXE + AGE6 + DIP7, data = lfs_pert_pr_glm |> filter(ACTEU != 3))
mes_modeles <- list(
"original" = m_original,
"swapped" = m_swapped
)
all_cios <- get_all_confints(mes_modeles)
```
```{r}
graph_cios(all_cios, titre = "Superposition des intervalles de confiance\ndes Odds Ratio du modèle selon le jeu de données") +
theme(axis.text.y = element_text(size = 8))
```
## Exercice
Comparer la perte d'information de différents taux de swapping.
Vous utiliserez la mesure de perte d'information que vous souhaitez.
Comment définir des individus similaires ?
La similarité entre deux individus peut être envisagée de deux manières:
La première option nécessite d’utiliser uniquement des variables catégorielles, quitte à créer des classes pour les variables continues qu’on souhaiterait inclure dans la liste.
Dans la pratique, cette première option est la moins gourmande en ressources de calcul, car elle ne nécessite pas de calculer une distance entre chaque receveur et chaque donneur potentiel. Elle est probablement la seule envisageable si le jeu de données contient plusieurs millions de lignes.
Si nous disposons d’un échantillon, chaque individu dispose d’un poids de sondage. Avec le
Target Record Swapping
, on prend le risque d’échanger deux individus avec des poids très différents et de déséquilibrer des agrégats importants. Pour éviter ce genre de désagrément, il est possible d’ajouter le poids parmi les variables de similarité, sous la forme d’un arrondi à l’unité ou bien de tranches de valeurs. On pourra également exclure des donneurs potentiels, les individus ayant des poids très élevés comparés aux autres. Ceci permettra de limiter les déformations des distributions.