Hands-on!

Nessa prática, sugerimos alguns pequenos exemplos para você implementar sobre o Spark.

Estimar o Pi

Existe um algoritmo para estimar o Pi com números radômicos. Implemente-o sobre o Spark.

Descrição do algoritmo: http://www.eveandersson.com/pi/monte-carlo-circle

Implementação EM PYTHON (não sobre o SPARK): http://www.stealthcopter.com/blog/2009/09/python-calculating-pi-using-random-numbers/

O númer de pontos deve ser 100000 (cem mill) vezes o número mínimo de partições padrão do seu SparkContext (sc.defaultMinPartitions). Esses pontos devem ser selecionados aleatóriamente na etapa de map (ver observações).

Observações: use as funções map (para mapear as ocorrêncas em 0 ou 1, significando 1 quando o ponto aleatório cair dentro do círculo e 0 quando o contrário) e reduce (para sumar as ocorrências).


In [19]:
from random import *
from math import sqrt
inside=0
n=1000
for i in range(0,n):
    x=random()
    y=random()
    if sqrt(x*x+y*y)<=1:
        inside+=1
pi=4*inside/n

print(pi)


3.164

In [26]:
from random import *
from math import sqrt
def soma(a,b): return a+b
def area(x,y):return 1 if sqrt(x*x+y*y)<=1 else  0
def mapfunction(z):
    x=random()
    y=random()
    return area(x,y)

In [27]:
nummin = sc.defaultMinPartitions * 10000
data = sc.parallelize(range(1, nummin))
res1 = data.map(mapfunction)

In [28]:
print(res1.reduce(soma))


15767

In [30]:
pispark = 4*(res1.reduce(soma))/(res1.count())
print(pispark)


3.153557677883894

Filtragem de Primos

Dado uma sequência de números de 1 a 1000000, filtre somente os primos dessa sequência.


In [1]:
def primes( n ):
# i sera nosso divisor inicial
    i = 1;
# j sera nosso contador de ocorrências
    j = 0;
#Nenhum numero real vai ser divisivel por um numero maior do que sua metade
    n1 = (n/2);

    while (i <= n):

       if (n % i==0):
          i = i+1;
          j = j+1;

       if (i>=n1):
        # damos a i, o valor da variavel entrada, pois o próximo divisor sera o próprio número
          i = n;
          i = i+1;
          j = j+1;

       else:
          i = i+1;
    if(j==2):
        return True
    else: 
        return False

In [2]:
data = sc.parallelize(range(1, 1000000))
res = data.filter(primes)
print(res.take(100))


[1, 2, 3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521]

Municípios do Brasil

Dado o dataset mucipios_do_Brasil.csv, faça duas operações com ele:

  1. Monte uma lista dos municípios por estado.
  2. Conte quantos municípios há em cada estado.

Dicas: use as operações groupByKey e reduceByKey, não faça um count na lista da operação 1.


In [1]:
def mapfun(x):
    return [x[0],x[1]]

In [2]:
lines = sc.textFile("municipios_do_Brasil.csv")

data = lines.map(lambda line: line.split(",")).map(mapfun)

print(data.take(10))


[['uf', 'cidade'], ['AC', 'Acrelândia'], ['AC', 'Assis Brasil'], ['AC', 'Brasiléia'], ['AC', 'Bujari'], ['AC', 'Capixaba'], ['AC', 'Cruzeiro do Sul'], ['AC', 'Epitaciolândia'], ['AC', 'Feijó'], ['AC', 'Jordão']]

In [3]:
data.sortByKey()
print(data.take(20))


[['uf', 'cidade'], ['AC', 'Acrelândia'], ['AC', 'Assis Brasil'], ['AC', 'Brasiléia'], ['AC', 'Bujari'], ['AC', 'Capixaba'], ['AC', 'Cruzeiro do Sul'], ['AC', 'Epitaciolândia'], ['AC', 'Feijó'], ['AC', 'Jordão'], ['AC', 'Mâncio Lima'], ['AC', 'Manoel Urbano'], ['AC', 'Marechal Thaumaturgo'], ['AC', 'Plácido de Castro'], ['AC', 'Porto Acre'], ['AC', 'Porto Walter'], ['AC', 'Rio Branco'], ['AC', 'Rodrigues Alves'], ['AC', 'Santa Rosa do Purus'], ['AC', 'Sena Madureira']]

In [4]:
Counts = data.groupByKey().map(lambda x : (x[0], list(x[1])))
print(Counts.take(1))


