O documento apresenta o framework Apache Spark para pré-processamento de grandes dados, abordando conceitos como RDDs, DataFrames, UDFs e a biblioteca Spark ML. É demonstrado um estudo de caso completo de pré-processamento de um conjunto de dados de reviews da Amazon contendo 82 milhões de registros.
Pré processamento de grandes dados com Apache Spark
1. Pré-processamento de
Grandes Dados com Apache
Spark
Rio Big Data Meetup - Novembro 2015
Felipe Almeida (falmeida1988@gmail.com | http://queirozf.com)
https://github.com/queirozfcom/rio-big-data-meetup-nov-2015
2. Estrutura da palestra
● Introdução
● O problema
● Spark
● Spark Dataframes
● Spark UDFs
● Spark ml
● Estudo de caso
2/28
3. Introdução
● Tarefas de mineração de dados e aprendizado de máquina só são
possíveis após uma etapa de pré-processamento.
● Pergunta: como pré-processar dados da ordem de muitos GB ou
TB?
● Hadoop e Spark
● As versões recentes do Spark adicionaram recursos úteis para
essas tarefas.
3/28
4. O problema
● Vamos tratar especificamente do problema de extração de
features
○ Isto é, transformar uma massa de dados em um conjunto de
dados onde cada amostra é representada por um vetor de
features
4/28
5. Spark
● Framework para computação em cluster, feito em Scala.
● Nasceu para resolver dois problemas do Hadoop:
○ Necessidade de persistir em disco após cada job
○ Difícil utilização para tarefas interativas
● Abstração principal: RDD
○ Um dataset distribuído nos nós do cluster
● Suporta várias operações além das famosas map e reduce
5/28
6. Spark
6/28
carrega um arquivo texto do HDFS
cada linha é transformada em uma lista de
palavras
exemplo de programa Spark usando Python (wordcount)
cada palavra é transformada em uma tupla
(palavra,1)
os pares com a mesma chave (i.e. mesma palavra) são
agrupados e somados
7. Spark DataFrames
● O módulo spark-sql adicionou o conceito de DataFrames
○ Como usado na linguagem R ou na biblioteca pandas (Python)
● Um DataFrame é comumente utilizado para representar um
dataset:
○ Linhas representam cada amostra (ponto)
○ Colunas representam cada feature
● Também é um RDD
○ Do tipo RDD[sql.Row]
○ Suporta também todas as operações de RDD
7/28
9. Spark DataFrames
// dataframes moram neste módulo
import org.apache.spark.sql._
// construindo um sqlcontext a partir do sparkcontext
val sqlContext = new SQLContext(sc)
// carregando dados do S3 (schema inferido automaticamente)
val df = sqlContext.read.json("s3://path/to/dataset")
// select from dataframe where overall > 4.0
df.where(df("overall") > 4.0)
9/28
11. Spark DataFrames - transformações
Exemplo: tokenização (separar texto em tokens)
DataFrame original DataFrame modificado
11/28
feature #1
amostra #1 “olá mundo!!”
amostra #2 “spark para grandes
dados”
amostra #3 “usando spark”
aplicação da
transformação
de tokenização
feature #1’
amostra #1 [“olá”, “mundo”]
amostra #2 [“spark”, “para”,
“grandes”, “dados”]
amostra #3 [“usando”,”spark”]
12. Spark UDFs
● UDFs: User-defined functions
○ São funções que atuam sobre uma coluna de um DataFrame
● Note a diferença com relações a funções como filter, map,
reduce que atuam sobre uma linha de um DataFrame
12/28
13. Spark UDFs
● UDFs podem ser usadas para criar colunas em um DataFrame:
import org.apache.spark.sql.functions.udf
// uma UDF que retorna o tamanho de uma string
val len = udf { str:String => str.length }
// aplicar a UDF len à coluna texto e criar uma
// nova coluna com o resultado
val df1 = df.withColumn("tamanho", len(df("texto"))
13/28
14. Spark UDFs
Resultado da aplicação da UDF len :
DataFrame df DataFrame df1
14/28
texto
amostra #1 “foo”
amostra #2 “foo bar”
amostra #3 “oi”
aplicação da
UDF len
tamanho
amostra #1 3
amostra #2 7
amostra #3 2
15. Spark ml
15/28
● spark.ml é um componente do módulo spark-mllib
● Disponibiliza, entre outras coisas, várias transformações baseadas em
UDFs para manipular um DataFrame
● Entre elas:
○ RegexTokenizer
○ OneHotEncoder
○ StringIndexer
○ MinMaxScaler
○ Bucketizer
16. Spark ml
● RegexTokenizer (String => Vector[String])
○ Tokeniza strings usando uma regex como delimitador
DataFrame df DataFrame df1
16/28
texto
amostra #1 “foo,bar”
amostra #2 “bar baz”
amostra #3 “foo.bar.baz”
aplicação do
RegexTokenizer
usando a regex
/s+|,|./ como
delimitador
tokens
amostra #1 [“foo”,”bar”]
amostra #2 [“bar”,”baz”]
amostra #3 [“foo”,”bar”,”baz”]
21. Estudo de caso: Reviews Amazon
● Um estudo de caso mostrando várias etapas possíveis para um
dataset real
● Não é um processo completo, apenas alguns passos para motivar
os ouvintes e dar uma ideia das quantidades envolvidas
○ Usa UDFs e também o módulo spark-mllib
● Código completo em https://github.com/queirozfcom/rio-big-data-
meetup-nov-2015
○ Incluindo a criação dos clusters usando AWS EMR
21/28
22. O dataset
Cada elemento é uma review de um produto na Amazon.com
● ~ 55 Gb (após desempacotamento)
● ~ 82 Milhões de Reviews
● Maio/1996 - Julho/2014
● Formato Json
● Link: http://jmcauley.ucsd.edu/data/amazon/
22/28
23. O dataset
● Elemento de exemplo:
{
"reviewerID": "A2SUAM",
"asin": "00000",
"reviewerName": "J. McDonald",
"helpful": [2, 3],
"reviewText": "I bought this for ...",
"overall": 5.0,
"summary": "Heavenly Highway!",
"unixReviewTime": 1252800000
}
23/28
24. Passos do Pipeline de exemplo
1. Retirar linhas com elementos null
2. Adicionar features para:
a. O tamanho do texto do reviewText e do summary
b. Período do dia em que a review for feita (dia/noite)
c. Período da semana em que a review foi feita (dia útil/fim
de semana)
3. Juntar todo o texto corrido (reviewText + summary) em um único
campo, passar para minúsculas, tokenizar e transformar em um
vetor de frequências (TF)
4. Normalizar a nota (atributo overall)
5. Transformar o atributo helpful em um float e normalizar
24/28
25. Dicas Gerais / Lições aprendidas
● É melhor criar uma máquina EC2, baixar o dataset para ela e, de
lá, fazer upload para o S3
○ Se estiverem na mesma área, o processo é muito mais rápido
● Se usar AWS EMR, cuidado para não esquecer o cluster ligado!
○ Use --auto-terminate
● Habilitar dynamicAllocation
● Recomendo a API Scala pois as outras às vezes ficam defasadas
25/28
26. Mais informações
● Todo o código foi rodado no ambiente da AWS, usando o serviço
EMR (Elastic MapReduce), com o build emr-4.0.1
○ Todo o código usado pode ser obtido em https://github.
com/queirozfcom/rio-big-data-meetup-nov-2015
● Guia para criar um cluster Spark usando o serviço AWS Elastic
MapReduce (EMR)
● Guia para usar o Apache Zeppelin no AWS EMR
● Guia para criar UDFs (User-defined Functions) no Spark/pyspark
26/28