1. O JavaScript é necessário para o funcionamento completo desta página.

Por John Paul Mueller, Luca Mueller

A análise de sentimentos deriva computacionalmente de um texto escrito usando a atitude do escritor (positiva, negativa ou neutra) em relação ao tópico do texto. Esse tipo de análise se mostra útil para as pessoas que trabalham em marketing e comunicação porque as ajuda a entender o que os clientes e os consumidores pensam de um produto ou serviço e, assim, agem adequadamente (por exemplo, tentando recuperar clientes insatisfeitos ou decidindo usar uma estratégia de vendas diferente). ) Todos realizam análises de sentimentos. Por exemplo, ao ler o texto, as pessoas naturalmente tentam determinar o sentimento que moveu a pessoa que o escreveu. No entanto, quando o número de textos para ler e entender é muito grande e o texto acumula constantemente, como nas mídias sociais e nos e-mails dos clientes, é importante automatizar a análise de sentimentos.

Análise de sentimentos de IA

O próximo exemplo é uma execução de teste de RNNs usando Keras e TensorFlow que cria um algoritmo de análise de sentimentos capaz de classificar as atitudes expressas em uma crítica de cinema. Os dados são uma amostra do conjunto de dados da IMDb que contém 50.000 críticas (divididas ao meio entre conjuntos de trens e testes) de filmes acompanhadas por um rótulo que expressa o sentimento da crítica (0 = negativo, 1 = positivo). O IMDb é um grande banco de dados online que contém informações sobre filmes, séries de TV e videogames. Originalmente mantido por uma base de fãs, agora é administrado por uma subsidiária da Amazon. No IMDb, as pessoas encontram as informações de que precisam sobre seu programa favorito, além de postar seus comentários ou escrever uma crítica para outros visitantes lerem.

Keras oferece um pacote para download de dados da IMDb. Você prepara, embaralha e organiza esses dados em um trem e um conjunto de testes. Em particular, os dados textuais da IMDb oferecidos por Keras são limpos de pontuação, normalizados em minúsculas e transformados em valores numéricos. Cada palavra é codificada em um número que representa sua classificação em frequência. As palavras mais frequentes têm números baixos; palavras menos frequentes têm números mais altos.

Como ponto de partida, o código importa a função imdb do Keras e a utiliza para recuperar os dados da Internet (cerca de um download de 17,5 MB). Os parâmetros que o exemplo usa abrangem apenas as 10.000 palavras principais e o Keras deve embaralhar os dados usando uma semente aleatória específica. (O conhecimento da semente possibilita a reprodução aleatória conforme necessário.) A função retorna dois conjuntos de trem e teste, ambos feitos de seqüências de texto e o resultado do sentimento.

de keras.datasets import imdb
top_words = 10000
((x_train, y_train),
(x_test, y_test)) = imdb.load_data (num_words = top_words,
semente = 21)

Após a conclusão do código anterior, você pode verificar o número de exemplos usando o seguinte código:

print ("Exemplos de treinamento:% i"% len (x_train))
print ("Exemplos de teste:% i"% len (x_test))

Após indagar sobre o número de casos disponíveis para uso na fase de treinamento e teste da rede neural, o código gera uma resposta de 25.000 exemplos para cada fase. (Esse conjunto de dados é relativamente pequeno para um problema de idioma; claramente o conjunto de dados é principalmente para fins de demonstração.) Além disso, o código determina se o conjunto de dados é equilibrado, o que significa que ele tem um número quase igual de exemplos de sentimentos positivos e negativos.

importar numpy como np
print (np.unique (y_train, return_counts = True))

O resultado, matriz ([12500, 12500]), confirma que o conjunto de dados é dividido igualmente entre resultados positivos e negativos. Esse equilíbrio entre as classes de resposta é exclusivamente devido à natureza demonstrativa do conjunto de dados. No mundo real, você raramente encontra conjuntos de dados equilibrados. A próxima etapa cria alguns dicionários Python que podem ser convertidos entre o código usado no conjunto de dados e as palavras reais. De fato, o conjunto de dados usado neste exemplo é pré-processado e fornece seqüências de números representando as palavras, não as próprias palavras. (Os algoritmos LSTM e GRU encontrados em Keras esperam sequências de números como números.)

word_to_id = {w: i ​​+ 3 para w, i em imdb.get_word_index (). items ()}
id_to_word = {0: '', 1: '', 2: ''}
id_to_word.update ({i + 3: w para w, i em imdb.get_word_index (). items ()})
def convert_to_text (sequência):
return '' .join ([id_to_word [s] para s em sequência se s> = 3])
print (convert_to_text (x_train [8]))

O snippet de código anterior define dois dicionários de conversão (de palavras para códigos numéricos e vice-versa) e uma função que traduz os exemplos de conjuntos de dados em texto legível. Como exemplo, o código imprime o nono exemplo: “esse filme foi como um tremendo acidente tão horrível quanto…”. A partir deste trecho, você pode facilmente prever que o sentimento para este filme não é positivo. Palavras como ruim, naufrágio e horrível transmitem um forte sentimento negativo, e isso facilita a adivinhação do sentimento correto.

Neste exemplo, você recebe as seqüências numéricas e as transforma em palavras, mas o oposto é comum. Geralmente, você obtém frases compostas de palavras e as transforma em seqüências de números inteiros para alimentar uma camada de RNNs. O Keras oferece uma função especializada, o Tokenizer, que pode fazer isso por você. Ele usa os métodos fit_on_text, para aprender como mapear palavras para números inteiros a partir de dados de treinamento, e examples_to_matrix, para transformar texto em uma sequência.

No entanto, em outras frases, você pode não encontrar essas palavras reveladoras para a análise de sentimentos. O sentimento é expresso de uma maneira mais sutil ou indireta, e a compreensão do sentimento no início do texto pode não ser possível porque frases e palavras reveladoras podem aparecer muito mais tarde no discurso. Por esse motivo, você também precisa decidir quanto da frase deseja analisar.

Convencionalmente, você pega uma parte inicial do texto e a usa como representante de toda a revisão. Às vezes, você só precisa de algumas palavras iniciais - por exemplo, as primeiras 50 palavras - para entender; às vezes você precisa de mais. Os textos especialmente longos não revelam sua orientação cedo. Portanto, cabe a você entender o tipo de texto com o qual está trabalhando e decidir quantas palavras analisar usando o aprendizado profundo. Este exemplo considera apenas as 200 primeiras palavras, o que deve ser suficiente.

Você notou que o código começa a dar código para palavras começando com o número 3, deixando códigos de 0 a 2. Números mais baixos são usados ​​para tags especiais, como sinalizar o início da frase, preenchendo espaços vazios para corrigir a sequência em um determinado comprimento e marcar as palavras que são excluídas porque não são frequentes o suficiente. Este exemplo captura apenas as 10.000 palavras mais frequentes. Usar tags para apontar situações de início, fim e notáveis ​​é um truque que funciona com RNNs, especialmente para tradução automática.

de keras.preprocessing.sequence import pad_sequences
max_pad = 200
x_train = pad_sequences (x_train,
maxlen = max_pad)
x_test = pad_sequences (x_test,
maxlen = max_pad)
impressão (x_train [0])

Usando a função pad_sequences do Keras com max_pad definido como 200, o código recebe as primeiras duzentas palavras de cada revisão. Caso a revisão contenha menos de duzentas palavras, o número de zero necessário precede a sequência para atingir o número necessário de elementos da sequência. Cortar as seqüências em um determinado comprimento e preencher os vazios com valores zero é chamado de preenchimento de entrada, uma atividade de processamento importante ao usar RNNs como algoritmos de aprendizado profundo. Agora o código cria a arquitetura:

de keras.models import Sequential
de keras.layers importam Bidirecional, Denso, Dropout
de keras.layers importam GlobalMaxPool1D, LSTM
de keras.layers.embeddings import Incorporação
embedding_vector_length = 32
model = Sequencial ()
model.add (incorporação (top_words,
embedding_vector_length,
input_length = max_pad))
model.add (bidirecional (LSTM (64, return_sequences = True))))
model.add (GlobalMaxPool1D ())
model.add (denso (16, ativação = "relu"))
model.add (Denso (1, ativação = "sigmóide"))
model.compile (loss = 'binary_crossentropy',
otimizador = 'adam',
métricas = ['precisão'])
print (model.summary ())

O snippet de código anterior define a forma do modelo de aprendizado profundo, onde ele usa algumas camadas especializadas para o processamento de linguagem natural do Keras. O exemplo também exigiu um resumo do modelo (comando model.summary ()) para determinar o que está acontecendo com a arquitetura usando diferentes camadas neurais.

Você tem a camada Incorporação, que transforma as seqüências numéricas em uma incorporação densa de palavras. Esse tipo de incorporação de palavras é mais adequado para ser aprendido por uma camada de RNNs. O Keras fornece uma camada de incorporação, que, além de ser necessariamente a primeira camada da rede, pode realizar duas tarefas:

  • Aplicando incorporação de palavras pré-treinadas (como Word2vec ou GloVe) à entrada de sequência. Você só precisa passar a matriz que contém a incorporação para seus pesos de parâmetro. Criando uma incorporação de palavras do zero, com base nas entradas que recebe.

Nesse segundo caso, a incorporação precisa apenas saber:

  • input_dim: o tamanho do vocabulário esperado dos dados output_dim: o tamanho do espaço de incorporação que será produzido (as chamadas dimensões) input_length: o tamanho da sequência a ser esperada

Depois de determinar os parâmetros, a Incorporação encontrará os melhores pesos para transformar as seqüências em uma matriz densa durante o treinamento. O tamanho denso da matriz é dado pelo comprimento das sequências e pela dimensionalidade da incorporação.

