Word Embeddings e Visualização de Dados com PCA em Python

O avanço do Processamento de Linguagem Natural (PLN) nos últimos anos, impulsionado por modelos como GPT-4 e Claude, fundamenta-se na capacidade das máquinas de interpretar a linguagem humana. O pilar dessa itnerpretação é a transformação de palavras em representações numéricas, processo conhecido como Word Embeddings (incorporação de palavras).

Diferente de métodos simples como o Bag-of-Words ou a codificação One-Hot, os Word Embeddings permitem que algoritmos capturem relações semânticas entre termos de forma autossupervisionada. Isso significa que o sistema aprende que "rei" e "rainha" possuem uma proximidade contextual sem intervenção humana direta.

A Estrutura dos Word Embeddings

A construção de um modelo de incorporação geralmente segue dois estágios principais:

  1. Vetorização Esparsa: Inicialmente, as palavras são convertidas em vetores One-Hot, resultando em uma matriz vasta onde cada palavra é representada por um único bit ligado (1) em uma posição específica.
  2. Aprendizado de Representação Densiva: Através de redes neurais, como o algoritmo Skip-gram, o modelo aprende a prever o contexto de uma palavra-alvo. O resultado é uma matriz de pesos (o embedding) onde cada palavra é representada por um vetor denso, geralmente de 100 a 300 dimensões.

Para lidar com o alto custo computacional de calcular probabilidades em vocabulários imensos, utilizam-se técnicas como Negative Sampling (amostragem negativa) e Hierarchical Softmax. A primeira foca em distinguir a palavra correta de um pequeno conjunto de palavras incorretas, enquanto a segunda utiliza estruturas de árvore para reduzir a complexidade da busca de \(O(V)\) para \(O(\log V)\).

Redução de Dimensionalidade com PCA

Visualizar vetores de 300 dimensões é impossível para seres humanos. Para compreender como o modelo está agrupando as palavras, utilizamos o PCA (Principle Component Analysis). O PCA é um algoritmo de aprendizado não supervisionado que projeta dados de alta dimensão em um espaço menor (como 2D ou 3D), preservando a maior variância possível.

O fluxo lógico do PCA consiste em:

  1. Normalização dos dados (centralização na média).
  2. Cálculo da matriz de covariância.
  3. Decomposição de autovalores e autovetores (ou SVD).
  4. Projeção dos dados originais nos autovetores principais.

Abaixo, uma implementação funcional do PCA utilizando NumPy:

import numpy as np

def reduzir_dimensao_pca(matriz_entrada, dim_saida=2):
    """
    Reduz a dimensionalidade de vetores de palavras.
    """
    # Centralização dos dados
    matriz_centralizada = matriz_entrada - np.mean(matriz_entrada, axis=0)
    
    # Matriz de covariância
    matriz_cov = np.cov(matriz_centralizada, rowvar=False)
    
    # Cálculo de autovalores e autovetores
    autovalores, autovetores = np.linalg.eigh(matriz_cov)
    
    # Ordenação decrescente baseada nos autovalores
    indices_ordenados = np.argsort(autovalores)[::-1]
    autovetores_topo = autovetores[:, indices_ordenados[:dim_saida]]
    
    # Projeção final
    dados_reduzidos = np.dot(matriz_centralizada, autovetores_topo)
    
    return dados_reduzidos

Implementação Prática de Word2Vec

Para aplicar Word Embeddings em cenários reais, utilizamos bibliotecas como Gensim e NLTK. O primeiro passo é o pré-processamento para limpar ruídos como tags HTML e caracteres especiais.

import re
from bs4 import BeautifulSoup
from nltk.corpus import stopwords

def filtrar_sentenca(texto_bruto):
    # Remove HTML
    texto_puro = BeautifulSoup(texto_bruto, "html.parser").get_text()
    # Mantém apenas letras
    letras = re.sub("[^a-zA-Z]", " ", texto_puro)
    # Tokenização e remoção de stopwords
    palavras = letras.lower().split()
    stops = set(stopwords.words("english"))
    return [p for p in palavras if p not in stops]

Após o tratamento dos dados, configuramos e treinamos o modelo Word2Vec. Os parâmetros principais incluem o tamanho do vetor (vector_size), a janela de contexto (window) e a contagem mínima de ocorrências (min_count).

from gensim.models import Word2Vec

# Configurações do modelo
params = {
    "vector_size": 300,
    "min_count": 40,
    "window": 10,
    "workers": 4,
    "sg": 1  # 1 para Skip-gram
}

# Supondo que 'corpus_tokens' seja uma lista de listas de palavras
modelo_w2v = Word2Vec(sentences=corpus_tokens, **params)

# Otimização de memória após o treino
modelo_w2v.init_sims(replace=True)

# Testando similaridade semântica
resultado = modelo_w2v.wv.most_similar("king")
print(resultado)

Ao treinar com um volume de dados robusto, o modelo é capaz de identificar relações complexas. Por exemplo, ao buscar termos próximos a "boy" (garoto), o modelo retornará naturalmente palavras como "girl", "teenager" ou "son", demonstrando que a estrutura matemática do embedding capturou com sucesso o significado contextual das palavras.

Tags: nlp Python Word2Vec PCA machine-learning

Publicado em 10-10 21:26