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.
fonte
Respostas:
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 .J Y C K, D T , T∼ TH
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/
fonte
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
se tornaria
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.
fonte
Eu usaria alguma normalização como pré-processamento, como:
Jr
convertido emJunior
.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.
fonte