Skip to main content
letreiro brilhante embaixo de uma janela

Mineração de texto: python para descobrir emoções

O que as pessoas pensam sobre a sua empresa, ou sobre a empresa que você trabalha?

Há um tempo, comecei a estudar um conteúdo dentro do aprendizado de máquina conhecido com mineração de texto — ou mineração de emoções. Este campo tenta identificar emoções em texto.

Por exemplo: hoje estou feliz.

Quem for ler esta frase perceberá que trata-se de uma frase de alegria, entretanto como fazer o computador entender que esta frase é uma frase de felicidade?

A resposta é mais ou menos simples: utilizando o aprendizado de máquina. Essa pergunta tem um peso ainda maior quando falamos do mundo corporativo.

Imagina escanear a reação de um montante grande de pessoas e, com isso, acelerar uma tomada de decisão, como uma automação, que tem uma influência direta sobre o business?

Ou sobre o customer success.

Bem, hoje nós falaremos sobre como usar a mineração de emoção, por meio de texto e utilizando a linguagem Python.  

Vamos lá? 🙂

Mineração de emoções nas redes sociais

Se pararmos para pensar as pessoas nunca se comunicaram tanto por redes sociais como hoje. Seja facebook, Twitter, Instagram entre outras redes sociais.

As pessoas demonstram seus sentimentos e suas vontades via redes sociais.

Então, poderíamos usar como ‘termômetro’ para saber se nossa empresa está sendo bem falada ou não estas redes sociais. Certo?  

Um bom começo para nosso estudo será o Twitter, já que o mesmo dispõe de uma API para desenvolvedores para coletar tweets, a chamada tweepy.

Sim, esta biblioteca está disponível para Python, que será a linguagem utilizada no meu exemplo, como já adiantei.

Imagine o seguinte cenário. Trabalhamos em uma empresa que produz “capinha de celular” e desejamos saber o que as pessoas comentam sobre nossos produtos.

Com isso podemos criar uma campanha de marketing para lançar um produto novo, ou detectar alguma falha já existente e corrigi-la.

Mas como catalogar emoções?

Segundo o psicólogo Paul Ekman existem seis tipos de emoções básicas que são:

  1. Surpresa
  2. Alegria
  3. Tristeza
  4. Medo
  5. Desgosto ou nojo
  6. Raiva

Porém, para o nosso caso decidimos catalogar as frases em duas emoções que são: alegria e raiva.

Se uma frase for de alegria, para nós, significa, que a pessoa está feliz com o produto. Mas, se uma frase for de raiva significa que a pessoa está descontente com nosso produto.

Mineração de texto usando python na prática

Para fins didáticos separei em seções os passos da construção do algoritmo de machine learning para que possamos classificar as frases como sendo de alegria, ou de raiva.

Imagine que já coletamos os tweets e agora partiremos para o pré-processamento das nossas frases coletadas.

banco=[{‘ Está capa de celular é o máximo’,’alegria’},
{“Perdi meu dinheiro comprando esta capa de celular”,”raiva”},
{“Amei esta capinha”,”alegria”},
{“PQP estragou na primeira semana”,”Raiva”},
{“Parece um celular novo mas é apenas a capinha hahahaha”,”alegria”}]

Usaremos este banco de dados com apenas cinco frases para o entendimento ficar mais claro, porém a lógica será a mesma para uma quantidade maior de frases.

O “pulo do gato” é mapear a maior quantidade de frases similares entre si, que expressam esses dois sentimentos.

Pré-processamento

Em qualquer idioma existem palavras que não agregam muito sentido a frases como por exemplo: “a”, “as”, “e”, “de”, “das” e etc… essas palavras na biblioteca nltk* são conhecidas como StopWords.

Então, sim, estas palavras podem gerar algum tipo de ruído indesejável para nossas análises posteriores.

*conjunto de bibliotecas para PLN (processamento de linguagem natural simbólica e estatística) em Python

Outra coisa que podemos fazer nesta mesma etapa é retirar o sufixo e o prefixo das palavras e ficar apenas com seu radical. Observe as palavras:

Carro

Carrinho

Carrão

As três palavras dizem respeito a algum tipo de carro, então o que podemos fazer é retirar o sufixo da palavra e ficar apenas com seu radical.

Isto é, carr.

Iremos fazer isso com todas as nossas palavras, porém, ao fazermos isso, podemos perder um pouco de informação.

Isso quer dizer que retirar uma Stopword, sufixo e prefixo tem um certo custo e devemos analisar se vale a pena ou não fazer esse processo.

Criando o algoritmo de mineração de texto

Vamos voltar à biblioteca nltk:

import nltk
stopwords=nltk.corpus.stopwords.words(‘portuguese’)

Esse pacote contém radicais de várias línguas assim como Stopwords, e o que rola é que elas variam de língua para língua, então precisamos referenciar o português na segunda linha

Agora criaremos a função que faz o processamento que falamos anteriormente:

def fazstemmer(texto):
   stemmer=nltk.stem.RSLPStemmer()
   frasessteming=[]
   for (palavras,emocao) in texto:
       comsteming=[str(stemmer.stem(p)) for p in palavras.split() if p not in stopwords]
       frasessteming.append((comsteming,emocao))
   return frasessteming

E como resultado temos o seguinte :

[([‘est’, ‘cap’, ‘celul’, ‘máx’], ‘alegria’), ([‘perd’, ‘dinh’, ‘compr’, ‘cap’, ‘celul’], ‘raiva’), ([‘ame’, ‘cap’], ‘alegria’), ([‘pqp’, ‘estrag’, ‘prim’, ‘seman’], ‘Raiva’), ([‘parec’, ‘celul’, ‘nov’, ‘apen’, ‘cap’, ‘hahahah’], ‘alegria’)]

