Deputado Histogramado

expressao.xyz/deputado/

Como processar as sessões do parlamento Português

O que se passou nas mais de 4000 sessões de discussão do parlamento Português que ocorreram desde 1976? Neste notebook vamos tentar visualizar o que se passou da maneira mais simples - contando palavras, e fazendo gráficos.

Para obter os textos de todas as sessões usaremos o demo.cratica.org, onde podemos aceder facilmente a todas as sessões do parlamento de 1976 a 2015. Depois com um pouco de python, pandas e matplotlib vamos analisar o que se passou.

Para executar estes notebook será necessário descarregar e abrir com o Jupiter Notebooks (a distribuição Anaconda faz com que instalar todas as ferramentas necessárias seja fácil - https://www.continuum.io/downloads)

Parte 3 - Simplificar o dataset e exportar

Código para carregar os dados do notebook anterior:


In [1]:
%matplotlib inline
import pylab
import matplotlib
import pandas
import numpy


dateparse = lambda x: pandas.datetime.strptime(x, '%Y-%m-%d')
sessoes = pandas.read_csv('sessoes_democratica_org.csv',index_col=0,parse_dates=['data'], date_parser=dateparse)

In [2]:
del sessoes['tamanho']

In [3]:
total0 = numpy.sum(sessoes['sessao'].map(len))
print(total0)


799561050

Temos ~800 MB de dados. O servidor onde o backend do site vai funcionar apenas têm 1GB de memória, o que cria um desafio técnico. Como a útilidade do site é apenas contar palavras ou expressões que ocorrem mais em certas sessões, e não em todas as sessões ('enfermeiro' vs 'deputado'), podemos retirar essas palavras mais usuais:


In [4]:
def substitui_palavras_comuns(texto):
    t = texto.replace('.',' ').replace('\n',' ').replace(',',' ').replace(')',' ').replace('(',' ').replace('!',' ').replace('?',' ').replace(':',' ').replace(';',' ')
    t = t.replace(' de ',' ').replace(' que ',' ').replace(' do ',' ').replace(' da ',' ').replace(' sr ',' ').replace(' não ',' ').replace(' em ',' ').replace(' se ','').replace(' para',' ').replace(' os ',' ').replace(' dos ',' ').replace(' uma ',' ').replace(' um ',' ').replace(' as ',' ').replace(' dos ',' ').replace(' no ',' ').replace(' dos ',' ').replace('presidente','').replace(' na ',' ').replace(' por ','').replace('presidente','').replace(' com ',' ').replace(' ao ',' ').replace('deputado','').replace(' das ',' ').replace(' como ','').replace('governo','').replace(' ou ','').replace(' mais ',' ').replace(' assembleia ','').replace(' ser ',' ').replace(' tem ',' ')
    t = t.replace(' srs ','').replace(' pelo ','').replace(' mas ','').replace(' foi ','').replace('srs.','').replace('palavra','').replace(' que ','').replace(' sua ','').replace(' artigo ','').replace(' nos ','').replace(' eu ','').replace('muito','').replace('sobre ','').replace('também','').replace('proposta','').replace(' aos ',' ').replace(' esta ',' ').replace(' já ',' ')
    t = t.replace(' vamos ',' ').replace(' nesta ',' ').replace(' lhe ',' ').replace(' meu ',' ').replace(' eu ',' ').replace(' vai ',' ')
    t = t.replace(' isso ',' ').replace(' dia ',' ').replace(' discussão ',' ').replace(' dizer ',' ').replace(' seus ',' ').replace(' apenas ',' ').replace(' agora ',' ')
    t = t.replace(' ª ',' ').replace(' foram ',' ').replace(' pois ',' ').replace(' nem ',' ').replace(' suas ',' ').replace(' deste ',' ').replace(' quer ',' ').replace(' desta ',' ').replace(' qual ',' ')
    t = t.replace(' o ',' ').replace(' a ',' ').replace(' e ',' ').replace(' é ',' ').replace(' à ',' ').replace(' s ',' ')
    t = t.replace(' - ','').replace(' º ',' ').replace(' n ',' ').replace(' . ',' ').replace(' são ',' ').replace(' está ',' ').replace(' seu ',' ').replace(' há ',' ').replace('orador',' ').replace(' este ',' ').replace(' pela ',' ').replace(' bem ',' ').replace(' nós ',' ').replace('porque','').replace('aqui','').replace(' às ',' ').replace('ainda','').replace('todos','').replace(' só ',' ').replace('fazer',' ').replace(' sem ',' ').replace(' qualquer ',' ').replace(' quanto ',' ').replace(' pode ',' ').replace(' nosso ',' ').replace(' neste ',' ').replace(' ter ',' ').replace(' mesmo ',' ').replace(' essa ',' ').replace(' até ',' ').replace(' me ',' ').replace(' nossa ',' ').replace(' entre ',' ').replace(' nas ',' ').replace(' esse ',' ').replace(' será ',' ').replace(' isto ',' ').replace(' quando ',' ').replace(' seja ',' ').replace(' assim ',' ').replace(' quanto ',' ').replace(' pode ',' ').replace(' é ',' ')
    t = t.replace('  ',' ').replace('  ',' ').replace('  ',' ')
    return t


sessoes['sessao'] = sessoes['sessao'].map(substitui_palavras_comuns)

Fazendo uma contagem ás palavras mais frequentes que ainda restam:


In [5]:
import re
from collections import Counter

def agrupa_palavras(texto):
    texto = texto.lower() #processa tudo em minusculas
    palavras = re.split(';|,|\n| |\(|\)|\?|\!|:',texto)   # separa as palavras
    palavras = [x.title() for x in palavras if len(x)>0] # organiza e remove as palavras com menos de 5 caracteres
    return palavras

def conta_palavras(sessoes):
    lista = sessoes['sessao'].map(agrupa_palavras)  # cria uma lista de 'lista de palavras', um elemento por sessao
    palavras = []
    for l in lista:
        palavras.extend(l)                          # junta as 'listas de palavras' todas na mesma lista
    return Counter(palavras).most_common(100)        # conta as palavras mais frequentes

x = conta_palavras(sessoes[1:100])
for (y,z) in x:
    print(str(str(z)+' x '+y))


6928 x José
6283 x Ps
6205 x Partido
6156 x Manuel
5939 x Cds
5897 x António
5831 x Trabalhadores
5136 x Comissão
5131 x Psd
5130 x Pcp
5108 x Lei
4173 x Constituição
3837 x Política
3227 x Contra
3219 x Moreira
3154 x Estado
2953 x País
2940 x Carlos
2923 x Costa
2828 x Povo
2751 x Vital
2707 x Voto
2590 x Votação
2568 x Luís
2530 x Parlamentar
2444 x Direito
2425 x Trabalho
2423 x Português
2378 x Udp
2365 x Nacional
2330 x República
2329 x Portanto
2274 x Decreto-Lei
2271 x Problema
2265 x Socialista
2264 x Ordem
2260 x Nunes
2241 x Social
2236 x Portugal
2226 x Parte
2206 x Sentido
2201 x Grupo
2190 x Francisco
2168 x Caso
2145 x Regimento
2102 x Outros
2086 x Programa
2082 x Mesa
2066 x Carvalho
2065 x Plano
2063 x Ministro
2055 x Facto
2046 x Projecto
2024 x Silva
2020 x Seguinte
2005 x Sessão
2002 x Esclarecimento
1992 x Relação
1989 x Intervenção
1944 x Era
1942 x Tempo
1913 x Antes
1909 x Lugar
1900 x Vozes
1891 x Têm
1887 x Questão
1884 x Outro
1865 x Forma
1850 x Sousa
1849 x Pelos
1846 x Democracia
1836 x Matéria
1828 x Almeida
1828 x Estão
1815 x Sido
1811 x Pereira
1800 x Debate
1797 x Medidas
1795 x Poder
1784 x Momento
1757 x Vez
1737 x Maria
1728 x Conselho
1726 x Situação
1718 x Hoje
1694 x Dias
1686 x Partidos
1673 x Ele
1672 x Oliveira
1667 x 25
1663 x João
1656 x Pedido
1638 x Jorge
1626 x Correia
1618 x Favor
1614 x Aplausos
1613 x Acácio
1600 x Alguns
1589 x Horas
1588 x Termos

In [ ]:

E estimando a redução de tamanho:


In [6]:
total = numpy.sum(sessoes['sessao'].map(len))
print(str(total/total0*100)+' %')
print(total)


67.03995185858541 %
536025343

536 MB. Nada mau. Graças a esta redução tornou-se possível fazer uma query do site funcionar em ~4 seg em vez de 30 seg pois agora os dados cabem na memória. De notar que a ordem das palavras é a mesma, mas geram-se alguns problemas contando certas expressões ('porto de mar' é agora 'porto mar', e contando 'porto mar' tambem se contam ocorrencias de '(...)Porto. Mar(...)', pois retiramos os pontos e reduzimos os espaços consecutivos a um único. Mesmo assim, o dataset é perfeitamente útil para identificar em que sessões se falou de um certo assunto.

Exportemos entao o ficheiro CSV que vai ser usado no site:


In [7]:
sessoes.to_csv('sessoes_democratica_clipped.csv')

In [ ]: