Análise de sentimentos de frases usando redes neurais

Olá a todos!

Todas as pessoas que recebem ensino superior, sem serem expulsas, ainda assim chegam ao estágio de escrever um diploma. Eu não fui exceção. Eu queria implementar algo interessante e dominar o até agora inexplorado, então chamei a atenção para o tópico de redes neurais e inteligência artificial em geral. E a tarefa que resolvi com a ajuda dele é a análise da tonalidade do texto, que já é amplamente utilizada em vários sistemas de monitoramento. Vou tentar descrever o processo de sua solução neste artigo.

Em suma, o objetivo é entender se uma frase tem uma conotação positiva ou negativa. Quero dizer imediatamente que esse problema pode ser resolvido de várias maneiras, e não apenas pelas redes neurais. Podemos criar dicionários nos quais as posições das palavras estão marcadas, etc. (todos os métodos estão em abundância no hub), mas cada método pode ir além, de acordo com o artigo, portanto, deixaremos a revisão para mais tarde.

Dados


A primeira tarefa no meu caminho foi coletar e pré-processar dados para treinamento. Um bom conjunto de dados para esse caso é o corpus de textos curtos de Yu. Rubtsova, anteriormente divididos em frases positivas e negativas coletadas no Twitter. O que é especialmente conveniente - tudo isso existe no formato CSV.

Preparação do treinamento


Preste atenção na forma em que os dados são apresentados - muitos emoticons, links, caracteres desnecessários, hits. Tudo isso não é uma informação importante e apenas interfere no aprendizado; além disso, tudo deve ser removido em latim. Portanto, o texto seria bom para pré-processar.

def preprocessText(text):
    text = text.lower().replace("", "")
    text = re.sub('((www\.[^\s]+)|(https?://[^\s]+))', ' ', text)
    text = re.sub('@[^\s]+', ' ', text)
    text = re.sub('[^a-zA-Z--1-9]+', ' ', text)
    text = re.sub(' +', ' ', text)
    return text.strip()

Depois de fugir todas as frases do arquivo, as colocamos em minúsculas, substituímos "" por "e", referências, menções, simplesmente removemos as palavras em inglês por falta de significado. Em resumo, fazemos do mesmo tipo, limpando o “lixo” que é supérfluo para o treinamento.

Ferramentas


Obviamente, se você tiver um supercomputador em casa, poderá rolar esta seção ainda mais, procurando uma parte interessante. Aconselho o restante do serviço Google Colab , que permite executar o Jupyter Notebooks (e quem nunca ouviu falar sobre isso, para ajudar o mecanismo de pesquisa) usando apenas um navegador e todo o trabalho é feito em uma máquina virtual na nuvem.
O tamanho temporário da sessão que você recebe para trabalhar é limitado a 12 horas - você pode concluir mais cedo, após o que tudo será redefinido.

Nós escrevemos nosso belo código


Como qualquer outro iniciante no aprendizado de máquina, eu escolhi o Python - porque é simples e as bibliotecas são uma nuvem inteira.

Primeiro, o gerenciador de pacotes executará um comando importante, cujo significado explicarei um pouco mais adiante.

imagem

Em seguida, importamos as bibliotecas que usaremos ao treinar a grade e preparar os dados, acho que muitas delas lhe são familiares.

imagem

Finalmente ao ponto.

Então, por que baixamos e importamos a biblioteca de texto Tensorflow? O fato é que as frases não podem ser "alimentadas" para a grade na forma em que são legíveis para nós. É aqui que entra a incorporação de palavras, um termo para o qual não encontrei uma tradução adequada e, em geral, duvido de sua existência. Mas, grosso modo, estamos falando sobre combinar um vetor a uma palavra. Isto é bem dito aqui .

Precisamos converter frases inteiras em um vetor, para que possamos usar uma solução pronta do Google - Universal Frases Encoder.

imagem

Você pode baixá-lo no hub aqui . Aliás, existem muitas soluções prontas mais interessantes que podem ser usadas ao se aprender uma rede neural, para não se incomodar.

imagem

Todos os tweets são classificados por classe - ruim / bom. Criamos um pandas-dataframe no qual eles são classificados por classe (os ruins não são visíveis na imagem, devido ao fato de que eles se encaixam).

imagem

Preparamos os dados - vamos ao modelo em si. Para fazer isso, use a estrutura Keras.

from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential, load_model
model = tf.keras.Sequential()

model.add(
  tf.keras.layers.Dense(
    units=256,
    input_shape=(X_train.shape[1], ),
    activation='relu'
  )
)
model.add(
  tf.keras.layers.Dropout(rate=0.5)
)

model.add(
  tf.keras.layers.Dense(
    units=128,
    activation='relu'
  )
)
model.add(
  tf.keras.layers.Dropout(rate=0.5)
)

model.add(tf.keras.layers.Dense(2, activation='softmax'))
model.compile(
    loss='categorical_crossentropy',
    optimizer=tf.keras.optimizers.Adam(0.001),
    metrics=['accuracy']
)

history = model.fit(
    X_train, y_train,
    epochs=10,
    batch_size=16,
    validation_split=0.1,
    verbose=1,
    shuffle=True
)

model.evaluate(X_test, y_test)

Um pouco sobre o modelo em si. Possui camadas de entrada, ocultas e de saída.

Cada camada tem sua própria função de ativação.

