¿Cómo puedo transformar nombres en un conjunto de datos confidenciales para hacerlos anónimos, pero preservar algunas de las características de los nombres?


42

Motivación

Trabajo con conjuntos de datos que contienen información de identificación personal (PII) y, a veces, necesito compartir parte de un conjunto de datos con terceros, de manera que no exponga la PII y exponga a mi empleador a responsabilidad. Nuestro enfoque habitual aquí es retener datos por completo o, en algunos casos, reducir su resolución; por ejemplo, reemplazando una dirección de calle exacta con el condado o sección censal correspondiente.

Esto significa que ciertos tipos de análisis y procesamiento deben realizarse internamente, incluso cuando un tercero tenga recursos y experiencia más adecuados para la tarea. Dado que los datos de origen no se divulgan, la forma en que hacemos este análisis y procesamiento carece de transparencia. Como resultado, la capacidad de un tercero para realizar QA / QC, ajustar parámetros o realizar mejoras puede ser muy limitada.

Anonimizar datos confidenciales

Una tarea consiste en identificar a las personas por sus nombres, en los datos enviados por el usuario, teniendo en cuenta los errores y las inconsistencias. Un individuo privado puede ser registrado en un lugar como "Dave" y en otro como "David", las entidades comerciales pueden tener muchas abreviaturas diferentes, y siempre hay algunos errores tipográficos. He desarrollado guiones basados ​​en una serie de criterios que determinan cuándo dos registros con nombres no idénticos representan al mismo individuo y les asigna una identificación común.

En este punto, podemos hacer que el conjunto de datos sea anónimo reteniendo los nombres y reemplazándolos con este número de identificación personal. Pero esto significa que el destinatario casi no tiene información sobre, por ejemplo, la fuerza del partido. Preferiríamos poder transmitir la mayor cantidad de información posible sin divulgar la identidad.

Lo que no funciona

Por ejemplo, sería genial poder cifrar cadenas mientras se conserva la distancia de edición. De esta forma, los terceros podrían hacer algunos de sus propios controles de calidad / control de calidad, o elegir realizar un procesamiento adicional por su cuenta, sin tener que acceder (o poder realizar ingeniería inversa) a la PII. Quizás hagamos coincidir las cadenas internamente con la distancia de edición <= 2, y el destinatario quiere ver las implicaciones de ajustar esa tolerancia para editar la distancia <= 1.

Pero el único método con el que estoy familiarizado es ROT13 (más generalmente, cualquier cifrado de turno ), que apenas cuenta como cifrado; es como escribir los nombres al revés y decir: "¿Prometes que no voltearás el papel?"

Otra mala solución sería abreviar todo. "Ellen Roberts" se convierte en "ER" y así sucesivamente. Esta es una solución pobre porque en algunos casos las iniciales, en asociación con datos públicos, revelarán la identidad de una persona, y en otros casos es demasiado ambigua; "Benjamin Othello Ames" y "Bank of America" ​​tendrán las mismas iniciales, pero sus nombres son diferentes. Entonces no hace ninguna de las cosas que queremos.

Una alternativa poco elegante es introducir campos adicionales para rastrear ciertos atributos del nombre, por ejemplo:

+-----+----+-------------------+-----------+--------+
| 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    |
+-----+----+-------------------+-----------+--------+

Llamo a esto "poco elegante" porque requiere anticipar qué cualidades pueden ser interesantes y es relativamente burdo. Si se eliminan los nombres, no hay mucho que pueda concluir razonablemente sobre la fuerza de la coincidencia entre las filas 2 y 3, o sobre la distancia entre las filas 2 y 4 (es decir, qué tan cerca están de la coincidencia).

Conclusión

El objetivo es transformar las cadenas de tal manera que se conserven tantas cualidades útiles de la cadena original como sea posible mientras se oculta la cadena original. El descifrado debería ser imposible, o tan poco práctico como para ser efectivamente imposible, sin importar el tamaño del conjunto de datos. En particular, un método que preserva la distancia de edición entre cadenas arbitrarias sería muy útil.

Encontré un par de artículos que podrían ser relevantes, pero están un poco pasados ​​por alto:

Respuestas:


19

Una de las referencias que mencioné en el OP me llevó a una solución potencial que parece bastante poderosa, descrita en "Enlace de registro de preservación de la privacidad utilizando filtros Bloom" ( doi: 10.1186 / 1472-6947-9-41 ):

Se ha desarrollado un nuevo protocolo para la vinculación de registros que preserva la privacidad con identificadores cifrados que permiten errores en los identificadores. El protocolo se basa en filtros Bloom en q-gramos de identificadores.

El artículo entra en detalles sobre el método, que resumiré aquí lo mejor que pueda.

Un filtro Bloom es una serie de bits de longitud fija que almacena los resultados de un conjunto fijo de funciones hash independientes, cada una calculada con el mismo valor de entrada. La salida de cada función hash debe ser un valor de índice entre los posibles índices en el filtro; es decir, si tiene una serie de 10 bits indexada a 0, las funciones hash deben devolver (o correlacionarse) con valores de 0 a 9.

El filtro comienza con cada bit establecido en 0. Después de seleccionar el valor de entrada con cada función del conjunto de funciones hash, cada bit correspondiente a un valor de índice devuelto por cualquier función hash se establece en 1. Si más devuelve el mismo índice que una función hash, el bit en ese índice solo se establece una vez. Podría considerar que el filtro Bloom es una superposición del conjunto de hashes en el rango fijo de bits.

El protocolo descrito en el artículo vinculado anteriormente divide las cadenas en n-gramos, que en este caso son conjuntos de caracteres. Como ejemplo, "hello"podría producir el siguiente conjunto de 2 gramos:

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

Rellenar el frente y la espalda con espacios parece ser generalmente opcional al construir n-gramos; Los ejemplos dados en el documento que propone este método utilizan dicho relleno.

Cada n-gramo se puede dividir en hash para producir un filtro Bloom, y este conjunto de filtros Bloom se puede superponer sobre sí mismo (operación OR a nivel de bits) para producir el filtro Bloom para la cadena.

Si el filtro contiene muchos más bits que las funciones hash o n-gramos, es poco probable que las cadenas arbitrarias produzcan exactamente el mismo filtro. Sin embargo, cuanto más n-gramas tengan dos cadenas en común, más bits compartirán finalmente sus filtros. Luego puede comparar cualquiera de los dos filtros A, Bpor medio de su coeficiente de dados:

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

Donde hes el número de bits que se establece en 1 en ambos filtros, aes el número de bits establecido en 1 en solo el filtro A, y bes el número de bits establecido en 1 en solo el filtro B. Si las cadenas son exactamente iguales, el coeficiente de dados será 1; cuanto más difieran, más cerca estará el coeficiente 0.

Debido a que las funciones hash están asignando un número indeterminado de entradas únicas a un pequeño número de posibles índices de bits, diferentes entradas pueden producir el mismo filtro, por lo que el coeficiente indica solo una probabilidad de que las cadenas sean iguales o similares. El número de funciones hash diferentes y el número de bits en el filtro son parámetros importantes para determinar la probabilidad de falsos positivos: pares de entradas que son mucho menos similares a lo que predice el coeficiente de dados producido por este método.

Este tutorial me pareció muy útil para comprender el filtro Bloom.

Hay cierta flexibilidad en la implementación de este método; Consulte también este documento de 2010 (también vinculado al final de la pregunta) para obtener algunas indicaciones de su rendimiento en relación con otros métodos y con diversos parámetros.


Marcar esto como la respuesta aceptada porque fuera de los enfoques sugeridos, es el más prometedor para mi caso de uso particular.
Aire

Gracias por todos estos detalles y antecedentes. ¿Encontró alguna implementación (por ejemplo, en Python) de este enfoque?
amball

@amball no tengo.
Aire

8

A la mitad de la lectura de su pregunta, me di cuenta de que Levenshtein Distance podría ser una buena solución a su problema. Es bueno ver que tienes un enlace a un documento sobre el tema, déjame ver si puedo arrojar algo de luz sobre cómo sería una solución de Levenshtein.

La distancia de Levenshtein se usa en muchas industrias para la resolución de entidades, lo que la hace útil es que es una medida de la diferencia entre dos secuencias. En el caso de la comparación de cadenas, son solo secuencias de caracteres.

Esto podría ayudar a resolver su problema al permitirle proporcionar un número que proporcione una medida de cuán similar es el texto de otro campo.

Aquí hay un ejemplo de una forma básica de usar Levenshtein con los datos que proporcionó:

ingrese la descripción de la imagen aquí

Esto proporciona una solución correcta, la distancia de 8 proporciona alguna indicación de una relación y es muy compatible con PII. Sin embargo, todavía no es súper útil, veamos qué sucede si hacemos algo de magia de texto para tomar solo la primera inicial del primer nombre y el apellido completo dejando algo en el medio:

ingrese la descripción de la imagen aquí

Como puede ver, la distancia de 0 de Levenshtein es bastante indicativa de una relación. Comúnmente, los proveedores de datos combinarán un montón de permutaciones de Levenshtein del nombre y apellido con 1, 2 o todos los caracteres solo para dar cierta dimensionalidad en cuanto a cómo se relacionan las entidades mientras se mantiene el anonimato dentro de los datos.


1
Lo que me interesa del artículo que vinculé es que dice mostrar un método para realizar este tipo de cálculo sin el conocimiento de ambas cadenas de entrada . En el documento, cada actor tiene conocimiento de una cadena, lo que no es útil para mis propósitos; Necesitaría un actor para poder realizar el cálculo sin conocer ninguna de las cadenas. Calcularlos de antemano solo es factible para conjuntos de datos muy pequeños o productos muy limitados; un producto cruzado completo de distancias enteras en mi conjunto de datos tomaría ~ 10 PB de almacenamiento.
Aire

Es por eso que mencioné la idea de un cifrado de sustitución (ROT13), ya que conserva la distancia entre las cadenas; pero no es seguro, y sospecho que puede ser imposible cifrar de forma segura las cadenas mientras se conserva la distancia de edición. (Encantaría estar equivocado!)
Aire

Correcto, simplemente filtraría la matriz para incluir solo Levenshteins debajo de un cierto límite, por lo que solo está poblando donde hay una alta probabilidad de superposición. Además, cuando se trata de PII, considero que si incluye suficiente información para determinar una relación entre entidades dispares en sus conjuntos de datos, es muy poco probable que esté preservando el anonimato de los clientes. El objetivo de anonimizar los datos es evitar posibles dolores de cabeza regulatorios relacionados con la PII en esa línea (los estándares siempre se pueden ajustar), por lo que personalmente no me arriesgaría.
neone4373

7

Si es posible, vincularía los registros relacionados (por ejemplo, Dave, David, etc.) y los reemplazaría con un número de secuencia (1,2,3, etc.) o un hash salado de la cadena que se utiliza para representar todos los registros relacionados ( por ejemplo, David en lugar de Dave).

Supongo que los terceros no necesitan tener idea de cuál es el nombre real, de lo contrario, también podría dárselos.

editar : debe definir y justificar qué tipo de operaciones debe realizar el tercero. Por ejemplo, ¿qué tiene de malo el uso de iniciales seguidas de un número (por ejemplo, BOA-1, BOA-2, etc.) para desambiguar a Bank of America de Benjamin Othello Ames? Si eso es demasiado revelador, puede agrupar algunas de las letras o nombres; por ejemplo, [AE] -> 1, [FJ] -> 2, etc. para que BOA se convierta en 1OA, o ["Bank", "Barry", "Bruce", etc.] -> 1 para que Bank of America vuelva a estar 1OA.

Para obtener más información, consulte k-anonimato .


Aprecio la referencia de k-anonimato y la sugerencia de bin, eso me da algunas cosas nuevas en las que pensar.
Aire

6

Una opción (dependiendo del tamaño de su conjunto de datos) es simplemente proporcionar distancias de edición (u otras medidas de similitud que esté usando) como un conjunto de datos adicional.

