Motivação
Trabalho com conjuntos de dados que contêm informações de identificação pessoal (PII) e às vezes preciso compartilhar parte de um conjunto de dados com terceiros, de uma maneira que não exponha as PII e sujeite meu empregador a responsabilidades. Nossa abordagem usual aqui é reter os dados inteiramente ou, em alguns casos, reduzir sua resolução; por exemplo, substituindo um endereço exato da rua pelo município ou setor censitário correspondente.
Isso significa que certos tipos de análise e processamento devem ser feitos internamente, mesmo quando um terceiro tiver recursos e conhecimentos mais adequados à tarefa. Como os dados de origem não são divulgados, o modo como processamos essa análise e processamento carece de transparência. Como resultado, a capacidade de terceiros de executar controle de qualidade / controle de qualidade, ajustar parâmetros ou fazer refinamentos pode ser muito limitada.
Anonimizando dados confidenciais
Uma tarefa envolve a identificação de indivíduos por seus nomes, nos dados enviados pelo usuário, levando em consideração erros e inconsistências. Um indivíduo particular pode ser gravado em um local como "Dave" e em outro como "David", as entidades comerciais podem ter muitas abreviações diferentes e sempre há alguns erros de digitação. Desenvolvi scripts com base em vários critérios que determinam quando dois registros com nomes não idênticos representam o mesmo indivíduo e atribuem a eles um ID comum.
Nesse ponto, podemos tornar o conjunto de dados anônimo, retendo os nomes e substituindo-os por esse número de identificação pessoal. Mas isso significa que o destinatário quase não tem informações sobre, por exemplo, a força da partida. Preferimos poder transmitir o máximo de informação possível sem divulgar a identidade.
O que não funciona
Por exemplo, seria ótimo poder criptografar seqüências de caracteres, preservando a distância de edição. Dessa forma, terceiros podem fazer parte de seu próprio controle de qualidade / controle de qualidade, ou optar por fazer um processamento adicional por conta própria, sem nunca acessar (ou poderem potencialmente fazer engenharia reversa) as IIP. Talvez combinemos as strings internamente com a distância de edição <= 2, e o destinatário deseja examinar as implicações de aumentar essa tolerância para editar a distância <= 1.
Mas o único método que eu conheço que faz isso é o ROT13 (mais geralmente, qualquer cifra de deslocamento ), que dificilmente conta como criptografia; é como escrever os nomes de cabeça para baixo e dizer: "Promete que não vai virar o papel?"
Outra solução ruim seria abreviar tudo. "Ellen Roberts" se torna "ER" e assim por diante. Essa é uma solução ruim porque, em alguns casos, as iniciais, em associação com dados públicos, revelam a identidade de uma pessoa e, em outros casos, é ambíguo demais; "Benjamin Othello Ames" e "Bank of America" terão as mesmas iniciais, mas seus nomes são diferentes. Portanto, ele não faz nenhuma das coisas que queremos.
Uma alternativa deselegante é a introdução de campos adicionais para rastrear certos atributos do nome, por exemplo:
+-----+----+-------------------+-----------+--------+
| 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 |
+-----+----+-------------------+-----------+--------+
Eu chamo isso de "deselegante" porque requer antecipar quais qualidades podem ser interessantes e é relativamente grossa. Se os nomes forem removidos, não há muito que você possa concluir razoavelmente sobre a força da correspondência entre as linhas 2 e 3 ou sobre a distância entre as linhas 2 e 4 (ou seja, quão próximas elas estão da correspondência).
Conclusão
O objetivo é transformar cadeias de caracteres de maneira que o máximo possível de qualidades úteis da cadeia original seja preservado, enquanto oculta a cadeia original. A descriptografia deve ser impossível, ou tão impraticável que seja efetivamente impossível, independentemente do tamanho do conjunto de dados. Em particular, um método que preserva a distância de edição entre cadeias arbitrárias seria muito útil.
Encontrei alguns documentos que podem ser relevantes, mas estão um pouco exagerados:
No meio da leitura da sua pergunta, percebi que o Levenshtein Distance poderia ser uma boa solução para o seu problema. É bom ver que você tem um link para um artigo sobre o assunto, deixe-me ver se consigo esclarecer como seria uma solução Levenshtein.
A distância de Levenshtein é usada em muitos setores para a resolução de entidades, o que o torna útil é que é uma medida da diferença entre duas seqüências. No caso de comparação de strings, são apenas seqüências de caracteres.
Isso pode ajudar a resolver seu problema, permitindo que você forneça um número que forneça uma medida de quão semelhante é o texto de outro campo.
Aqui está um exemplo de uma maneira básica de usar o Levenshtein com os dados que você forneceu:
Isso fornece uma solução aceitável, a distância de 8 fornece alguma indicação de um relacionamento e é muito compatível com PII. No entanto, ainda não é super útil, vamos ver o que acontece se fizermos alguma mágica em texto para pegar apenas a primeira inicial do primeiro nome e o sobrenome completo, deixando qualquer coisa no meio:
Como você pode ver, a distância de 0 de Levenshtein é bastante indicativa de um relacionamento. Geralmente, os provedores de dados combinam várias permutações de Levenshtein do nome e sobrenome com 1, 2 ou todos os caracteres apenas para dar alguma dimensionalidade à forma como as entidades estão relacionadas, mantendo o anonimato nos dados.
fonte
Se possível, vincularia registros relacionados (por exemplo, Dave, David etc.) e os substituiria por um número de sequência (1,2,3 etc.) ou um hash salgado da string usada para representar todos os registros relacionados ( por exemplo, David em vez de Dave).
Suponho que terceiros não precisam ter nenhuma idéia de qual é o nome verdadeiro; caso contrário, você também pode dar a eles.
editar : você precisa definir e justificar que tipo de operações o terceiro precisa ser capaz de executar. Por exemplo, o que há de errado em usar as iniciais seguidas de um número (por exemplo, BOA-1, BOA-2 etc.) para desambiguar o Bank of America de Benjamin Othello Ames? Se isso é muito revelador, você pode colocar algumas das letras ou nomes; por exemplo, [AE] -> 1, [FJ] -> 2, etc., para que o BOA se torne 1OA, ou ["Bank", "Barry", "Bruce" etc.] -> 1 para que o Bank of America esteja novamente 1OA.
Para mais informações, consulte k-anonimato .
fonte
Uma opção (dependendo do tamanho do conjunto de dados) é fornecer apenas as distâncias de edição (ou outras medidas de similaridade que você está usando) como um conjunto de dados adicional.
Por exemplo:
Embora ainda haja muito a ser feito para anular a descriptografia dos dados.
Por exemplo, se "Tim" é conhecido como o nome mais popular para um garoto, a contagem de IDs com frequência que se aproxima da porcentagem conhecida de Tims na população pode denunciá-lo. A partir daí, você pode procurar nomes com uma distância de edição de 1 e concluir que esses IDs podem se referir a "Tom" ou "Jim" (quando combinados com outras informações).
fonte
Não tenho muita certeza, mas talvez o hash sensível à localidade seja uma boa solução. Faz hash de dados de entrada (no seu caso - nomes), para que as strings originais sejam preservadas. Por outro lado, a idéia principal do LSH é maximizar a probabilidade de hashes para itens semelhantes. Existem muitas implementações diferentes de LSH. Tentei o Nilsimsa-hash para comparar textos de tuítes e funcionou muito bem. Mas não tenho certeza de quão bem ele funcionará no caso de cadeias curtas (nomes) - esse problema requer teste. Eu tentei seus exemplos, e aqui está o resultado (nome A, nome B, "distância" - o máximo é 120):
Como você vê, CHRISTOPH BAUER e CJ BAUER apareceram para ser o par mais próximo. Mas a diferença não é significativa. E apenas por exemplo - representação hash desses nomes:
fonte
Aqui está uma abordagem que não vi mencionada: separe o processo em duas etapas: a primeira etapa focada na codificação de nomes, para que versões alternativas com o mesmo nome sejam codificadas da mesma (ou quase a mesma) e a segunda etapa focada em tornar eles anônimos.
Para a primeira etapa, você pode usar um dos algoritmos fonéticos (Soundex e variantes) , aplicado ao nome, sobrenome e iniciais em várias ordens. (Veja este artigo também). É nesta etapa que você resolve semelhanças versus diferenças de nomes para equilibrar falsos positivos e falsos negativos.
Para a segunda etapa, você pode escolher qualquer método hash ou criptográfico que desejar, sem se preocupar com o modo como esse método afeta a correspondência de nomes. Isso lhe dá liberdade para usar um método que tenha as melhores características para desempenho, robustez e anonimato.
fonte