Se você usar a camada Incorporação fornecida pelo Keras, lembre-se de que a função fornece apenas uma matriz de peso do tamanho do vocabulário pela dimensão da incorporação desejada. Ele mapeia as palavras para as colunas da matriz e ajusta os pesos da matriz para os exemplos fornecidos. Essa solução, embora prática para problemas de linguagem fora do padrão, não é análoga à incorporação de palavras discutida anteriormente, que é treinada de maneira diferente e em milhões de exemplos.

O exemplo usa o agrupamento bidirecional - uma camada LSTM de 64 células. Bidirecional transforma uma camada LSTM normal dobrando-a: No primeiro lado, aplica a sequência normal de entradas que você fornece; no segundo, passa o inverso da sequência. Você usa essa abordagem porque, às vezes, usa palavras em uma ordem diferente e adequada, e a construção de uma camada bidirecional captura qualquer padrão de palavra, independentemente da ordem. A implementação do Keras é realmente direta: você apenas a aplica como uma função na camada que deseja renderizar bidirecionalmente.

O LSTM bidirecional é configurado para retornar sequências (return_sequences = True); isto é, para cada célula, ele retorna o resultado fornecido depois de ver cada elemento da sequência. Os resultados, para cada sequência, são uma matriz de saída de 200 x 128, em que 200 é o número de elementos da sequência e 128 é o número de células LSTM usadas na camada. Essa técnica impede que o RNN obtenha o último resultado de cada célula LSTM. Dicas sobre o sentimento do texto podem realmente aparecer em qualquer lugar da sequência de palavras incorporada.

Em resumo, é importante não obter o último resultado de cada célula, mas sim o melhor resultado. Portanto, o código se baseia na seguinte camada, GlobalMaxPool1D, para verificar cada sequência de resultados fornecida por cada célula LSTM e reter apenas o resultado máximo. Isso deve garantir que o exemplo capte o sinal mais forte de cada célula LSTM, que, esperamos, seja especializada em seu treinamento para captar alguns sinais significativos.

Depois que os sinais neurais são filtrados, o exemplo possui uma camada de 128 saídas, uma para cada célula LSTM. O código reduz e mistura os sinais usando uma camada densa sucessiva de 16 neurônios com a ativação da ReLU (fazendo com que apenas os sinais positivos passem). A arquitetura termina com um nó final usando a ativação sigmóide, que comprime os resultados no intervalo de 0 a 1 e os faz parecer probabilidades.

Depois de definir a arquitetura, agora você pode treinar a rede para executar a análise de sentimentos. Três épocas (passando os dados três vezes pela rede para que eles aprendam os padrões) serão suficientes. O código usa lotes de 256 revisões a cada vez, o que permite que a rede veja variedade suficiente de palavras e sentimentos antes de atualizar seus pesos usando a retropropagação. Por fim, o código concentra-se nos resultados fornecidos pelos dados de validação (que não fazem parte dos dados de treinamento). Obter um bom resultado com os dados de validação significa que a rede neural está processando a entrada corretamente. O código relata os dados de validação logo após cada época terminar.

history = model.fit (x_train, y_train,
validation_data = (x_test, y_test),
épocas = 3, tamanho do lote = 256)

A obtenção dos resultados demora um pouco, mas se você estiver usando uma GPU, ela será concluída no tempo que você tomar para tomar uma xícara de café. Neste ponto, você pode avaliar os resultados, novamente usando os dados de validação. (Os resultados não devem ter surpresas ou diferenças em relação ao que o código relatou durante o treinamento.)

perda, métrica = model.evaluate (x_test, y_test, detalhado = 0)
print ("Precisão do teste:% 0,3f"% métrica)

A precisão final, que é a porcentagem de respostas corretas da rede neural profunda, terá um valor entre 85 e 86%. O resultado mudará um pouco cada vez que você executar o experimento por causa da randomização ao construir sua rede neural. Isso é perfeitamente normal, considerando o tamanho pequeno dos dados com os quais você está trabalhando. Se você começar com os pesos da sorte certos, o aprendizado será mais fácil em uma sessão de treinamento tão curta.

No final, sua rede é um analisador de sentimentos capaz de adivinhar corretamente o sentimento expresso em uma crítica de cinema cerca de 85% das vezes. Dado ainda mais dados de treinamento e arquiteturas neurais mais sofisticadas, você pode obter resultados ainda mais impressionantes. No marketing, uma ferramenta semelhante é usada para automatizar muitos processos que exigem a leitura de texto e a ação. Novamente, você pode associar uma rede como essa a uma rede neural que ouve uma voz e a transforma em texto. (Essa é outra aplicação das RNNs, agora com Alexa, Siri, Google Voice e muitos outros assistentes pessoais.) A transição permite que o aplicativo entenda o sentimento mesmo em expressões vocais, como uma ligação telefônica de um cliente.