Correspondência difusa de nome e apelido

8

Eu tenho um conjunto de dados com a seguinte estrutura:

full_name,nickname,match Christian Douglas,Chris,1, Jhon Stevens,Charlie,0, David Jr Simpson,Junior,1 Anastasia Williams,Stacie,1 Lara Williams,Ana,0 John Williams,Willy,1

onde cada linha do preditor é um nome completo do par, apelido e a variável de destino, corresponde, que é 1 quando o apelido corresponde à pessoa com esse nome e 0 caso contrário. Como você pode ver, a maneira como o apelido é obtido do nome completo não segue um padrão específico.

Quero treinar um algoritmo de ML que, dado o nome completo do par, apelido, preveja a probabilidade de correspondência.

Minha linha de base está apenas tentando ver o número de personagens que correspondem e recursos como esse. No entanto, estou pensando em uma abordagem de PNL usando aprendizado profundo. Minha pergunta é se existem arquiteturas de redes neurais específicas desse problema.

David Masip
fonte
11
Como existem amostras de homens para treinamento?
Shamit Verma
Cerca de 100k, mas apenas 17% têm correspondência = 0
David Masip
É um conjunto de dados aberto para o qual você pode compartilhar um link?
Adarsh ​​Chavakula 22/03/19
como encontrar um relacionamento entre um nome e um apelido quando não há nenhum, por exemplo "Anastasia Williams | Stacie" .. você precisa de mais recursos para fazer esse trabalho, eu acho.
Iamklaus

Respostas:

3

Eu tive um problema semelhante no meu último emprego. Minha solução foi criar recursos via (transformação (s) + comparação) * muitos combos e feed de modelos, depois agregar e modelar, ou seja, modelo de 2 camadas. A chave é a pontuação de codificação e semelhança como recursos.

Transformações: remova vogais (ótimas para determinadas raízes), remova vogais finais, remove caracteres duplos, converte em string fonética (IPA, soundex, https://pypi.org/project/Fuzzy/ ), substitua caracteres que pareçam semelhantes ou tenham sons diferentes em outros idiomas ( na Europa Oriental soa como nos EUA, pode parecer com , etc), ... A estratégia é lidar com muita estranheza / irregularidade nos nomes das pessoas .JYCK,D T,TTH

Comparações (similaridade e diferença): tente [nível de caractere, bloco / raiz / nível de correção [pré / suf], nível de palavra (pode não se aplicar a você)]] pontuações de similaridade e diferença. Tente o coeficiente de dados, Levenshtein, Needleman – Wunsch, Substrato comum (não) contíguo mais longo, semelhança com histograma de caracteres, # correspondência de caracteres, sem correspondência (cada esquerda e direita) etc. Você pode tentar usar um RNN / LSTM e aprender a similaridade para cada transformação. Use a saída do (s) modelo (s) treinado (s) como outro recurso.

Experimente diferentes combinações acima e selecione algumas que parecem ter valor. Você pode simplesmente pegar todas as pontuações e ajustar-se à Regressão Logística (ou Rede Neural) ou criar modelos estatísticos e classificar a porcentagem de saída com base em um pequeno conjunto de treinamento para normalizá-la. Outra maneira de pré-processar as pontuações brutas é usar a codificação de calibração via função logística. Em seguida, adicione estatísticas resumidas das pontuações normalizadas como recursos adicionais. Empurre tudo isso para o modelo final.

Você lidará com nomes derivados de nomes árabes, espanhóis, franceses etc.? Isso é apenas um extra, mas considere fazer o download dos dados de estatísticas de nomes do Seguro Social e do Censo dos EUA para aprimorar seu projeto com mais variações de nome. Vou deixar o como, mas ajuda a saber sobre as possibilidades prováveis. Esteja ciente de que o simples uso de Levenshtein não funciona tão bem com William-> Bill, Dianne-> Di, Larry-> Lawrence, Mohammed-> Muhamed e Hamed, Danielle-> Daniela, Thomas-> Tom e Jimmy-> James . A estratégia que mencionei deve ajudá-lo com toda a variação.

Recursos adicionais a serem explorados: https://github.com/jamesturk/jellyfish https://nameberry.com/list/276/If-You-Like-Danielle-You-Might-Love https://pypi.org/project /fonética/

ldmtwo
fonte
2

Não encontrei nenhuma literatura útil disponível para usar o aprendizado profundo para esse problema específico. A maioria dos métodos parece depender de métodos que não sejam de aprendizado de máquina, como semelhanças de cordas e distâncias de Levenstein. Uma abordagem razoável baseada em aprendizado profundo para esse problema seria uma rede neural recorrente . Um LSTM (memória de longo prazo) ou GRU (Gated Recurrent Unit) seria o ideal. A idéia é ter uma RNN que tenha um estado interno e respeite a ordem em que as entradas são alimentadas.

Diferentemente da classificação de texto, análise de sentimentos ou geração de sequência, a codificação preferida para o texto aqui seria no nível de caracteres, em vez de no nível de palavras .

Por exemplo

Christian Douglas,Chris,1
Jhon Stevens,Charlie,0

se tornaria

[C,h,r,i,s,t,i,a,n, ,D,o,u,g,l,a,s, ,C,h,r,i,s] --> [1]
[J,h,o,n, ,S,t,e,v,e,n,s, ,C,h,a,r,l,i,e]       --> [0]

As duas seqüências a serem correspondidas são concatenadas em uma única sequência. A intuição aqui é que a RNN processaria a sequência caractere por caractere e aprenderia (ler pesos de atualização) que os caracteres no final têm um padrão semelhante ao que foi visto anteriormente na mesma sequência para deduzir que deveria ser 1 em vez de 0

O vetor de [1/0] é a variável de destino.

As etapas padrão de pré-processamento da RNN se aplicam como de costume - preencheremos as seqüências no início para que elas tenham o mesmo comprimento (por exemplo, 50), os caracteres sejam codificados como numéricos em vez de string, etc.

Como o dicionário aqui é bem pequeno (26 alfabetos + espaço + teclado), a arquitetura de rede pode ser bastante simples. Uma única camada de incorporação + camada recorrente deve ser suficiente.

Enquadrar o problema dessa maneira nos permite usar um RNN de baunilha ou um LSTM / GRU pronto para uso em vez de criar uma arquitetura personalizada que usa duas cadeias de caracteres separadas como entrada para cada ponto de dados e lança um número.

Você pode testar essa abordagem e ver se é capaz de superar satisfatoriamente os modelos de linha de base.

Uma boa leitura para RNNs de nível de personagem é o blog e o código de Andrej Karpathy . O problema que ele está tentando resolver é diferente e o código está completamente numpy, mas ainda assim captura bem a ideia.

Adarsh ​​Chavakula
fonte
1

Eu usaria alguma normalização como pré-processamento, como:

  • Jrconvertido em Junior.
  • Converta o nome em Soundex como disse ldmtwo

E, em seguida, use algoritmos de string em vez de ML para isso, como o algoritmo Z, o algoritmo KMP ou a distância de Levenshtein e, em seguida, use o limite na pontuação.

rilut
fonte