P.ej:

  1. Generar un conjunto de nombres únicos en el conjunto de datos.
  2. Para cada nombre, calcule la distancia de edición entre sí.
  3. Generar una identificación o hash irreversible para cada nombre
  4. Reemplace los nombres en el conjunto de datos original con esta ID
  5. Proporcione una matriz de distancias de edición entre números de identificación como nuevo conjunto de datos

Aunque todavía hay mucho por hacer para desanonimizar los datos de estos incluso.

Por ejemplo, si se sabe que "Tim" es el nombre más popular para un niño, el recuento de frecuencia de identificaciones que coinciden estrechamente con el porcentaje conocido de Tims en la población podría revelarlo. A partir de ahí, puede buscar nombres con una distancia de edición de 1 y concluir que esas ID pueden referirse a "Tom" o "Jim" (cuando se combinan con otra información).


5

No estoy muy seguro, pero tal vez el hashing sensible a la localidad sea una buena solución. Hace hashing de datos de entrada (en su caso, nombres), por lo que se conservarán las cadenas originales. Por otro lado, la idea principal de LSH es maximizar la probabilidad de hash para artículos similares. Hay muchas implementaciones LSH diferentes. Intenté Nilsimsa-hash para comparar textos de tweets, y funcionó bastante bien. Pero no estoy seguro de qué tan bien funcionará en caso de cadenas cortas (nombres): este problema requiere prueba. Intenté sus ejemplos, y aquí está el resultado (nombre A, nombre B, "distancia" - el máximo es 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

Como puede ver, CHRISTOPH BAUER y CJ BAUER resultaron ser el par más cercano. Pero la diferencia no es significativa. Y solo por ejemplo: representación hash de estos nombres:

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

3

Aquí hay un enfoque que no vi mencionado: separe el proceso en dos pasos: el primer paso se centró en codificar nombres para que las versiones alternativas del mismo nombre se codifiquen de la misma manera (o casi lo mismo), y el segundo paso se centró en hacer ellos anónimos.

Para el primer paso, puede usar uno de los Algoritmos fonéticos (Soundex y variantes) , aplicado al nombre, apellido e iniciales en varios órdenes. (Ver este artículo , también). Es en este paso donde resuelve similitudes versus diferencias en los nombres para equilibrar los falsos positivos de los falsos negativos.

Para el segundo paso, puede elegir cualquier método hash o criptográfico que desee, sin preocuparse de cómo ese método afecta la coincidencia de nombres. Esto le da la libertad de usar un método que tenga las mejores características para el rendimiento, la solidez y el anonimato.


No creo que esta sugerencia aborde el problema tal como se presenta en la pregunta. ¿Dónde está la flexibilidad posterior al cifrado? ¿Cómo refino su análisis sin acceso a los datos originales?
Aire

@AirThomas Lo siento pero no entiendo tus dos preguntas. ¿Qué quiere decir con "flexibilidad posterior al cifrado"? No vi nada en tu pregunta / descripción como esa. ¿Qué quiere decir con "refinar su análisis sin acceso a los datos originales"? No vi nada sobre "refinar".
MrMeritology

1
Traté de identificar el problema en el segundo párrafo de la sección Motivación . Imagine, por ejemplo, que desea publicar su conjunto de datos a varios investigadores que desean realizar algunos modelos. Hay muchas metodologías inteligentes y efectivas que podrían aplicarse, y cada investigador trabaja de manera un poco diferente. No puede revelar los nombres de personas privadas en su conjunto de datos. Si realiza esa parte del análisis antes de publicar los datos, obliga a todos a elegir la metodología.
Aire

Si además proporciona hashes de los nombres, el beneficio es que los terceros pueden distinguir la identidad exacta, pero no más. Entonces, la pregunta es, ¿cómo podría proporcionar más información sobre los datos que no puede divulgar? Por ejemplo, ¿hay algún método que conserve en la salida de cifrado / hashing la distancia de edición entre entradas arbitrarias? He encontrado al menos un método que al menos se aproxima a esa funcionalidad (para obtener más información, consulte mi propia respuesta). Espero que eso aclare las cosas.
Aire
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.