Come posso trasformare i nomi in un set di dati confidenziali per renderlo anonimo, ma preservare alcune delle caratteristiche dei nomi?


42

Motivazione

Lavoro con set di dati che contengono informazioni di identificazione personale (PII) e talvolta ho bisogno di condividere parte di un set di dati con terze parti, in un modo che non espone le PII e sottopone il mio datore di lavoro alla responsabilità. Il nostro approccio abituale qui è quello di trattenere i dati interamente, o in alcuni casi per ridurne la risoluzione; ad esempio, la sostituzione di un indirizzo esatto con la contea o il tratto di censimento corrispondenti.

Ciò significa che determinati tipi di analisi ed elaborazione devono essere eseguiti internamente, anche quando una terza parte ha risorse e competenze più adatte all'attività. Poiché i dati di origine non vengono divulgati, il modo in cui procediamo con questa analisi ed elaborazione manca di trasparenza. Di conseguenza, la capacità di qualsiasi terza parte di eseguire QA / QC, regolare i parametri o apportare perfezionamenti può essere molto limitata.

Anonimizzazione dei dati riservati

Un'attività consiste nell'identificare le persone con i loro nomi, nei dati inviati dall'utente, tenendo conto degli errori e delle incoerenze. Un privato potrebbe essere registrato in un posto come "Dave" e in un altro come "David", le entità commerciali possono avere molte abbreviazioni diverse e ci sono sempre alcuni errori di battitura. Ho sviluppato script basati su una serie di criteri che determinano quando due record con nomi non identici rappresentano lo stesso individuo e assegnano loro un ID comune.

A questo punto possiamo rendere anonimo il set di dati trattenendo i nomi e sostituendoli con questo numero ID personale. Ma questo significa che il destinatario non ha quasi alcuna informazione, ad esempio sull'intensità della partita. Preferiremmo essere in grado di trasmettere quante più informazioni possibili senza divulgare l'identità.

Cosa non funziona

Ad esempio, sarebbe bello poter crittografare le stringhe preservando la distanza di modifica. In questo modo, le terze parti potrebbero eseguire parte del proprio QA / QC o scegliere di effettuare ulteriori elaborazioni per conto proprio, senza mai accedere (o essere in grado di eseguire il reverse engineering) delle PII. Forse abbiniamo le stringhe internamente con la modifica della distanza <= 2 e il destinatario vuole esaminare le implicazioni del rafforzamento di tale tolleranza per modificare la distanza <= 1.

Ma l'unico metodo che ho familiarità con ciò è ROT13 (più in generale, qualsiasi cifra di spostamento ), che a malapena conta come crittografia; è come scrivere i nomi sottosopra e dire: "Prometti di non capovolgere il foglio?"

Un'altra cattiva soluzione sarebbe abbreviare tutto. "Ellen Roberts" diventa "ER" e così via. Questa è una soluzione scadente perché in alcuni casi le iniziali, in associazione con i dati pubblici, rivelano l'identità di una persona, e in altri casi è troppo ambigua; "Benjamin Othello Ames" e "Bank of America" ​​avranno le stesse iniziali, ma i loro nomi sarebbero altrimenti diversi. Quindi non fa nessuna delle cose che vogliamo.

Un'alternativa non elegante è quella di introdurre campi aggiuntivi per tenere traccia di alcuni attributi del nome, ad esempio:

+-----+----+-------------------+-----------+--------+
| Row | ID | Name              | WordChars | Origin |
+-----+----+-------------------+-----------+--------+
| 1   | 17 | "AMELIA BEDELIA"  | (6, 7)    | Eng    |
+-----+----+-------------------+-----------+--------+
| 2   | 18 | "CHRISTOPH BAUER" | (9, 5)    | Ger    |
+-----+----+-------------------+-----------+--------+
| 3   | 18 | "C J BAUER"       | (1, 1, 5) | Ger    |
+-----+----+-------------------+-----------+--------+
| 4   | 19 | "FRANZ HELLER"    | (5, 6)    | Ger    |
+-----+----+-------------------+-----------+--------+

Lo chiamo "inelegante" perché richiede di anticipare quali qualità potrebbero essere interessanti ed è relativamente grossolano. Se i nomi vengono rimossi, non c'è molto che si possa ragionevolmente concludere sulla forza della corrispondenza tra le righe 2 e 3, o sulla distanza tra le righe 2 e 4 (cioè, quanto sono vicine alla corrispondenza).

Conclusione

L'obiettivo è quello di trasformare le stringhe in modo tale da preservare quante più qualità utili della stringa originale mentre oscuri la stringa originale. La decrittazione dovrebbe essere impossibile o così poco pratica da essere effettivamente impossibile, indipendentemente dalle dimensioni del set di dati. In particolare, sarebbe molto utile un metodo che preservi la distanza di modifica tra stringhe arbitrarie.