Uma pequena explicação: nas redes neurais artificiais, a função de ativação do neurônio determina o sinal de saída, que é determinado pelo sinal de entrada ou por um conjunto de sinais de entrada. Você pode ler mais aqui , pelo fato de muitos deles existirem para tarefas diferentes, mas trabalharemos apenas com 2.

Atribuímos a função de ativação ReLu às duas primeiras camadas . O dia de folga é Softmax .

Além de adicionar camadas, você pode notar a palavra "desistência". O que é isso? Curiosamente, mas além do problema de subaprendizagem de uma rede neural, quando suas previsões não são verdadeiras, há o problema de super treinamento - o modelo explica bem apenas exemplos da amostra de treinamento, adaptando-os aos exemplos de treinamento, em vez de aprender a classificar exemplos que não participaram do treinamento. Isso é brega nos novos dados, sua linda modelo, que já havia feito seu trabalho de forma soberba antes, simplesmente "voa" e começa a surpreendê-lo desagradável. Portanto, o Dropout está envolvido no fato de que, com alguma probabilidade especificada, "desliga" os neurônios da grade, de modo que eles deixam de participar do processo de aprendizado. Em seguida, a média dos resultados de várias redes (quando um neurônio é excluído da rede, um novo é obtido).

A propósito, um ótimo artigo para quem está interessado.

Você pode começar a aprender!

Train on 53082 samples, validate on 5898 samples
Epoch 1/10
53082/53082 [==============================] - 12s 223us/sample - loss: 0.5451 - accuracy: 0.7207 - val_loss: 0.5105 - val_accuracy: 0.7397
Epoch 2/10
53082/53082 [==============================] - 11s 213us/sample - loss: 0.5129 - accuracy: 0.7452 - val_loss: 0.5000 - val_accuracy: 0.7523
Epoch 3/10
53082/53082 [==============================] - 11s 215us/sample - loss: 0.4885 - accuracy: 0.7624 - val_loss: 0.4914 - val_accuracy: 0.7538
Epoch 4/10
53082/53082 [==============================] - 11s 215us/sample - loss: 0.4686 - accuracy: 0.7739 - val_loss: 0.4865 - val_accuracy: 0.7589
Epoch 5/10
53082/53082 [==============================] - 11s 214us/sample - loss: 0.4474 - accuracy: 0.7889 - val_loss: 0.4873 - val_accuracy: 0.7616
Epoch 6/10
53082/53082 [==============================] - 11s 216us/sample - loss: 0.4272 - accuracy: 0.8004 - val_loss: 0.4878 - val_accuracy: 0.7603
Epoch 7/10
53082/53082 [==============================] - 11s 213us/sample - loss: 0.4081 - accuracy: 0.8111 - val_loss: 0.4986 - val_accuracy: 0.7594
Epoch 8/10
53082/53082 [==============================] - 11s 215us/sample - loss: 0.3899 - accuracy: 0.8241 - val_loss: 0.5101 - val_accuracy: 0.7564
Epoch 9/10
53082/53082 [==============================] - 11s 215us/sample - loss: 0.3733 - accuracy: 0.8315 - val_loss: 0.5035 - val_accuracy: 0.7633
Epoch 10/10
53082/53082 [==============================] - 11s 215us/sample - loss: 0.3596 - accuracy: 0.8400 - val_loss: 0.5239 - val_accuracy: 0.7620
6554/6554 [==============================] - 0s 53us/sample - loss: 0.5249 - accuracy: 0.7524
[0.5249265961105736, 0.752365]

Então, dez épocas se passaram. Para aqueles que não estão familiarizados com esses conceitos, explicarei a definição da Internet: a era é uma iteração no processo de aprendizado, incluindo a apresentação de todos os exemplos do conjunto de treinamento e, possivelmente, verificando a qualidade do treinamento no conjunto de controle. Portanto, todos os nossos dados foram 10 vezes completos em todo o processo.

Resultado


imagem

Obviamente, a rede será necessária mais de uma vez e seria bom saber como salvá-la para a posteridade, para que eles não precisem treiná-la novamente e tudo mais.

A estrutura é salva no formato JSON e os pesos são gravados em um arquivo h5 .

O mecanismo de pesquisa está cheio de guias sobre como iniciar o processo inverso de inicializar a rede a partir desses arquivos, então não vou descrevê-lo.

Usando o método de previsão, tentaremos descobrir a opinião da rede e o componente tonal de 2 frases obviamente diferentes a esse respeito. É verdade que eles ainda precisam ser reduzidos a uma matriz primeiro, mas já sabemos como fazer isso usando uma solução pronta.

Na saída, vemos 2 números - a probabilidade de a frase pertencer às classes "negativa" / "positiva". Acho que a imagem mostra claramente que há uma diferença) Então palavras semelhantes foram no final e a rede fez um ótimo trabalho com o relacionamento delas com as aulas.

Conclusão


Então, eu quero dizer que dominar ferramentas avançadas para desenvolver redes neurais e resolver problemas simples, tendo determinado corretamente as etapas necessárias para resolvê-lo e tendo lido a teoria um pouco, parece ser uma tarefa bastante fácil. Gostaria de observar que vi vários artigos sobre o tema da análise tonal em Habré, mas ainda assim foi interessante tentar algo mais fácil e sem uma enorme massa de texto, embora a teoria deva ser estudada incondicionalmente :)

Você pode encontrar o código aqui se colocar um asterisco no projeto, será ótimo. Se você precisar de arquivos com pesos e estrutura de rede, além de dados processados ​​- escreva nos comentários, adicione ao repositório.

All Articles