Análise de Sentimentos - Aprenda de uma vez por todas como funciona utilizando dados do Twitter - Aprenda Data Science e Alavanque a sua Carreira
Rodrigo Santana Março 15, 2017 30 comentários Conceitos e Fundamentos, Machine Learning
Você sabe o que é Análise de Sentimentos ?
Imagine uma empresa que quer saber sobre a reputação do seu produto que foi lançado no mercado.
É possível usar as redes sociais para buscar informações, mas como saber se estão falando bem ou mau desse produto?
Ler, entender e tirar uma conclusão de centenas de comentários de usuários sobre um produto pode ser uma tarefa inviável.
Análise de Sentimentos é uma técnica que consiste em extrair informações de textos em linguagem natural.
O objetivo dessa técnica é obter de forma automática a polaridade de um texto ou sentença. Por exemplo, dada uma sentença um computador classifica como positivo ou negativo essa sentença.
Ou ainda, dado um texto, o computador classificar como positivo ou negativo o conteúdo deste.
Muitas empresas e Startups fazem Análise de Sentimentos de opiniões sobre seus produtos nas redes sociais. O objetivo é saber o humor dos seus produtos nessas mídias.
Nesse artigo vamos abordar essa técnica sendo aplicada em dados do Twitter.
Estes dados foram coletados por pessoas que trabalham para o governo de Minas e foi nos passada para testes.
Além de aprender sobre essa técnica, irei disponibilizar a base de dados e os scripts utilizados nesse artigo.
Ficou curioso(a) para saber mais sobre Análise de Sentimentos?
Então continue lendo artigo. Nele você vai aprender mais sobre:
Base de dados e Scripts
Pre-processamento do texto
Modelando a base de dados
Naive Bayes – Como funciona
Sentiment Analysis hands on!
Avaliando o modelo – Resultados
Se você já gostou do assunto desse artigo, não deixe de compartilhar com seus amigos para que cada vez mais pessoas aprendam sobre como funciona análise de sentimentos e assine nossa lista para ficar sempre atualizado com novas postagens.
Nossa base de Tweets contém 8199 linhas classificadas como positivo, negativo e neutro.
Você pode fazer download desta aqui
Para acompanhar tudo que foi feito nesse artigo, disponibilizo aqui o notebook com todos os scripts utilizados.
Aprecie sem moderação 🙂
O Pré-processamento do texto consiste em alterar a estrutura da base de dados original para um formato mais conveniente para o processamento computacional.
Uma das tarefas muito utilizadas no pré-processamento de textos é a remoção de stopwords.
Esse método consiste em remover palavras muito frequentes tais como "a", "de", "o", "da", "que","e","do" entre outras, pois, estas muitas vezes não representam informações relevantes para construção do modelo.
Outra tarefa muito utilizada é a Stemming.
Essa técnica consiste em reduzir o termo ao seu radical, removendo afixos e vogais temáticas.
Por exemplo, a palavra "frequentemente" após esse processo se torna "frequent", a palavra "copiar" após esse processo se torna "copi".
Uma vantagem do pré-processamento é a diminuição das palavras da base de dados, consequentemente temos um vocabulário menor de palavras no nosso modelo.
Outra vantagem é que com menos palavras para processar temos um ganho no tempo computacional para geração do modelo
Pré-processamento de textos e Análise de Sentimentos
Para a tarefa de análise de sentimentos é importante quaisquer informações que levam a um entendimento do sentimento de uma frase.
Por exemplo, a frase "'Eu não gosto do partido, e também não votaria novamente nesse governante!'".
Podemos perceber que está claro que o advérbio não faz toda a diferença na sentença. Este está negando que gosta de um partido e que não votaria novamente.
Está claro que a frase é negativa.
Porém, métodos de stopwords removem palavras muito usadas, distorcendo o sentido das frases.
Veja como ficaria essa frase após um método de stopwords:
'Gosto partido votaria novamente nesse governante"
A frase ficou com um outro sentido, o advérbio não foi removido distorcendo completamente o sentimento da frase.
Para a tarefa de análise de sentimentos, não iremos remover stopwords, e nem fazer stemming, pois, essas técnicas afeta o desempenho do classificador de forma negativa.
Vou disponibilizar as funções para remoção de stopwords e stemming, caso queira fazer testes.
A tarefa de Análise de Sentimentos pode ser feita de várias formas.
Nesse artigo iremos usar Machine Learning usando aprendizado supervisionado.
Caso tenha alguma dúvida sobre esse assunto leia esse artigo
Vamos usar o Algoritmo Naive Bayes para fazer a tarefa de análise de sentimentos utilizando classificação
O Naive Bayes é um classificador probabilístico simples baseado no teorema de Bayes.
Este utiliza dados de treino para formar um modelo probabilístico baseado na evidência das features no dado.
O Naive Bayes supõe que há uma independência entre as features do modelo. Isso significa que o classificador assume que a presença de uma determinada feature não tem nenhuma relação com outras.
No caso de um texto, o classificador assume que as palavras não tem uma relação entre elas.
Por exemplo, na frase "I love my dog, but today it's terrible" o classificador assume que as palavras dessa frase não dependem uma da outra.
Sendo assim, essa sentença pode ter uma polaridade positiva caso a maioria das palavras tem uma probabilidade maior de serem positivas.
É por isso que este tem o nome de "Naive".
Apesar dessa característica, o Naive Bayes funciona muito bem para classificação de textos.
Como o Naive Bayes Funciona?
Vamos entender com um exemplo simples.
Abaixo temos uma base de palavras com as suas respectivas classes.
O objetivo aqui é classificar se a palavra "love" é positiva ou negativa. Veja:
Base dados..
Palavra Classe
love negative
O primeiro passo é criar uma tabela de frequência das palavras e suas classes
Palavra Positive Negative
Agora crie a tabela de probabilidades
dog 2 2/13 = 0.15
love 3 2 5/13 = 0.38
bad 1 1/13 =0.076
cat 1 3 4/13 = 0.30
house 2 2/13 = 0.15
7/13 = 0.53 6/13 = 0.46
Agora vamos calcular a probabilidade da palavra "love" ser positiva ou negativa.
O Naive Bayes usa a seguinte sentença:
P(positive|'love') = P('love'|positive) * P(positive) / P('love')
P(negative|'love') = P('love'|negative) * P(negative) / P('love')
P('love'|positive) = 3/7 = 0.42 , P(positive) = 7/13 = 0.53, P('love') = 5/13 = 0.38
P('love'|negative) = 2/6 = 0.33 , P(negative) =6/13 = 0.46, P('love') = 5/13 = 0.38
Agora, P(positive|'love') = 0.42 * 0.53 / 0.38 = 0.58
Agora, P(negative|'love') = 0.33 * 0.46 / 0.38 = 0.39
Veja que a probabilidade da palavra 'love' ser positiva é maior que a probabilidade dela ser negativa.
Para classificar uma instância de teste, a probabilidade de cada palavra é calculada como no exemplo acima, caso a palavra exista no treino.
Caso o classificador não "conheça" nenhuma palavra da instância de teste, este usará a probabilidade da classe de maior frequência no treino.
Vamos usar as seguintes bibliotecas para implementação da nossa solução.
Caso não tenha instalado, consulte este artigo para instalar em seu ambiente.
Aqui vou importa-las de uma só vez para simplificar o processo, mas ao longo do artigo cada uma será explicada conforme sua utilização.
bibliotecas_utilizadas
import nltk import re import pandas as pd from sklearn.feature_extraction.text import CountVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn import metrics from sklearn.model_selection import cross_val_predict
Modelando a base de dados.
Existem diversas formas de modelar uma base de dados de texto. A mais conhecida é chamada de Bag of Words.
O modelo baseado em Bag of words utiliza todas as palavras do texto, a frequência de cada palavra e associa isso a classe do treino.
A frequência das palavras é usada para treinar um modelo.
Por exemplo, imagine as seguintes sentenças:
Sentença 1: O smartphone é bom, porém não gosto de smartphone grandes , Negativo
Sentença 2: Gostei bastante desse smartphone, mesmo sendo caro, Positivo
O modelo nesse caso, usa todas as palavras da base, ou seja, todas as palavras das duas sentenças.
{o, smartphone,é, bom, porém, não, gosto, de, grandes,gostei,bastante,desse,mesmo,sendo,caro}
Em seguida é feita a contagem do número de vezes que cada palavra apareceu na sentença.
Para representar a Sentença 1 a palavra "smartphone" ficaria com a contagem 2, pois esta apareceu duas vezes na frase. As outras palavras ficaram com a contagem 1 e 0 quando essas não foram encontradas na sentença. Veja:
{1,2,1,1,1,1,1,1,1,0,0,0,0,0,0, Negativo}
A sentença 2 seria representada da seguinte forma:
{0,1,0,0,0,0,0,0,0,1,1,1,1,1,1, Positivo}
Primeiramente vamos ler a base de dados e contar quantas linhas contém nesta..
dataset = pd.read_csv('tweets-mg.csv) dataset.count()
dataset = pd.read_csv('tweets-mg.csv)
Para modelar a base primeiramente é preciso separar os tweets das classes.
tweets = dataset['Text'].values classes = dataset['Classificacao'].values
tweets = dataset['Text'].values
classes = dataset['Classificacao'].values
Em seguida vamos criar o código que treina o modelo usando a abordagem Bag of Words e o algoritmo Naive Bayes Multinomial.
vectorizer = CountVectorizer(analyzer="word") freq_tweets = vectorizer.fit_transform(tweets) modelo = MultinomialNB() modelo.fit(freq_tweets,classes)
vectorizer = CountVectorizer(analyzer="word")
freq_tweets = vectorizer.fit_transform(tweets)
modelo.fit(freq_tweets,classes)
Na linha 1 criamos um objeto do tipo CountVectorizer chamado vectorizer.
Após isso, na linha 2, usamos o objeto vectorizer para calcular a frequência de todas as palavras da lista de tweets e armazenamos seu retorno em freq_tweets.
Em seguida, criamos um objeto chamado modelo do tipo Naive Bayes Multinomial. Esse é o algoritmo de classificação que iremos utilizar.
Por fim, na linha 4, treinamos o modelo usando a frequência de palavras (freq_tweets) e as classes de cada instância.
Com o modelo já criado, vamos fazer alguns testes de classificação
Defina algumas instâncias, dentro de uma lista, como no exemplo abaixo:
testes = ['Esse governo está no início, vamos ver o que vai dar', 'Estou muito feliz com o governo de Minas esse ano', 'O estado de Minas Gerais decretou calamidade financeira!!!', 'A segurança desse país está deixando a desejar', 'O governador de Minas é do PT']
testes = ['Esse governo está no início, vamos ver o que vai dar',
'Estou muito feliz com o governo de Minas esse ano',
'O estado de Minas Gerais decretou calamidade financeira!!!',
'A segurança desse país está deixando a desejar',
'O governador de Minas é do PT']
Em seguida vamos transforma-las no formato Bag of words e passar para nosso modelo classificar.
freq_testes = vectorizer.transform(testes) modelo.predict(freq_testes)
freq_testes = vectorizer.transform(testes)
modelo.predict(freq_testes)
Na primeira linha, armazenamos lista de frequências e na linha seguinte executamos a função predict para retornar uma classe para nossas instâncias de teste. Veja a saída:
array(['Neutro', 'Neutro', 'Negativo', 'Negativo', 'Neutro']
Podemos ver que nosso classificador errou na segunda instância, onde a classe deveria ser Positivo.
Em compensação nas outras frases este se saiu bem. 🙂
Tente outras instâncias e observe o resultado do classificador.
O teste acima é interessante apenas para ver como a coisa funciona na prática.
Precisamos validar o modelo com dados que este não conhece, para termos uma noção de como este vai se sair em um sistema real.
Podemos separar parte dos dados para treino e parte para teste.
Por exemplo, nossa base tem 8199 linhas, poderíamos separar 80% desta para treinar o modelo e os outros 20% para testa-lo.
Dessa forma, o modelo seria testado com dados que este não conhece.
A desvantagem dessa abordagem é que caso os 20% dos dados fossem muito parecidos com a parte do treino, teríamos um ótimo resultado.
Mas isso pode não refletir a realidade na qual o modelo será usado.
Existe uma forma melhor de validar o modelo criado.
A forma mais eficiente é aplicar a técnica de Cross Validation, ou Validação Cruzada.
Esta consiste em dividir todo o dado em K partes, essas partes que se chamam folds.
Dessas partes uma será separada para teste e as outras restantes serão usadas para treinar o modelo.
Isso é feito repetidamente até que o modelo seja treinado e testado com todas as partes (folds).
Para entender, veja esse exemplo simples:
Para k = 10 , imagine que todo nosso dado de treino foi dividido em 10 partes distintas.
Assim, o modelo será treinado com 9 partes, e testado com a parte restante.
Esse processo é repetido até que o modelo seja treinado e testado com todas as partes do dado.
Com essa técnica evitamos problemas de variância nos dados.
Para implementar a validação do modelo, vamos usar a função cross_val_predict() também disponível na biblioteca Scikit-Learn
resultados = cross_val_predict(modelo, freq_tweets, sentimento, cv=10)
O comando atribui a variável resultados, a validação usando a técnica Cross Validation com 10 folds
A primeira métrica que vamos medir é a Acurácia do modelo.
A Acurácia, basicamente é o percentual de acertos que modelo teve.
Para ver a acurácia faça:
metrics.accuracy_score(classes,resultados) 0.8831564824978656
metrics.accuracy_score(classes,resultados)
0.8831564824978656
Perceba que modelo teve 0.88 de acurácia, isso significa que este acertou 88% dos testes.
Existem outras métricas que nos dizem mais sobre os resultados.
As métricas precision(precisão), recall(revocação) e f1-score(medida F) nos da uma visão melhor dos resultados e permite que entendemos melhor como o modelo está funcionando.
Para entender o que é a Precisão e Revocação e F1-Score, primeiro temos que saber sobre a terminologia para classificação. São elas:
True positive (TP) : significa uma classificação correta da classe positive. Por exemplo, a classe real é Positivo e o modelo classificou como Positivo.
True negative (TN) : significa uma classificação correta da classe negative. Por exemplo, a classe real é Negativo e o modelo classificou como Negativo.
False positive (FP) : significa uma classificação errada da classe positive. Por exemplo, a classe real é Negativo e o modelo classificou como Positivo.
False negative (FN) : Significa uma classificação errada da classe negative. Por exemplo, a classe real é Positivo e o modelo classificou como Negativo.
A precisão (precision) é calculada da seguinte forma:
Isso significa o número de vezes que uma classe foi predita corretamente dividida pelo número de vezes que a classe foi predita.
Por exemplo, o número de vezes que a classe Positivo foi classificada corretamente dividido pelo número de classes classificadas como Positivo.
A revocação (recall) é calculada da seguinte forma:
Isso significa o número de vezes que uma classe foi predita corretamente (TP) dividido pelo número de vezes que a classe aparece no dado de teste (FN).
Por exemplo, o número de vezes que a classe Positivo foi predita corretamente dividido pelo número de classes Positivo que contém no dado de teste.
A F1-score é calculada da seguinte forma:
f1-score = 2*((precision * recall) / (precision + recall)
Essa medida é a média harmônica entre precisão e revocação. Com essa informação podemos dizer a performance do classificador com um indicador apenas.
Como essa medida é uma média, esta da uma visão mais exata da eficiência do classificador que apenas a precisão ou a revocação.
E a acurácia mostrada acima? Para calcular esta, use a formula:
Accuracy = (TP +TN )/ (TP + FP +TN +FN)
Perceba que a acurácia nos mostra como o classificador se saiu de uma maneira geral, pois, esta mede a quantidade de acertos sobre o todo.
Por isso podemos dizer que seria o percentual de instâncias classificadas corretamente.
Essa matriz, de confusa, só tem o nome 🙂
Também conhecida como tabela de contingência, esta é uma matriz simples que apresenta os resultados de um classificador de forma intuitiva.
Real Predito
Positivo 10 3
Negativo 4 6
Sobre o topo da tabela temos as classes preditas pelo classificador.
No lado esquerdo temos as classes reais.
Para entender, imagine que temos 23 instâncias para classificar em nossa base de teste.
Dessas, 13 são classes positivas e 10 são classes negativas.
Após o teste do modelo, imagine que a nossa Matriz de Confusão seja a tabela acima.
Com essa tabela fica fácil ver que para a classe "positivo" o classificador classificou 10 instâncias como positivo e 3 como negativo, ou seja, ele acerto 10 e errou 3 instâncias.
Para classe "negativo", o classificador classificou 4 como positivo e 6 como negativo, ou seja, este acertou 6 e errou 4.
Para medir a Precisão, Revocação e Medida F do modelo faça:
sentimento=['Positivo','Negativo','Neutro'] print (metrics.classification_report(classes,resultados,sentimento),'') precision recall f1-score support Positivo 0.95 0.88 0.91 3300 Negativo 0.89 0.93 0.91 2446 Neutro 0.80 0.84 0.82 2453 avg / total 0.89 0.88 0.88 8199
sentimento=['Positivo','Negativo','Neutro']
print (metrics.classification_report(classes,resultados,sentimento),'')
Positivo 0.95 0.88 0.91 3300
Negativo 0.89 0.93 0.91 2446
Neutro 0.80 0.84 0.82 2453
avg / total 0.89 0.88 0.88 8199
O pacote metrics exibe as medidas de precisão, revocação e medida F por classe e por fim, a média disso.
Perceba que isso é útil para investigarmos a eficiência do modelo para classificação de classes específicas. Por exemplo, podemos ver que a precisão e a revocação do modelo para classificar instâncias neutras é bem diferente para as classes positivas e negativas.
Outro recurso interessante é a Matriz de Confusão, vamos gerar esta para o nosso modelo:
print (pd.crosstab(classes, resultados, rownames=['Real'], colnames=['Predito'], margins=True), '') Predito Negativo Neutro Positivo All Real Negativo 2275 162 9 2446 Neutro 240 2067 146 2453 Positivo 45 356 2899 3300 All 2560 2585 3054 8199
print (pd.crosstab(classes, resultados, rownames=['Real'], colnames=['Predito'], margins=True), '')
Negativo Neutro Positivo All
Negativo 2275 162 9 2446
Neutro 240 2067 146 2453
Positivo 45 356 2899 3300
All 2560 2585 3054 8199
Podemos tentar melhorar nosso modelo.
Existem várias formas de fazer isso. Podemos alterar o algoritmo de classificação, ou extrair mais features dos dados para treinar de uma forma diferente.
Ou ainda, podemos ajustar os parâmetros do Naive Bayes
Vamos fazer um teste alterando a forma de treinar nosso modelo.
Vamos treina-lo usando a modelagem "bigrams"
Essa modelagem consiste em passar duas palavras como features para o classificador ao invés de apenas uma.
Dessa forma, estamos dizendo que uma palavra tem uma relação com outra palavra, veja um exemplo:
Na frase: "Eu não gosto desse governo" na modelagem inicial passamos para o modelo cada palavra sendo uma feature, ficaria = {eu, não, gosto,desse, governo}
Usando Bigrams, passaríamos para o modelo 2 palavras, veja:
{eu não, não gosto, gosto desse, desse governo}
Vamos treinar o modelo com essa modelagem e avaliar os resultados:
O código abaixo treina o modelo
vectorizer = CountVectorizer(ngram_range=(1,2)) freq_tweets = vectorizer.fit_transform(tweets) modelo = MultinomialNB() modelo.fit(freq_tweets,classes)
vectorizer = CountVectorizer(ngram_range=(1,2))
A única diferença aqui é na linha 1, estamos usando a função ngram_range(1,2) que faz essa modelagem para nós.
Avaliando os resultados novamente
Imprima a acurácia desse novo modelo
resultados = cross_val_predict(modelo, freq_tweets, classes, cv=10) metrics.accuracy_score(classes,resultados) 0.89547505793389437
resultados = cross_val_predict(modelo, freq_tweets, classes, cv=10)
0.89547505793389437
A acurácia melhorou 😉
Isso é bom, mas vamos investigar como está a classificação de cada classe
Vamos imprimir precisão, revocação e medida f1
sentimento=['Positivo','Negativo','Neutro'] print (metrics.classification_report(classes,resultados,sentimento)) precision recall f1-score support Positivo 0.97 0.88 0.92 3300 Negativo 0.91 0.93 0.92 2446 Neutro 0.80 0.89 0.84 2453 avg / total 0.90 0.90 0.90 8199
print (metrics.classification_report(classes,resultados,sentimento))
Positivo 0.97 0.88 0.92 3300
Negativo 0.91 0.93 0.92 2446
Neutro 0.80 0.89 0.84 2453
avg / total 0.90 0.90 0.90 8199
Podemos ver que o medida f1 média também melhorou.
Vamos imprimir a Matriz de confusão
print (pd.crosstab(classes, resultados, rownames=['Real'], colnames=['Predito'], margins=True)) Predito Negativo Neutro Positivo All Real Negativo 2265 179 2 2446 Neutro 181 2177 95 2453 Positivo 43 357 2900 3300 All 2489 2713 2997 8199
print (pd.crosstab(classes, resultados, rownames=['Real'], colnames=['Predito'], margins=True))
Negativo 2265 179 2 2446
Neutro 181 2177 95 2453
Positivo 43 357 2900 3300
All 2489 2713 2997 8199
Podemos ver que o resultado foi interessante. A medida f1 do modelo melhorou com essa modelagem.
E visualizando a tabela de contingência é possível ver que o modelo classificou melhor as instâncias neutras.
Veja, com Bigrams as instâncias neutras foram classificadas 2177 corretamente contra 2067 e diminuiu o erro de instâncias neutras sendo classificadas como Negativo, 181 contra 240.
As instâncias negativas foram melhor classificadas com relação ao positivo, apenas 2 foram classificadas erroneamente como positivo.
Porém, houve um pequeno aumento de instâncias negativas sendo classificadas como neutras, 179 contra 162.
É importante avaliar o modelo usando todas métricas possíveis.
Acima vimos que o modelo melhorou sua eficiência, visto que a classificação de instâncias neutras foram consideravelmente melhores.
Análise de sentimentos tem se tornado uma técnica importante, especialmente em
redes sociais, com o desenvolvimento de aplicações para monitoramento de produtos e
marcas, assim como a análise de opiniões de clientes.
Algumas Startups e empresas já estão usando Análise de Sentimentos em seus negócios.
Um exemplo disso é o Hugme, uma ferramenta focada em monitoramento das redes sociais.
O Hugme é totalmente integrado ao reclameAqui e diversas mídias socias. No Hugme, análise de sentimentos é aplicada na interação do usuário com o canal de atendimento da empresa.
Outro exemplo interessante é startup TrustVox.
Esta tem como objetivo coletar a opinião de clientes que adquiriram um produto da empresa.
A Startup usa Análise de Sentimentos no feedback do cliente, e entrega diversas informações úteis para as empresas que utilizam esse serviço.
Ainda no segmento de atendimento ao cliente, temos a TrackSale
Esta empresa obtém feedback de clientes através de múltiplos canais de coleta de opiniões.
Com as informações coletadas a empresa aplica Análise de Sentimentos nos dados e entrega uma plataforma para os clientes fazerem a gestão da satisfação dos clientes.
A solução é bem interessante e tem muitas funcionalidades. Vale a pena conhecer.
Outro belo exemplo é o projeto Observatório do Investimento que utiliza Análise de Sentimentos para identificar o humor de usuários sobre notícias relacionadas ao mercado financeiro.
São coletadas notícias sobre ativos da bolsa de valores e com esses dados, a técnica de análise de sentimentos é aplicada para se descobrir a polaridade das notícias, definindo assim, o humor médio daquele ativo.
Como você pode usar Análise de Sentimentos para o seu negócio?
Imagine análise de sentimentos aplicada a uma conversa com um assistente virtual que poderia descobrir o humor do cliente e o direcionar para um atendimento mais especializado?
Outro exemplo seria, uma ferramenta que fizesse crawler na Web em busca de opiniões sobre produtos de uma marca.
Com os dados obtidos pode ser aplicado análise de sentimentos em busca de obter um sentimento médio sobre produtos. Isso seria algo bem útil para empresas que buscam melhorar seus produtos e serviços.
Imagine como deve ser difícil para uma produtora de filmes saber qual é a opinião de milhares de pessoas que assistiram um determinado filme.
Como atualmente existem diversos canais de discussão, sites especializados e redes sociais específicas, é possível obter comentários de centenas de pessoas sobre filmes.
Com esses dados, a produtora pode aplicar a técnica de Análise de Sentimentos para classificar centenas de milhares de comentários de forma automática.
Análise de Sentimentos é uma tarefa extremamente poderosa e pode ser utilizada em diversas aplicações em diversos segmentos diferentes. Saber corretamente como e onde aplicar a técnica pode ser um diferencial fundamental para o sucesso do projeto.
Neste artigo mostramos como utilizar uma das abordagens para realizar Análise de Sentimentos em dados do Twitter sobre o Governo de Minas.
Vimos como modelar e processar os dados, entendemos o funcionamento e aplicamos o algoritmo de classificação Naive Bayes.
Por fim avaliamos as métricas do nosso modelo.
Artigo anterior 10 Melhores Ferramentas e Bibliotecas para Trabalhar com Mineração de Dados e Big Data
Próximo artigo Ciência dos Dados com Weka: Domine 7 Técnicas Essênciais sem Escrever uma Linha de Código
Parabéns pelo artigo, poderia esclarecer melhor a contagem que é feita?
{0,1,0,0,0,0,0,0, 0, 1,1,1,1,1,1,1, Positivo}
Não ficou claro para mim como esses valores foram obtidos se é a contagem da palavra na frase, principalmente na segunda, que possui muito mais resultados que palavras.
Olá Oliver, tudo joia? Primeiramente obrigado pelo comentário cara.
Posso esclarecer sim, a contagem que é feita, é o seguinte:
O modelo, usa todas as palavras da base, ou seja, todas as palavras das duas sentenças, assim:
e cria-se um vetor, onde as colunas são as palavras e a frequência de cada palavra é definida conforme a palavra aparece na frase, por exemplo na frase 1 a palavra "smartphone" apareceu duas vezes então a frequência dela no vetor é 2, enquanto que as outras são 1 caso aparecem uma vez ou 0 caso não aparecem na frase, veja:
Frase 1: "O smartphone é bom, porém não gosto de smartphone grandes "
{1, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, Negativo}
Frase 2: " Gostei bastante desse smartphone, mesmo sendo caro "
{0, 1 ,0, 0 ,0 ,0 , 0 ,0 ,0 ,1 ,1 ,1 ,1 ,1 , 1, Positivo}
Ficou mais claro? espero que sim, caso tenha ficado com dúvidas só falar aqui.
Olá, estou tentando acompanhar seu artigo, pois irei fazer meu TCC de análise de dados mas utilizado a Linguagem R, só que para fazer a análise de sentimentos, foi nos orientados a utilizar o NLTK, só que não sei como fazer buscar o arquivo csv. Estou tentando fazer seu passo-a-passo, mas não estou conseguindo, o arquivo tem que estar em um diretório especifico ?
Olá Juliano, tudo tranquilo?
No passo a passo do artigo, o arquivo de dados deve está no mesmo diretório do script python, exemplo:
dataset = pd.read_csv('tweets-mg.csv)
O arquivo "tweets-mg.csv" deve está no mesmo diretório do seu script python. Mas caso não esteja, você pode passar o caminho completo do arquivo que funciona também, por exemplo:
dataset = pd.read_csv('/home/minerandodados/tweets-mg.csv)
Entendeu? posta aqui blz? 😉
Consegui entender isso, mas estou tendo muita dificuldade, e não estou conseguindo fazer, não tenho familiaridade com o Python! até então não sabíamos que iriamos ter que utilizar ele!
Entendi. Amigo olha esse artigo aqui do nosso blog => http://minerandodados.com.br/index.php/2017/02/20/ferramentas-mineracao-de-dados-big-data/#bibliotecas
Você só precisa instalar a biblioteca "Anaconda" e pronto, ela já vem com o Python e com o pandas, ai você vai conseguir avançar. Da uma lida, é fácil, rapidinho você consegue montar seu ambiente. 😉
Ah sim, eu já instalei ela, para rodar os script eu utilizo o spyder?
Bacana, usa o Jupyter notebooks, e baixa o script que disponibilizei no artigo de análise de sentimentos. Aí é só ir seguindo o artigo.
irei tentar! estou fazendo um trabalho quase parecido mas é com Linguagem R, ai a parte de mineração e análise de Sentimentos foi orientado a usarmos o NLTK. Só que tanto o R como o Python é algo novo para nos, e depois devolveremos o resultado do NLTK para uma base de dados e fazer a estatística com o R.
Só seguir o artigo que você consegue. Como falei antes, instala o python e as bibliotecas, tudo muito simples. Abraço!
Rodrigo, estou vendo o passo a passo do codigo, e como eu faço para testar o codigo já treinado, passando uma frase e ver o retorno dele, assim como foi feito no inicio onde passas 5 frases e uma delas não foi mto bem classificada?!
Olá Juliano, joia cara?
Então, como mostrei no exemplo, uma vez que você tem o modelo treinado, você pode mandar fazer uma classificação. veja o exemplo:
frase_teste= ['Isso eh um teste!!']
freq_testes = vectorizer.transform(frase_teste)
Coloque sua frase em uma lista (ou mais frases) e passe ela para o método vectorizer.transform(). Depois é só chamar o método predict()
no meu caso, o objeto que contém o modelo chama "modelo" então fica 'modelo.precict()'
Olá Rodrigo! Voce saberia se dentro da Biblioteca MultinomialNB existe algo em que retorne qual a probabilidade da frase ser classificada de acordo com as classes. Tipo, eu passo a frase a ser classificada, com isso ele iria retornar 70% de ser positivo, 20% negativo e 10% neutro. Algo desse tipo!
Olá Juliano, tudo beleza?
Existe sim, existe o método predict_proba() que retorna a probabilidade de cada classe usada na classificação.
Por exemplo, no nosso modelo, a classificação da frase abaixo é negativa, veja:
testes=['O governo é horrivel']
array(['Negativo'], dtype='<U8')
Agora podemos ver qual a probabilidade que o modelo das outras classes:
print (modelo.predict_proba(freq_testes))
array([[ 0.70998311, 0.15252104, 0.13749585]])
O comando retorna a probabilidade de ser da classe 'Negativo', 'Neutro' e 'Positivo'. Para ver a ordem, imprima as classes:
print (modelo.classes_)
Com o método predict_proba() podemos ver que a probabilidade da frase anterior ser negativa é de 70%. Se quiser retornar o percentual, multiplique isso por 100.
modelo.predict_proba(freq_testes)*100
array([[ 70.99831119, 15.25210354, 13.74958527]])
Espero que lhe seja útil Juliano. 😉
Olá Juliano, tudo beleza? Existe sim, existe o método predict_proba() que retorna a probabilidade de cada classe usada na classificação.
O comando retorna a probabilidade de ser da classe 'Negativo', 'Neutro' e 'Positivo'.
Para ver a ordem, imprima as classes:
Com o método predict_proba() podemos ver que a probabilidade da frase anterior ser negativa é de 70%. Se quiser retornar o percentual, multiplique isso por 100…
Legal, Rodrigo, fiz aqui e deu certinho, só que teve alguns casos que o retorno foi meio estranho, conforme a imagem que irei anexar, isso é normal mesmo? e o retorno é um array mesmo? mas sem ter posições né? https://uploads.disquscdn.com/images/9961a5d656a78771991cd30084de38332788ae960d5252df7955db297e0f6ca9.png
Isso mesmo Juliano, o retorno é um array.
A posição é a mesma da qual é exibida quando você imprime as classes:
É que estou tentando separar esse Array, para pegar apenas o que me interessa, que sera a porcentagem de qual foi classificada! ai quando tento utilizar o Split tenho o seguinte erro retornado AttributeError: 'numpy.ndarray' object has no attribute 'split'.
Olá Juliano, isso é tranquilo veja o exemplo:
Imagine que coloco o resultado do array na variável 'a'
a = modelo.predict_proba(freq_testes)*100
Agora para imprimir o valor da probabilidade da classe "Negativo" (seguindo a ordem natural do array) eu faço:
print (a[0][0])
Para pegar a probablidade da classe 'Neutro" :
print (a[0][1])
E para classe "Positivo":
print (a[0][2])
Olá Juliano, beleza amigo?
Não sei se você viu, mas escrevemos um E-book Gratuito para quem quer iniciar em Data Science e Python. Acredito que pode ser útil para você. Segue o link:http://bit.ly/2mqtM5y
Rodrigo, uma coisa que eu percebi é que sua base de dados já tem uma classificação, no meu caso que estou gerando a base do twitter com o R, como eu faço essa classificação na base?
Olá Juliano, tudo bem meu caro?
Essa base já possui as classes, pois, já foi rotulada anteriormente. A equipe que fez o crawler do twitter, rotulou as instâncias, ou seja, atribui as classes (positivo,negativo,neutro) manualmente em cada uma delas.
Com certeza é um trabalho cansativo, mas pelo menos uma parte do seu dado você precisará fazer isso, talvez 50% 🙂
Rodrigo, tudo bem? Como eu já tinha falado, uma parte do meu Trabalho de Graduação, entrara nessa analise de sentimentos da frase. Como não terei tempo hábil para classificar a base que estou pegando do twitter, queria saber se eu poderia estar utilizando a base que você disponibiliza aqui para fazer o treinamento do algorítimo? ai com isso a passarei a minha base para ser analisada pelo algorítimo que já aprendeu com a base que você disponibiliza?
Pode usar sim Juliano, segue o link e bons estudos 🙂
https://github.com/minerandodados/mdrepo/blob/master/Tweets_Mg.csv
Obrigado Rodrigo! Estarei utilizando essa base, unica coisa que meu orientador falou é de mencionar a origem dela. Teria a fonte dessa base classificada!
Me desculpe pelo monte de comentários hahahah 😉
Bacana Juliano, muito bom!
Quanto aos comentários, não foi nada. 🙂
Você teria a fonte correta da base, para que eu possa mencionar!
e Obrigado pelos auxílios!
Como disse no artigo, a base foi cedida pela equipe do projeto na época. Não tem uma fonte específica.
Abraço e bons estudos. 🙂
Muito legal a postagem, só achei o dataset meio difícil por conta do assunto tratado, é difícil achar mensagens classificadas como "Positivo", o que suja um pouco a análise.