LIMPANDO DADOS - UM EXEMPLO COM TWITTER

a Coleta de dados envolve a sua limpeza para posterior pré-processamento (enriquecimento).

Há quem coloque limpeza em pré-processamento, mas tanto faz onde se coloca ..precisa ser feito ..senão entramos em 'garbage in, garbage out'

Uma limpeza eficaz pode permitir que até dados muito ruidosos se tornem úteis e tragam algum conhecimento.

Este exemplo exibe os principais passos na limpeza de dados em fontes altamente desestruturadas -- mídias sociais.

vejamos a nossa twitada candidato:


In [93]:
orig_twit = "I luv my <3 iphone & it's great!! you're awsm apple. DisplayIsAwesome, sooo happppppy :) http://www.apple.com"

print orig_twit


I luv my <3 iphone & it's great!! you're awsm apple. DisplayIsAwesome, sooo happppppy :) http://www.apple.com



Maravilha, né?

Vamos ao trabalho.

1 - DECODIFICANDO

Texto pode estar em diferentes formatos de codificação -- como "Latin-1" ou 'UTF-8", etc. Assim, para podermos melor analisar é necessário manter todos os dados em algum formato padrão.

UTF-8 é bastante popular e recomendado.


In [75]:
twit = orig_twit.decode("utf8").encode('ascii','ignore')

print twit


I luv my <3 iphone & it's great!! you're awsm apple. DisplayIsAwesome, sooo happppppy :) http://www.apple.com



2 - LIMPANDO HTML

Dados obtidos da web geralmente contém entidades em HTML, como < &amp e etc. que ficam entranhados nos nossos dados.

Podemos tirar estes com uso de expressões regulares sem muito esforço, mas no python por sorte há módulos que podem converter estas entidades em tags HTML normais.


In [76]:
import HTMLParser

html_parser = HTMLParser.HTMLParser()

twit = html_parser.unescape(twit)

print twit


I luv my <3 iphone & it's great!! you're awsm apple. DisplayIsAwesome, sooo happppppy :) http://www.apple.com



3 - APOSTROFES E CONTRAÇÕES

Se estivermos lidando com inglês (que permeia a web) uma boa estratégia é extrair as formas completas das contrações. Isso porém requer alguma desambiguação,que não veremos neste exemplo (e.g. it's vira 'it is' ou 'it has'?).


In [77]:
## Dicionario enorme
APPOSTOPHES = {u"'s" : u" is", u"'re" : u" are"}

words = twit.split()

for pattern in APPOSTOPHES:
    for idx,word in enumerate(words):
        if pattern in word:
            tokens = word.split(pattern)
            words[idx] = tokens[0] + APPOSTOPHES[pattern]

reformed = " ".join(words)

print reformed


I luv my <3 iphone & it is great!! you are awsm apple. DisplayIsAwesome, sooo happppppy :) http://www.apple.com



4 - REMOVER STOP-WORDS

Quando a análise é (estritamente) estatística, devemos considerar a remoção das chamadas STOP-WORDS.

STOP-WORDS são palavras frequentes que ocorrem em quase qualquer texto, quase qualquer frase, e.g. 'e', 'de', 'para', artigos, etc.

5 - REMOVER PONTUAÇÃO

Todas as pontuações devem ser tratadas (removidas, uniformizadas, ou ao menos identificadas e classificadas). Os principais delimitadores ('.';',';'?') devem ser retidos.

6 - REMOVER EXPRESSÕES

Comunicação textual em mídias sociais frequentemente exibe descrições de sentimento [chorando], [rindo], LOL, e etc.

Dependendo do objetivo da sua análise, estas expressões não são úteis e devem ser removidas. Neste caso expressões regulares voltam a ser a principal ferramenta.

7 - PARTIR PALAVRAS

Novamente, texto digitado de forma casual e informal não seguem muitas regras, assim é comum a ocorrência de palavras e expressões (incluindo hashtags) não serem divididas por espaço. Algumas regras simples de regex podem aliviar o problema.


In [80]:
import re

cleaned = " ".join(re.findall('[A-Z][^A-Z]*', reformed))

print cleaned


I luv my <3 iphone & it is great!! you are awsm apple.  Display Is Awesome, sooo happppppy :) http://www.apple.com



8 - GÍRIAS

Se tivermos acesso a algum léxico (seja ele formal ou de gírias) podemos montar um dicionário normalizador -- há recursos para normalizar gírias em Inglês, porém nunca encontrei algum específico para Português.


In [85]:
slang_norm = {
    'luv':'love',
    'awsm':'awesome',
    # em tese teriamos um dicionario enorme!
}

tokens = cleaned.split()

real_words = [slang_norm[token.lower()] if slang_norm.get(token) else token for token in tokens ]

real_words = ' '.join(real_words)

print real_words


I love my <3 iphone & it is great!! you are awesome apple. Display Is Awesome, sooo happppppy :) http://www.apple.com

9 - PADRONIZAÇÃO

Para tornar palavras passíveis de análise, é necessário algum tipo de padronização i.e. 'adddoroooooo' deveria ser 'adoro'.

Regras simples utilizando deduplicação de caracteres podem ser um ótimo passo inicial:


In [94]:
from itertools import groupby 

# notem que o 'soo' permanece duplicado ..a heuristice é útil 
# mas não resolve o problema todo!
twit_final = ''.join(''.join(s)[:2] for _, s in groupby(real_words))

print twit_final


I love my <3 iphone & it is great!! you are awesome apple. Display Is Awesome, soo happy :) http://ww.apple.com



Este problema se torna mais fácil em Português, uma vez que não temos (que eu saiba!) palavras com a mesma letra duplicada e.g. 'soon', 'moon','reek'.



Estes são os principais passos a serem considerados durante a limpeza de dados textuais.

Esta lista não é abrangente, mas busca dar visão sobre os desafios a serem encontrados

OBS: Vale ressaltar que nenhum destes passos é um requerimento. A natureza da tarefa sendo abordada ditará, primeiramente, o que deve ou não ser feito para alcançar algum resultado desejável de análise. "A ferramenta certa para o trabalho certo"


In [ ]: