Pré processamento de grandes dados com Apache Spark

426 visualizações

Publicada em

Pequena introdução a formas de preprocessar dados usando a API de DataFrames do Apache Spark. Apresentado no Rio Big Data Meetup de Novembro de 2015.

Publicada em: Dados e análise
0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
426
No SlideShare
0
A partir de incorporações
0
Número de incorporações
18
Ações
Compartilhamentos
0
Downloads
11
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Pré processamento de grandes dados com Apache Spark

  1. 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. 2. Estrutura da palestra ● Introdução ● O problema ● Spark ● Spark Dataframes ● Spark UDFs ● Spark ml ● Estudo de caso 2/28
  3. 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. 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. 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. 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. 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
  8. 8. Spark DataFrames ● Esquema de um DataFrame NxD (N amostras, D features) 8/28 feature #1 feature #2 feature #3 ... feature #D amostra #1 ... amostra #2 ... amostra #3 ... ... ... ... ... ... ... amostra #N ...
  9. 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
  10. 10. Spark DataFrames - transformações Exemplo: feature scaling (normalização de features) DataFrame original DataFrame modificado aplicação da transformação de normalização 10/28 feature #1 feature #2 amostra #1 2 400 amostra #2 4 200 amostra #3 6 400 feature #1 feature #2 amostra #1 0 1 amostra #2 0.5 0 amostra #3 1 1
  11. 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. 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. 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. 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. 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. 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”]
  17. 17. Spark ml ● StringIndexer (String => Double) ○ Transforma valores únicos em índices numéricos DataFrame df DataFrame df1 17/28 feature #1 amostra #1 “amarelo” amostra #2 “azul” amostra #3 “verde” amostra #4 “amarelo” aplicação do StringIndexer feature #1 mod amostra #1 0.0 amostra #2 1.0 amostra #3 2.0 amostra #4 0.0
  18. 18. Spark ml ● OneHotEncoder (Double => Vector[Double]) ○ Transforma índices de features em um domínio em um vetor one-hot DataFrame df DataFrame df1 18/28 aplicação do OneHotEncoder feature #1 amostra #1 0.0 amostra #2 1.0 amostra #3 2.0 amostra #4 0.0 feature #1 mod amostra #1 [1.0,0.0,0.0] amostra #2 [0.0,1.0,0.0] amostra #3 [0.0,0.0,1.0] amostra #4 [1.0,0.0,0.0]
  19. 19. Spark ml ● MinMaxScaler (Vector[Double] => Vector[Double]) ○ Normaliza os valores de uma coluna para o range [0,1] DataFrame df DataFrame df1 19/28 aplicação do MinMaxScaler feature #1 amostra #1 [2.0,800] amostra #2 [4.0,1200] amostra #3 [8.0,600] amostra #4 [16.0,200] feature #1 amostra #1 [0.0,0.6] amostra #2 [0.14,1.0] amostra #3 [0.43,0.4] amostra #4 [1.0,0.0]
  20. 20. Spark ml ● Bucketizer (Double => Double) ○ Discretiza features contínuas, usando limites DataFrame df DataFrame df1 20/28 aplicação do Bucketizer usando os limites 100, 200, 500, 2000 e 5000 feature #1 amostra #1 329.23 amostra #2 123.38 amostra #3 3289.57 amostra #4 1982.376 feature #1’ amostra #1 1.0 amostra #2 0.0 amostra #3 3.0 amostra #4 2.0
  21. 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. 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. 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. 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. 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. 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
  27. 27. FIM 27/28
  28. 28. Agradecimentos ● Professor Alexandre Assis DSc. (orientador do trabalho original) ○ PESC/COPPE UFRJ ● Rosângela Oliveira (colega no trabalho original) ○ rmsilva@cos.ufrj.br ● Julian McAuley PhD. (fornecimento do dataset) 28/28

×