Por que as teorias de Wittgenstein continuam sendo a base de toda a PNL modernaA representação vetorial das palavras é talvez uma das idéias mais bonitas e românticas da história da inteligência artificial. A filosofia da linguagem é um ramo da filosofia que explora a relação entre linguagem e realidade e como tornar a fala significativa e compreensível. Uma representação vetorial de palavras é um método muito específico no moderno Natural Language Processing (NLP). Em certo sentido, é uma evidência empírica das teorias de Ludwig Wittgenstein, um dos filósofos mais relevantes do século passado. Para Wittgenstein, o uso de palavras é uma jogada em um
jogo de linguagem social jogado por membros da comunidade que se entendem. O significado de uma palavra depende apenas de sua utilidade em um contexto; não corresponde um a um com um objeto do mundo real.
Para uma grande classe de casos em que usamos a palavra "significado", ela pode ser definida como o significado da palavra é o seu uso no idioma .
Obviamente, é muito difícil entender o significado exato de uma palavra. Há muitos aspectos a serem considerados:
- a qual objeto a palavra pode se referir;
- que parte do discurso é essa;
- se é uma expressão idiomática;
- todos os tons de significados;
- e assim por diante.
Todos esses aspectos, no final, se resumem a uma coisa: saber usar a palavra.
O conceito de
significado e por que um conjunto ordenado de caracteres tem uma conotação definida na linguagem não é apenas uma questão filosófica, mas provavelmente o maior problema com o qual os especialistas em IA que trabalham com a PNL precisam lidar. É bastante óbvio para uma pessoa de língua russa que um "cachorro" é um "animal", e parece mais um "gato" do que um "golfinho", mas essa tarefa está longe de ser simples para uma solução sistemática.
Tendo corrigido ligeiramente as teorias de Wittgenstein, podemos dizer que os cães se parecem com gatos porque geralmente aparecem nos mesmos contextos: você provavelmente pode encontrar cães e gatos associados às palavras "casa" e "jardim" do que às palavras "mar" e o "oceano". É essa intuição subjacente ao
Word2Vec , uma das implementações mais famosas e bem-sucedidas da representação vetorial de palavras. Hoje, as máquinas estão longe de uma
compreensão real
de textos e passagens longas, mas a representação vetorial das palavras é sem dúvida o único método que nos permitiu dar o maior passo nessa direção na última década.
Do BoW ao Word2Vec
Em muitos problemas do computador, o primeiro problema é apresentar os dados em forma numérica; palavras e frases são provavelmente as mais difíceis de imaginar nesta forma. Em nossa configuração, as palavras
D são selecionadas no dicionário e cada palavra pode receber um índice numérico
i .
Por muitas décadas, uma abordagem clássica foi adotada para representar cada palavra como um vetor numérico D-dimensional de todos os zeros, exceto um na posição i. Como exemplo, considere um dicionário de três palavras: "cachorro", "gato" e "golfinho" (D = 3). Cada palavra pode ser representada como um vetor tridimensional: "cachorro" corresponde a [1,0,0], "gato" a [0,1,0] e "golfinho", obviamente, [0,0,1]. O documento pode ser representado como um vetor D-dimensional, em que cada elemento conta as ocorrências da i-ésima palavra no documento. Esse modelo é chamado Bag-of-words (BoW) e é usado há décadas.
Apesar de seu sucesso nos anos 90, a BoW não possuía a única função interessante das palavras: seu significado. Sabemos que duas palavras muito diferentes podem ter significados semelhantes, mesmo que sejam completamente diferentes do ponto de vista da ortografia. “Gato” e “cachorro” são animais domésticos, “rei” e “rainha” estão próximos um do outro, “maçã” e “cigarro” não têm relação alguma.
Sabemos disso, mas no modelo BoW, todas essas palavras estão à mesma distância no espaço vetorial: 1.
O mesmo problema se aplica aos documentos: usando o BoW, podemos concluir que os documentos são semelhantes apenas se contiverem a mesma palavra um certo número de vezes. E aqui vem o Word2Vec, introduzindo nos termos do aprendizado de máquina muitas questões filosóficas que Wittgenstein discutiu em seus
Estudos Filosóficos há 60 anos.
Em um dicionário de tamanho D, onde a palavra é identificada por seu índice, o objetivo é calcular a representação vetorial N-dimensional de cada palavra para N << D. Idealmente, queremos que seja um vetor denso representando alguns aspectos semanticamente específicos do significado. Por exemplo, idealmente queremos que "cachorro" e "gato" tenham representações semelhantes, e "maçã" e "cigarro" estejam muito distantes no espaço vetorial.
Queremos realizar algumas operações algébricas básicas em vetores, como
+−=
. Quero que a distância entre os vetores "ator" e "atriz" coincida substancialmente com a distância entre o "príncipe" e a "princesa". Embora esses resultados sejam bastante utópicos, experimentos mostram que os vetores do Word2Vec exibem propriedades muito próximas delas.
O Word2Vec não aprende diretamente as visualizações com isso, mas as recebe como subproduto da classificação sem um professor. O conjunto médio de dados de corpus de palavras da PNL consiste em um conjunto de frases; cada palavra em uma frase aparece no contexto das palavras ao redor. O objetivo do classificador é prever a palavra de destino, considerando as palavras contextuais como entrada. Para a frase “cachorro marrom brinca no jardim”, as palavras [marrom, brinca, no jardim] são fornecidas ao modelo como entrada, e ela deve prever a palavra “cachorro”. Essa tarefa é considerada como aprendizado sem professor, pois o corpus não precisa ser marcado com uma fonte externa de verdade: com um conjunto de frases, você sempre pode criar exemplos positivos e negativos automaticamente. Olhando para “cachorro marrom brincando no jardim” como um exemplo positivo, podemos criar muitos padrões negativos, como “avião marrom brincando no jardim” ou “uva marrom brincando no jardim”, substituindo a palavra-alvo “cachorro” por palavras aleatórias do conjunto de dados.
E agora a aplicação das teorias de Wittgenstein é perfeitamente clara: o contexto é crucial para a representação vetorial das palavras, pois é importante atribuir significado à palavra em suas teorias. Se duas palavras tiverem significados semelhantes, elas terão representações semelhantes (uma pequena distância no espaço N-dimensional) apenas porque elas geralmente aparecem em contextos semelhantes. Assim, o "gato" e o "cachorro" acabarão tendo vetores próximos porque geralmente aparecem nos mesmos contextos: é útil que o modelo use representações vetoriais semelhantes para eles, porque é a coisa mais conveniente que ela pode fazer, para obter melhores resultados na previsão de duas palavras com base em seus contextos.
O artigo original oferece duas arquiteturas diferentes: CBOW e Skip-gram. Nos dois casos, as representações verbais são ensinadas juntamente com uma tarefa de classificação específica, fornecendo as melhores representações vetoriais possíveis de palavras que maximizam o desempenho do modelo.
Figura 1. Comparação das arquiteturas CBOW e Skip-gramCBOW é a sigla para Continuous Bag of Words, e sua tarefa é adivinhar uma palavra com o contexto em mente como entrada. As entradas e saídas são representadas como vetores D-dimensionais projetados em um espaço N-dimensional com pesos comuns. Estamos apenas procurando pesos de projeção. De fato, a representação vetorial das palavras é matrizes D × N, em que cada linha representa uma palavra do dicionário. Todas as palavras de contexto são projetadas em uma posição e suas representações vetoriais são calculadas como média; portanto, a ordem das palavras não afeta o resultado.
O pulo-grama faz a mesma coisa, mas vice-versa: tenta prever as palavras de contexto
C , tomando a palavra-alvo como entrada. A tarefa de prever várias palavras contextuais pode ser reformulada em um conjunto de problemas independentes de classificação binária, e agora o objetivo é prever a presença (ou ausência) de palavras contextuais.
Como regra geral, o Skip-gram exige mais tempo para treinamento e geralmente oferece resultados um pouco melhores, mas, como de costume, aplicativos diferentes têm requisitos diferentes, e é difícil prever com antecedência quais mostrarão o melhor resultado. Apesar da simplicidade do conceito, aprender esse tipo de arquitetura é um verdadeiro pesadelo devido à quantidade de dados e à capacidade de processamento necessária para otimizar pesos. Felizmente, na Internet, você pode encontrar algumas representações vetoriais de palavras pré-treinadas e estudar o espaço vetorial - o mais interessante - com apenas algumas linhas de código Python.
Possíveis melhorias: GloVe e fastText
Sobre o Word2Vec clássico nos últimos anos, muitas melhorias possíveis foram propostas. Os dois mais interessantes e mais usados são o GloVe (Stanford University) e o fastText (desenvolvido pelo Facebook). Eles estão tentando identificar e superar as limitações do algoritmo original.
Em um
artigo científico original , os autores do GloVe enfatizam que o treinamento de modelos em um contexto local separado faz pouco uso das estatísticas globais dos corpus. O primeiro passo para superar essa limitação é criar uma matriz global
X , onde cada elemento
i, j conta o número de referências à palavra
j no contexto da palavra
i . A segunda ideia importante deste documento é o entendimento de que apenas as probabilidades não são suficientes para a previsão confiável de valores, e também é necessária uma matriz de coocorrência, da qual certos aspectos dos valores podem ser extraídos diretamente.
Considere duas palavras iej que são de particular interesse. Por concretude, suponha que estamos interessados no conceito de um estado termodinâmico, para o qual podemos tomar j =
i =
e j =
. A relação dessas palavras pode ser investigada estudando a razão de suas probabilidades de ocorrência conjunta usando diferentes palavras sonoras, k. Para palavras k relacionadas ao gelo, mas não ao vapor, digamos k =
[sólido, estado da matéria], esperamos que a relação Pik / Pjk seja maior. Da mesma forma, para as palavras k associadas ao vapor, mas não ao gelo, digamos k =
, a proporção deve ser pequena. Para palavras como "água" ou "moda", que são igualmente relacionadas ao gelo e ao vapor, ou não têm relação com elas, essa proporção deve estar próxima da unidade.
Essa razão de probabilidades se torna o ponto de partida para o estudo da representação vetorial de palavras. Queremos poder calcular vetores que, em combinação com uma função específica
F, mantêm essa proporção constante no espaço de representação vetorial.
Figura 2. A fórmula mais comum para a representação vetorial de palavras no modelo GloVeA função F e a dependência da palavra k podem ser simplificadas substituindo as exponenciais e as compensações fixas, o que fornece a função de minimizar erros pelo método dos mínimos quadrados
J :
Figura 3. A função final de calcular a representação vetorial de palavras no modelo GloVeA função
f é uma função de contagem que tenta não sobrecarregar correspondências muito frequentes e raras, enquanto
bi e
bj são deslocamentos para restaurar a simetria da função. Nos últimos parágrafos do artigo, é mostrado que o treinamento deste modelo no final não é muito diferente do treinamento do modelo clássico de Skip-gram, embora em testes empíricos o GloVe seja superior às duas implementações do Word2Vec.
Por outro lado, o
fastText corrige uma desvantagem completamente diferente do Word2Vec: se o treinamento do modelo começar com a codificação direta de um vetor D-dimensional, a estrutura interna das palavras será ignorada. Em vez de codificar diretamente a codificação de palavras aprendendo representações verbais, o fastText oferece o estudo de N-gramas de caracteres e representa as palavras como a soma dos vetores de N-grama. Por exemplo, com N = 3, a palavra "flor" é codificada como 6 gramas diferentes [<fl, flo, low, Debt, wer, er>] mais uma sequência especial <flower>. Observe como colchetes angulares são usados para indicar o início e o fim de uma palavra. Assim, uma palavra é representada por seu índice no dicionário de palavras e o conjunto de N-gramas que ela contém, mapeado para números inteiros usando a função hash. Esse aprimoramento simples permite dividir representações de grama N entre palavras e calcular representações vetoriais de palavras que não estavam no caso de aprendizado.
Experiências e possíveis aplicações
Como já dissemos, para
usar essas representações vetoriais, você precisa de apenas algumas linhas de código Python.
Conduzi várias experiências com o
modelo GloVe de 50 dimensões , treinado em 6 bilhões de palavras das frases da Wikipedia, bem como com o
modelo fastText de 300 dimensões, treinado no Common Crawl (que forneceu 600 bilhões de tokens). Esta seção fornece links para os resultados de ambos os experimentos apenas para provar os conceitos e fornecer uma compreensão geral do tópico.
Antes de tudo, eu queria verificar algumas semelhanças básicas de palavras, a característica mais simples, mas importante, de sua representação vetorial. Como esperado, as palavras mais semelhantes às palavras “cachorro” foram “gato” (0,92), “cães” (0,85), “cavalo” (0,79), “cachorro” (0,78) e “animal de estimação” (0,77). Observe que a forma plural tem quase o mesmo significado que o singular. Novamente, é bastante trivial dizermos isso, mas para um carro não é completamente um fato. Agora comida: as palavras mais semelhantes para "pizza" são "sanduíche" (0,87), "sanduíches" (0,86), "lanche" (0,81), "assados" (0,79), "batatas fritas" (0,79) e "hambúrgueres" ( 0,78). Faz sentido, os resultados são satisfatórios e o modelo se comporta muito bem.
A próxima etapa é executar alguns cálculos básicos no espaço vetorial e verificar se o modelo adquiriu corretamente algumas propriedades importantes. De fato, como resultado do cálculo dos vetores
+-
, o resultado é "atriz" (0,94), e como resultado do cálculo do
+-
, a palavra "rei" (0,86) é obtida. De um modo geral, se o valor é
a:b=c:d
, a palavra
d deve ser obtida como
d=b-a+c
. Passando para o próximo nível, é impossível imaginar como essas operações vetoriais descrevem aspectos geográficos: sabemos que Roma é a capital da Itália, já que Berlim é a capital da Alemanha, de fato
+-= (0.88)
e
+-= (0.83)
.
E agora a parte divertida. Seguindo a mesma ideia, tentaremos adicionar e subtrair conceitos. Por exemplo, qual é o equivalente americano de pizza para italianos?
+-= (0.60)
, depois
(0.59)
. Desde que me mudei para a Holanda, sempre digo que este país é uma mistura de três coisas: um pouco de capitalismo americano, frio sueco e qualidade de vida e, finalmente, uma pitada de
abundância napolitana. Ao mudar levemente o teorema inicial, removendo um pouco da precisão suíça, obtemos a Holanda (0,68) como resultado dos
++-
: bastante impressionante, para ser honesto.
Figura 4. Para todos os leitores holandeses: tome isso como um elogio, ok?Bons recursos práticos podem ser encontrados
aqui e
aqui para usar essas representações vetoriais pré-treinadas.
Gensim é uma biblioteca Python simples e completa com algumas funções algébricas e de similaridade prontas para uso. Essas representações vetoriais pré-treinadas podem ser usadas de várias maneiras (e úteis), por exemplo, para melhorar o desempenho de analisadores de humor ou modelos de linguagem. Qualquer que seja a tarefa, o uso de vetores N-dimensionais melhorará significativamente a eficiência do modelo em comparação à codificação direta. Obviamente, o treinamento em representações vetoriais em uma área específica melhorará ainda mais o resultado, mas isso pode exigir, talvez, esforço e tempo excessivos.