Perceba acima, por exemplo, a primeira frase que era:

“Está capa de celular é o máximo”

…que na função ficou:

“est cap celul máx”

Mas, perceba que as frases estão organizadas em duplas contendo a frase e a emoção, então o que faremos agora é uma função que organiza somente as palavras em uma lista:

def buscadordepalavras(frases):
   total_palavras=[]
   for (palavras,emocao) in frases:
       total_palavras.extend(palavras)
   return total_palavras

E como resultado teremos a seguinte lista:

[‘hoj’, ‘acord’, ‘feliz’, ‘acord’, ‘lad’, ‘esquerd’, ‘cam’, ‘tiv’, ‘boa’, ‘noit’, ‘son’, ‘hoj’, ‘sai’, ‘frent’, ‘,ag’]

Iremos agora calcular a frequência das palavras usando a biblioteca nltk:

def buscafrequencia(palavras):
   palavras= nltk.FreqDist(palavras)
   return palavras

E teremos como resposta o seguinte:

<FreqDist with 15 samples and 19 outcomes>

A resposta acima nos diz que em nossa lista há 19 palavras e 15 palavras únicas, ou seja, em nossa lista há quatro palavras que se repetem.

Então, nosso objetivo é excluir da lista as quatro palavras que se repetem para criarmos nossa lista de palavras únicas:

def buscapalavrasunicas(frequencia):
   freq= frequencia.keys()
   return freq

E o resultado desta função será:

dict_keys([‘est’, ‘cap’, ‘celul’, ‘máx’, ‘perd’, ‘dinh’, ‘compr’, ‘pqp’, ‘estrag’, ‘prim’, ‘seman’, ‘parec’, ‘nov’, ‘apen’, ‘hahahah’])  

Agora utilizaremos uma função chamada extraipalavras.

O objetivo desta função é classificá-las como True,se estiverem dentro da nossa lista de palavras únicas, ou False se ela não está em nossa lista de palavras únicas.

def extraipalavras(documento):
   doc=set(documento)
   caracteristicas={}
   for palavras in palavras_unicas:
       caracteristicas[‘%s’%palavras]= (palavras in doc)
   return caracteristicas

Exemplo:

print(extrairpalavras([‘hoj”feliz’,’ont’,’est’,’prim’]))
{‘est’: True, ‘cap’: False, ‘celul’: False, ‘máx’: False, ‘perd’: False, ‘dinh’: False, ‘compr’: False, ‘pqp’: False, ‘estrag’: False, ‘prim’: True, ‘seman’: False, ‘parec’: False, ‘nov’: False, ‘apen’: False, ‘hahahah’: False}

A função extraipalavras fez a seguinte comparação:

As palavras que estão em nossa lista de palavras únicas foram classificadas como True e as que não estão em nossa lista de palavras únicas foram classificadas como False.

Agora chamaremos uma função da biblioteca nltk passando como parâmetros a função extraipalavras e nossas frases já processadas:

nossa_base= nltk.classify.apply_features(extraipalavras,stemmer)
print(nossa_base)

E como resultado teremos:  

({‘est’: False, ‘cap’: False, ‘celul’: False, ‘máx’: False, ‘perd’: False, ‘dinh’: False, ‘compr’: False, ‘pqp’: True, ‘estrag’: True, ‘prim’: True, ‘seman’: True, ‘parec’: False, ‘nov’: False, ‘apen’: False, ‘hahahah’: False}, ‘Raiva’)

Está função retorna às nossas frases mostrando quais palavras estão contidas ou não nas frases.

Neste exemplo temos a frase “PQP estrag prim seman” e são estas palavras que aparecem como True.

Adicionando novas frases ao algoritmo de mineração

Agora iremos testar nosso algoritmo com uma nova frase:

teste= “Nunca mais compro essa capinha de celular”

Para fazer a adição, chamaremos as funções que criamos anteriormente:

frase_nova=[]
stemmer=nltk.stem.RSLPStemmer()
for (palavras) in teste.split():
       comstem=[p for p in palavras.split()]
       frase_nova.append(str(stemmer.stem(comstem[0])))
print(frase_nova)

novo=extraipalavras(frase_nova)

print(classificador.classify(novo))
distribuicao=classificador.prob_classify(novo)
for classe in distribuicao.samples():
   print(“%r: %.2f” %(classe,distribuicao.prob(classe)*100))

E como resultado teremos:

[‘nunc’, ‘mais’, ‘compr’, ‘ess’, ‘cap’, ‘de’, ‘celul’]
raiva
‘alegria’: 48.08
‘raiva’: 51.92

A primeira linha mostra as palavras da frase processada e abaixo a probabilidade de a frase ser de alegria ou de raiva. Você vê que ‘raiva’ venceu pela probabilidade, com base nos aprendizados anteriores do algoritmo.

Próximos passos

Agora que construímos um algoritmo podemos fazer coletas semanais por uma ou duas horas, classificá-las e, com isso, podemos fazer desde uma simples contagem do tipo das frases que coletamos.

Isto é, podemos ver quantas são de alegria e quantas são de raiva. Também podemos aplicar outras métricas próprias da empresa.

Podemos também criar grupos do porquê as pessoas sentem raiva do nosso produto e fazer uma outra mineração para clusterizar as frases de raiva, atacando os problemas que são mais recorrentes.

Enfim, a partir daqui as possibilidades são infinitas. Espero ter ajudado a sua empresa! 🙂



Mineração de texto: python para descobrir emoções
4 (80%) 6 votes