Ho trovato un paio di articoli che potrebbero essere rilevanti, ma sono un po 'sopra la mia testa:

Risposte:


19

Uno dei riferimenti che ho citato nel PO mi ha portato a una potenziale soluzione che sembra abbastanza potente, descritta in "Collegamento dei record che preserva la privacy usando i filtri Bloom" ( doi: 10.1186 / 1472-6947-9-41 ):

È stato sviluppato un nuovo protocollo per il collegamento dei record a tutela della privacy con identificatori crittografati che consente errori negli identificatori. Il protocollo si basa sui filtri Bloom su q-grammi di identificatori.

L'articolo approfondisce il metodo, che riassumerò qui al meglio delle mie capacità.

Un filtro Bloom è una serie di bit a lunghezza fissa che memorizza i risultati di un insieme fisso di funzioni hash indipendenti, ciascuna calcolata sullo stesso valore di input. L'output di ciascuna funzione hash dovrebbe essere un valore di indice tra i possibili indici nel filtro; vale a dire, se si dispone di una serie con indice 0 di 10 bit, le funzioni hash dovrebbero restituire (o essere mappate a) valori da 0 a 9.

Il filtro inizia con ciascun bit impostato su 0. Dopo aver eseguito l'hashing del valore di input con ciascuna funzione dal set di funzioni hash, ogni bit corrispondente a un valore di indice restituito da qualsiasi funzione hash viene impostato su 1. Se lo stesso indice viene restituito da più di una funzione hash, il bit in quell'indice viene impostato solo una volta. Potresti considerare il filtro Bloom come una sovrapposizione dell'insieme di hash sull'intervallo fisso di bit.

Il protocollo descritto nell'articolo collegato sopra divide le stringhe in n-grammi, che in questo caso sono gruppi di caratteri. Ad esempio, "hello"potrebbe produrre il seguente set di 2 grammi:

["_h", "he", "el", "ll", "lo", "o_"]

Riempire la parte anteriore e posteriore con spazi sembra essere generalmente facoltativo nella costruzione di n-grammi; gli esempi forniti nel documento che propone questo metodo utilizzano tale imbottitura.

Ogni n-grammo può essere sottoposto a hash per produrre un filtro Bloom e questo set di filtri Bloom può essere sovrapposto su se stesso (operazione OR bit a bit) per produrre il filtro Bloom per la stringa.

Se il filtro contiene molti più bit di quanti ce ne siano funzioni hash o n-grammi, è improbabile che stringhe arbitrarie producano esattamente lo stesso filtro. Tuttavia, più n-grammi hanno due stringhe in comune, più bit condivideranno i loro filtri. È quindi possibile confrontare due filtri qualsiasi A, Btramite il loro coefficiente Dadi:

D A, B = 2h / (a ​​+ b)

Dov'è hil numero di bit impostati su 1 in entrambi i filtri, aè il numero di bit impostato su 1 nel solo filtro A ed bè il numero di bit impostato su 1 nel solo filtro B. Se le stringhe sono esattamente le stesse, il coefficiente dei dadi sarà 1; più differiscono, più il coefficiente sarà vicino 0.

Poiché le funzioni hash stanno mappando un numero indeterminato di input univoci su un piccolo numero di possibili indici di bit, input diversi possono produrre lo stesso filtro, quindi il coefficiente indica solo una probabilità che le stringhe siano uguali o simili. Il numero di diverse funzioni hash e il numero di bit nel filtro sono parametri importanti per determinare la probabilità di falsi positivi - predice coppie di input che sono molto meno simili al coefficiente Dice prodotto da questo metodo.

Ho trovato questo tutorial molto utile per comprendere il filtro Bloom.

Vi è una certa flessibilità nell'attuazione di questo metodo; vedere anche questo documento del 2010 (anch'esso collegato alla fine della domanda) per alcune indicazioni di quanto sia performante rispetto ad altri metodi e con vari parametri.


Contrassegnando questa come la risposta accettata perché fuori dagli approcci suggeriti, è la più promettente per il mio caso d'uso particolare.
Air

Grazie per tutti questi dettagli e lo sfondo. Ti sei imbattuto in qualche implementazione (ad esempio in Python) di questo approccio?
amball

@amball non l'ho fatto.
Air

8

A metà della lettura della tua domanda, ho capito che Levenshtein Distance poteva essere una buona soluzione al tuo problema. È bello vedere che hai un link a un articolo sull'argomento, fammi vedere se posso far luce su come sarebbe una soluzione di Levenshtein.

