Desde que o twitter liberou o histórico dos tweets antigos em formato CSV, procurei uma ferramenta para poder um tagcloud das minha palavras. Como o arquivo era muito grande (mais de 3 MB), as ferramentas online simplesmente travavam.
Procurando por alternativas, encontrei o pouco citado pytagcloud.
Então fiz o seguinte programa pra gerar o tagcloud dos meus tweets:
#! /usr/bin/pyhon
# -*- coding: utf-8 -*-
import re, csv
from pytagcloud import create_tag_image, make_tags
from pytagcloud.lang.counter import get_tag_counts
TWEETS = "tweets.csv"
buffer = ""
tws = csv.reader(open(TWEETS), delimiter=',', quotechar='"')
for rows in tws:
buffer += rows[5] + "\n"
output = "clound_large.png"
tags = make_tags(get_tag_counts(buffer), maxsize=120)
create_tag_image(tags,
output,
size=(800, 600),
fontname='Lobster')
Foi exatamente a cópia do programa documentado pelo próprio pytagcloud. Pra minha supresa, não funciona e sai o seguinte erro:
Traceback (most recent call last): File "generate_cloud.py", line 53, in File "/usr/local/lib/python2.7/dist-packages/pytagcloud/__init__.py", line 344, in create_tag_image File "/usr/local/lib/python2.7/dist-packages/pytagcloud/__init__.py", line 275, in _draw_cloud File "/usr/local/lib/python2.7/dist-packages/pytagcloud/__init__.py", line 62, in __init__ IOError: unable to read font filename Error in sys.excepthook: Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/apport_python_hook.py", line 66, in apport_excepthook ImportError: No module named fileutils Original exception was: Traceback (most recent call last): File "generate_cloud.py", line 53, in File "/usr/local/lib/python2.7/dist-packages/pytagcloud/__init__.py", line 344, in create_tag_image File "/usr/local/lib/python2.7/dist-packages/pytagcloud/__init__.py", line 275, in _draw_cloud File "/usr/local/lib/python2.7/dist-packages/pytagcloud/__init__.py", line 62, in __init__ IOError: unable to read font filename
Após muito mexer, pois o código exemplo, com texto menor, funciona perfeitamente, descobri que esse erro é gerado pela quantidade de palavras no arquivo de tweets. Consegui corrigir isso colocando um limite no tamanho dos tags, que é um array.
Em seguida me deparei com um problema de... codificação. Apesar de gerar o arquivo de imagem, as palavras que são originalmente utf-8 saem quebradas pois em algum lugar é usado iso-8859-1. Tentei utilizar o formato objeto.decode('utf-8').encode('latin-1') para recodificar o texto, mas o mesmo apresentava erro sempre. Fui descobrir que o causador era o danado do texto em árabe que postei no twitter pra sacanear o pessoal que usa Apple. Fiz uma conversão caractér a caractér e desconsiderei os que davam errado. Com isso terminei com o seguinte código:
#! /usr/bin/pyhon
# -*- coding: utf-8 -*-
import re, csv, sys
from pytagcloud import create_tag_image, make_tags
from pytagcloud.lang.counter import get_tag_counts
TWEETS = "tweets.csv"
LIMIT = int(sys.argv[-1])
buffer = ""
tws = csv.reader(open(TWEETS), delimiter=',', quotechar='"')
for rows in tws:
buffer += rows[5] + "\n"
buffer = re.sub("http://", "", buffer)
buffer = re.sub("https://", "", buffer)
buffer = re.sub("RT", "", buffer)
buffer = re.sub("mltp.ly/", "", buffer)
buffer = re.sub("bit.ly/", "", buffer)
buffer = re.sub("eri.cx/", "", buffer)
buffer = re.sub("via @addthis", " ", buffer)
buffer = re.sub("youtu.be/", "", buffer)
buffer = re.sub("twitthis.com/", "", buffer)
buffer = re.sub("t.co/", "", buffer)
buffer = re.sub("miud.in/", "", buffer)
buffer = re.sub("[,\. ](eu|da|do|de|com|to|tem|ter)[,\. ]", " ", buffer)
buffer = re.sub("[,\. ](mesmo|pelo|que|by|via|the|um|dos)[,\. ]", " ", buffer)
buffer = re.sub("[,\. ](é|to|tô|pra|para|muito|mto)[,\. ]", " ", buffer)
buffer = re.sub("[,\. ](em|vou|foi|as|us|me|I|you)[,\. ]", " ", buffer)
buffer = re.sub("[,\. ](para|pôr|is|esse|essa|isso|na)[,\. ]", " ", buffer)
buffer = re.sub("[,\. ](uma|um|ao|pelo|por|mais|com|eu)[,\. ]", " ", buffer)
buffer = re.sub("[,\. ](pra|quando|qdo|do|da|tb|também)[,\. ]", " ", buffer)
buffer = re.sub("[,\. ](isso|mas|meu|vc|in|on|so|of)[,\. ]", " ", buffer)
buffer = re.sub("[,\. ](end|for|esta|está|ter|at|ou)[,\. ]", " ", buffer)
buffer = re.sub("[,\. ](seu|sua|eu|and|so|sem|só)[,\. ]", " ", buffer)
text = ""
for c in buffer:
try:
a = c.decode('utf-8')
text += a.encode('iso-8859-1')
except:
pass
output = "clound_large_%d.png" % LIMIT
tags = make_tags(get_tag_counts(text), maxsize=120)
create_tag_image(tags[:LIMIT],
output,
size=(800, 600),
fontname='Lobster')
for i in xrange(LIMIT):
print i, tags[i]['tag'], tags[i]['size']
E assim gerei os tagclouds com limite de palavras mas sempre de mesmo tamanho. Os resultado foram esses:
10 palavras mais usadas
30 palavras mais usadas
50 palavras mais usadas
100 palavras mais usadas
200 palavras mais usadas
300 palavras mais usadas
400 palavras mais usadas
500 palavras mais usadas
Acima de 500 palavras, o pytagcloud cospe o famigerado erro. O engraçado é que com 500 palavras, o uso de espaço é melhor aproveitado que com 30.
E qual é o seu tagcloud?