[('AC', ['Acrelândia', 'Assis Brasil', 'Brasiléia', 'Bujari', 'Capixaba', 'Cruzeiro do Sul', 'Epitaciolândia', 'Feijó', 'Jordão', 'Mâncio Lima', 'Manoel Urbano', 'Marechal Thaumaturgo', 'Plácido de Castro', 'Porto Acre', 'Porto Walter', 'Rio Branco', 'Rodrigues Alves', 'Santa Rosa do Purus', 'Sena Madureira', 'Senador Guiomard', 'Tarauacá', 'Xapuri'])]

In [7]:
new = Counts.map(lambda tup: (tup[0], len(tup[1])))
print(new.take(4))


[('AC', 22), ('AP', 16), ('BA', 417), ('CE', 184)]

Word Count Memória Postumas de Brás Cubas

Memórias Póstumas de Brás Cubas é um romance escrito por Machado de Assis, desenvolvido em princípio como folhetim, de março a dezembro de 1880, na Revista Brasileira, para, no ano seguinte, ser publicado como livro, pela então Tipografia Nacional.

A obra retrata a escravidão, as classes sociais, o cientificismo e o positivismo da época. Dada essas informações, será que conseguimos idenficar essas características pelas palavras mais utilizadas em sua obra?

Utilizando o dataset Machado-de-Assis-Memorias-Postumas.txt, faça um word count e encontre as palavras mais utilizadas por Machado de Assis em sua obra. Não esqueça de utilizar stopwords.pt para remover as stop words!


In [10]:
def filterfun(w):
    stopwords = set(open('stopwords.pt').read().split())
    if w[0] in stopwords:
        return False
    else:
        return True

In [15]:
text_file = sc.textFile("Machado-de-Assis-Memorias-Postumas.txt")

counts = text_file.flatMap(lambda line: line.split(" ")) \
             .map(lambda word: (word, 1)) \
             .reduceByKey(lambda a, b: a + b)
counts = counts.filter(filterfun)
counts = counts.takeOrdered(100, key = lambda x: -x[1])

In [16]:
print(counts)


[('—', 723), ('', 303), ('Não', 210), ('O', 165), ('A', 163), ('lhe', 159), ('CAPÍTULO', 145), ('E', 117), ('Virgília', 109), ('olhos', 101), ('D.', 85), ('alguma', 81), ('Era', 76), ('Mas', 75), ('que,', 66), ('Quincas', 65), ('homem', 63), ('ia', 60), ('Que', 59), ('podia', 58), ('dizer', 57), ('Um', 55), ('Eu', 52), ('Lobo', 52), ('sei', 51), ('fui', 50), ('e,', 49), ('meus', 47), ('dizia', 47), ('logo', 47), ('algum', 45), ('mim', 45), ('idéia', 45), ('isto', 44), ('olhar', 44), ('eram', 44), ('lá', 43), ('talvez', 43), ('nossa', 41), ('Virgília,', 41), ('mão', 40), ('coisas', 40), ('fosse', 40), ('certo', 39), ('modo', 38), ('eu,', 38), ('No', 38), ('te', 37), ('tal', 37), ('tempo,', 36), ('Meu', 35), ('nada.', 35), ('depois,', 35), ('De', 35), ('ver', 35), ('pai', 34), ('Ao', 33), ('ir', 33), ('uns', 33), ('simples', 33), ('si', 32), ('algumas', 32), ('aí', 31), ('Talvez', 31), ('mim,', 31), ('Marcela', 31), ('É', 30), ('certa', 30), ('morte', 29), ('pé', 29), ('Se', 29), ('capítulo', 29), ('Brás', 28), ('anos,', 28), ('nosso', 28), ('Borba', 28), ('casa,', 28), ('muitas', 27), ('ele,', 27), ('filha', 27), ('Uma', 27), ('Já', 27), ('digo', 26), ('pai,', 26), ('boa', 26), ('disse-me', 26), ('porém,', 26), ('gesto', 26), ('Plácida', 26), ('verdade,', 25), ('Pois', 25), ('ali', 25), ('muito,', 25), ('porta', 25), ('homem,', 25), ('muita', 25), ('tu', 25), ('nunca', 25), ('coisa,', 25), ('nenhum', 24)]

É dificil deduzir sobre o que o livro baseado apenas nas suas palavras. As palavras nos permitem deduzir que se trata de um livro(a palavra capítulo aparece no top 10), podemos também deduzir o nome de alguns personagens importantes como Quincas, Virgília, Brás e Marcela