La distanza di Levenshtein viene utilizzata in molti settori per la risoluzione delle entità, ciò che lo rende utile è che è una misura della differenza tra due sequenze. Nel caso del confronto tra stringhe si tratta solo di caratteri sequenziali.

Ciò potrebbe aiutare a risolvere il problema consentendoti di fornire un numero che fornisca una misura di quanto sia simile il testo di un altro campo.

Ecco un esempio di un modo di base per utilizzare Levenshtein con i dati forniti:

inserisci qui la descrizione dell'immagine

Questo fornisce una soluzione ok, la distanza di 8 fornisce alcune indicazioni di una relazione ed è molto conforme alle PII. Tuttavia, non è ancora super utile, vediamo cosa succede se facciamo un po 'di magia del testo per prendere solo la prima iniziale del nome e il cognome completo facendo cadere qualcosa nel mezzo:

inserisci qui la descrizione dell'immagine

Come puoi vedere, la distanza di Levenshtein di 0 è piuttosto indicativa di una relazione. Comunemente i fornitori di dati combinano un gruppo di permutazioni di Levenshtein del nome e del cognome con 1, 2 o tutti i caratteri solo per dare una certa dimensionalità su come le entità sono correlate mantenendo l'anonimato all'interno dei dati.


1
Ciò che mi interessa del documento che ho collegato è che afferma di mostrare un metodo per eseguire questo tipo di calcolo senza la conoscenza di entrambe le stringhe di input . Nel documento, ogni attore ha conoscenza di una stringa, che non è utile per i miei scopi; Avrei bisogno di un attore per poter eseguire il calcolo senza la conoscenza di nessuna delle due stringhe. Calcolarli in anticipo è possibile solo per set di dati molto piccoli o prodotti molto limitati; un prodotto incrociato completo di distanze intere nel mio set di dati richiederebbe circa 10 PB di memoria.
Air

Ecco perché ho sollevato l'idea di un codice di sostituzione (ROT13) poiché conserva la distanza tra le stringhe; ma non è sicuro e sospetto che potrebbe essere impossibile crittografare in modo sicuro le stringhe preservando la distanza di modifica. (Mi piacerebbe sbagliarmi!)
Air

Bene, vorrei solo filtrare la matrice per includere solo Levenshtein al di sotto di un certo limite, quindi stai popolando solo dove c'è un'alta probabilità di sovrapposizione. Inoltre, quando si tratta di PII, sono dell'idea che se includi abbastanza informazioni per determinare una relazione tra entità disparate nei tuoi set di dati, è molto improbabile che tu stia preservando l'anonimato dei clienti. Il punto di anonimizzare i dati è quello di evitare potenziali mal di testa regolamentari relativi alle PII su quella linea (gli standard possono sempre essere inaspriti), quindi personalmente non correrei il rischio.
neone4373,

7

Se possibile, collegherei i record correlati (ad esempio, Dave, David, ecc.) E li sostituirei con un numero progressivo (1,2,3, ecc.) O un hash salato della stringa utilizzato per rappresentare tutti i record correlati ( ad es. David invece di Dave).

Presumo che i terzi non debbano avere idea di quale sia il vero nome, altrimenti potresti anche darglielo.

modifica : è necessario definire e giustificare il tipo di operazioni che la terza parte deve essere in grado di eseguire. Ad esempio, cosa c'è di sbagliato nell'utilizzare le iniziali seguite da un numero (ad esempio, BOA-1, BOA-2, ecc.) Per chiarire l'ambiguità di Bank of America da Benjamin Othello Ames? Se questo è troppo rivelatore, potresti raccogliere alcune delle lettere o dei nomi; ad es. [AE] -> 1, [FJ] -> 2, ecc., quindi BOA diventerebbe 1OA, oppure ["Bank", "Barry", "Bruce", ecc.] -> 1, quindi Bank of America è di nuovo 1OA.

Per ulteriori informazioni, consultare l' anonimato k .


Apprezzo il riferimento k-anonimato e il suggerimento bin - che mi dà alcune cose nuove a cui pensare.
Air

6

Un'opzione (a seconda della dimensione del set di dati) è quella di fornire solo distanze di modifica (o altre misure di somiglianza che stai utilizzando) come set di dati aggiuntivo.

Per esempio:

  1. Genera un set di nomi univoci nel set di dati
  2. Per ciascun nome, calcola la distanza di modifica tra loro
  3. Genera un ID o un hash irreversibile per ciascun nome
  4. Sostituisci i nomi nel set di dati originale con questo ID
  5. Fornire una matrice di distanze di modifica tra numeri ID come nuovo set di dati

Anche se c'è ancora molto che si potrebbe fare per rendere anonimi i dati da questi.

Ad esempio, se "Tim" è noto per essere il nome più popolare per un ragazzo, il conteggio delle frequenze degli ID che corrispondono strettamente alla percentuale nota di Tims nella popolazione potrebbe darlo via. Da lì puoi quindi cercare nomi con una distanza di modifica di 1 e concludere che tali ID potrebbero riferirsi a "Tom" o "Jim" (se combinato con altre informazioni).


5

Non ne sono del tutto sicuro, ma forse l'hashing sensibile alla località è una buona soluzione. Fa l'hashing dei dati di input (nel tuo caso - nomi), quindi le stringhe originali verrebbero conservate. Dall'altro lato, l'idea principale di LSH è quella di massimizzare la probabilità di hash per oggetti simili. Ci sono molte diverse implementazioni di LSH. Ho provato Nilsimsa-hash per confrontare i testi dei tweet e ha funzionato abbastanza bene. Ma non sono sicuro di come funzionerà in caso di stringhe brevi (nomi): questo problema richiede test. Ho provato i tuoi esempi, ed ecco il risultato (nome A, nome B, "distanza" - il massimo è 120):

1. AMELIA BEDELIA  - CHRISTOPH BAUER - 107
2. AMELIA BEDELIA  - C J BAUER       - 82
3. AMELIA BEDELIA  - FRANZ HELLER    - 91
4. CHRISTOPH BAUER - C J BAUER       - 81
5. CHRISTOPH BAUER - FRANZ HELLER    - 98
6. C J BAUER       - FRANZ HELLER    - 83

Come vedi, CHRISTOPH BAUER e CJ BAUER si sono rivelati la coppia più vicina. Ma la differenza non è significativa. E solo per esempio - rappresentazione hash di questi nomi:

AMELIA BEDELIA  6b208299602b5000c3005a048122a43a828020889042240005011c1880864502
CHRISTOPH BAUER 22226448000ab10102e2860b52062487ff0000928e0822ee106028016cc01237
C J BAUER       2282204100961060048050004400240006032400148000802000a80130402002
FRANZ HELLER    58002002400880080b49172044020008030002442631e004009195020ad01158

3

Ecco un approccio che non ho visto menzionato: separare il processo in due passaggi: il primo passaggio si è concentrato sulla codifica dei nomi in modo che le versioni alternative con lo stesso nome siano codificate allo stesso modo (o quasi lo stesso) e il secondo passaggio si è concentrato sulla creazione loro anonimi.

Per il primo passo, è possibile utilizzare uno degli algoritmi fonetici (Soundex e varianti) , applicato a nome, cognome e iniziali in vari ordini. (Vedi anche questo articolo ). È in questo passaggio che si risolvono somiglianze vs. differenze nei nomi per bilanciare falsi positivi da falsi negativi.

Per il secondo passaggio, puoi scegliere qualsiasi metodo di hashing o crittografico che ti piace, senza preoccuparti di come quel metodo influisce sulla corrispondenza dei nomi. Questo ti dà la libertà di usare un metodo che ha le migliori caratteristiche sia per prestazioni, robustezza e anonimato.


Non credo che questo suggerimento affronti il ​​problema come è presentato nella domanda. Dov'è la flessibilità post-crittografia? Come perfeziono la vostra analisi senza accedere ai dati originali?
Air

@AirThomas Mi dispiace ma non capisco le tue due domande. Cosa intendi con "flessibilità post-crittografia"? Non ho visto nulla nella tua domanda / descrizione del genere. Cosa intendi con "affina la tua analisi senza accedere ai dati originali"? Non ho visto nulla sulla "raffinazione".
MrMeritology il

1
Ho cercato di identificare il problema nel secondo paragrafo della sezione Motivazione . Immagina, ad esempio, di voler rilasciare il tuo set di dati a vari ricercatori che vogliono fare alcuni modelli. Esistono numerose metodologie intelligenti ed efficaci che potrebbero essere applicate e ogni ricercatore lavora in modo leggermente diverso. Non è possibile divulgare i nomi di privati ​​nel set di dati. Se esegui quella parte dell'analisi prima di rilasciare i dati, forza la tua scelta di metodologia su tutti.
Air

Se fornisci inoltre hash dei nomi, il vantaggio è che terze parti possono distinguere l'identità esatta, ma non di più. Quindi la domanda è: come potresti fornire maggiori informazioni sui dati che non puoi rilasciare? Ad esempio, esiste un metodo che mantiene nell'output di hashing / crittografia la distanza di modifica tra input arbitrari? Ho trovato almeno un metodo che almeno si avvicina a quella funzionalità (per ulteriori informazioni, vedere la mia risposta). Spero che questo renda le cose più chiare.
Air
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.