Pré-processamento de Dados

Documentos relacionados
Pré-processamento dos Dados e Análise Exploratória

Sumarizando Dados. Fabrício Olivetti de França. Universidade Federal do ABC

Programação Paralela. com Haskell. Fabrício Olivetti de França. Universidade Federal do ABC

MapReduce Mapeando e reduzindo

Paradigmas de Programação

Aula 7 Medidas de Distância. Profa. Elaine Faria UFU

Programação Funcional em Haskell

Aprendizado de Máquina (Machine Learning)

Aula 6 Mineração Streams Representação dos Dados. Profa. Elaine Faria UFU

Funções de Ordem Superior

Programação Funcional Capítulo 3 Tipos e Classes

Pedro Vasconcelos DCC/FCUP. Programação Funcional 2 a Aula Tipos e classes

Pedro Vasconcelos DCC/FCUP. Programação Funcional 4 a Aula Listas

Pedro Vasconcelos DCC/FCUP. Programação Funcional 2 a Aula Tipos e classes

Programação Funcional Aulas 5 & 6

Programação Funcional

Funções de Ordem Superior

MINERAÇÃO DE DADOS. Thiago Marzagão MINERAÇÃO DE TEXTOS. Thiago Marzagão (UnB) MINERAÇÃO DE DADOS 1/ / 25

Algoritmos - 3. Alexandre Diehl. Departamento de Física - UFPel

Programação de Computadores III

Programação Funcional. Capítulo 21. Parsers. José Romildo Malaquias. Departamento de Computação Universidade Federal de Ouro Preto 2018.

Programação de Computadores III

Organização de Computadores I

Aula prática 14. Expressão Lambda

Programação de Computadores:

Lista de Exercício de Linguagens de Programação Prog. Funcional

Computação L2. Linguagem C++ Observação: Material Baseado na Disciplina Computação Eletrônica.

Pedro Vasconcelos DCC/FCUP. Programação Funcional 18 a Aula Plataforma Haskell

Estruturas de Dados Estruturas de Dados Fundamentais

Expressões Lambda. Programação Funcional. Capítulo 7. José Romildo Malaquias Departamento de Computação Universidade Federal de Ouro Preto

Linguagens de Programação. Programação Funcional e Haskell Programação Interativa Thiago Alves

Aula 2: Resumo de Dados

SCC0173 Mineração de Dados Biológicos

Listas em Haskell. Listas. Linguagem Haskell. Maria Adriana Vidigal de Lima. Faculdade de Computação - UFU. Setembro

Pedro Vasconcelos DCC/FCUP. Programação Funcional 13 a Aula Definição de tipos

Informática para Ciências e Engenharias 2013/14. Teórica 7

Métodos Computacionais em Física

Conceitos de Linguagens de Programação

Algoritmos e Estrutura de Dados Aula 02 Listas em Python

Extraindo atributos de textos. Prof. Fabrício Olivetti de França

Haddop, MapReduce e Spark

Arquitetura de Computadores Sistema de Numeração. Apresentado por Prof. Fred Sauer Mat. Elaborado por Prof. Ricardo Quintão

MATRIZES - PARTE Definição e Manipulação de Matrizes AULA 21

Redes Neurais Artificiais

Manipulação básica de dados no PDI

Programação Funcional

Universidade Federal de Uberlândia - UFU Faculdade de Computação - FACOM Lista de exercícios de programação em linguagem C

Jarley Nóbrega

Universidade Federal de Uberlândia - UFU Faculdade de Computação - FACOM Lista de exercícios de programação em linguagem Python

Regressão Polinomial e Simbólica

Pedro Vasconcelos DCC/FCUP. Programação Funcional 14 a Aula Um verificador de tautologia

Ficha 1 Noções de sequência e decisão em algoritmia

Prof. MSc. David Roza José 1/39

Capítulo 1 - Lógica e Algoritmos

Introdução à Programação uma Abordagem Funcional

Profª Ana Lúcia Lima Marreiros Maia Profª Fabiana Cristina Bertoni

Marina Andretta. 10 de outubro de Baseado no livro Introduction to Linear Optimization, de D. Bertsimas e J. N. Tsitsiklis.

Pedro Vasconcelos DCC/FCUP. Programação Funcional 7 a Aula Funções de ordem superior

Introdução à Ciência da Computação II

Programação Funcional. Aula 6. Listas. José Romildo Malaquias. Departamento de Computação Universidade Federal de Ouro Preto 2011.

Interpolação polinomial

Tipos Algébricos. Programação Funcional. Capítulo 11. José Romildo Malaquias Departamento de Computação Universidade Federal de Ouro Preto

Python + Spark = PySpark. Prof. Fabrício Olivetti de França Universidade Federal do ABC

Álgebra Linear Semana 03

Primeiro Exercício programa: Como o Google ordena páginas. MAP-2121 para EPUSP

Transcrição:

Pré-processamento de Dados Fabrício Olivetti de França Universidade Federal do ABC

Pré-Processamento dos Dados

Tópicos 1. Pré-Processamento dos Dados 2. Conceitos Básicos 3. Representação Textual 4. Padrões Recorrentes 5. Padronizando e Normalizando os Atributos 6. Paralelizando o Pré-Processamento 1

Conceitos Básicos

Data Sets Conjunto de objetos de dados. Objeto de dados é uma entidade: funcionário de uma empresa medições da atividade cerebral em um paciente descrição de uma ocorrência policial 2

Objetos de Dados Idade Local Valor do impulso elétrico etc. 3

Tipos de Atributos Categóricos: Nominal Binário Ordinal Numéricos: Intervalar Razão 4

Atributos Nominais Símbolos ou nomes descritivos: Descreve uma característica Não apresentam relação de ordem, apenas igualdade Ex.: ocupação, cor dos olhos, etc. 5

Atributos Binários Atributo nominal com apenas dois valores possíveis: 0 ou 1. Ex.: resultado de um exame, gênero, etc. 6

Atributos Ordinais Valores que apresentam ordem, mas não possuem relação de magnitude. Ex.: {péssimo, ruim, regular, bom, ótimo} 7

Atributos Intervalares Atributo numérico com relação de ordem e magnitude. Ex.: Temperatura de 20 C é 10 unidades mais quente do que 10 C. Não podemos dizer que 20 C é duas vezes mais quente do que 10 C. 8

Atributos Intervalares O 0 absoluto em Celsius está em 273.15 C. 20 C está a 293.15 de nenhum calor, o dobro desse calor seria 586.30 ou 313.15 C. 9

Atributos de Razões Atributos numéricos com a mesmas propriedades do intervalar, mas com um ponto-zero. Altura Contagem de palavras Temperatura em Kelvin 10

Representando Objetos Precisamos de uma representação numérica. Dados numéricos: ok! (ou quase sempre ok) Dados nominais: vetor binário Dados ordinais: rank 11

Representando Objetos Tabela 1: Base de Dados. Profissão Conceito Nota Engenheiro A 9.5 Professor B 8.4 Engenheiro A 7.3 Gerente D 9.1 12

Atributos Categóricos Binários Tabela 2: Base de Dados. Engenheiro Professor Gerente Conceito Nota 1 0 0 A 9.5 0 1 0 B 8.4 1 0 0 A 7.3 0 0 1 D 9.1 13

Atributos Ordinais Numéricos # conceitos = 5 Rank: 5, 4, 3, 2, 1 z = (rank 1) # 1 Tabela 3: Base de Dados. Engenheiro Professor Gerente Conceito Nota 1 0 0 1 9.5 0 1 0 0.75 8.4 1 0 0 1 7.3 0 0 1 0.25 9.1 14

Leitura da Base de Dados data Profissao = Engenheiro Professor Gerente Estudante deriving (Show, Read, Eq, Enum, Bounded) data Conceito = F D C B A deriving (Show, Read, Enum) type Nota = Double type Objeto = (Profissao, Conceito, Nota) type Objeto = [Double] 15

Leitura da Base de Dados parsefile :: String -> [Objeto] parsefile file = map parseline (lines file) where parseline l = toobj (words l) toobj [w1, w2, w3] = (read w1 :: Profissao, read w2 :: Conceito, read w3 :: Nota) A função words separa uma string em uma lista de strings cortando nos caracteres de espaço. 16

Leitura da Base de Dados transformdata :: [Objeto] -> [Objeto ] transformdata data = map parseobj data where parseobj (prof, conc, nota) = (binariza prof) ++ [rank conc, nota] 17

Leitura da Base de Dados binariza :: Profissao -> [Double] binariza p = map bool2double [p == p p <- profissoes] where profissoes = [minbound..] :: [Profissao] bool2double True = 1.0 bool2double _ = 0.0 18

Leitura da Base de Dados rank :: Conceito -> Double rank co = (fromenum co) / (fromenum A) where fromenum = fromintegral. fromenum 19

Fluxo dos Dados A leitura e transformação dos dados segue um fluxo bem definido. É fácil perceber que, enquanto uma linha do arquivo está sendo processada pela função transformdata, outra pode ser processada pela função parsefile. Arquivo parsefile transformdata 20

Representação Textual

Mineração de Textos Documentos de textos: Não possuem representação vetorial Interdependência dos atributos Tamanho variável 22

Textos como conjuntos Se representarmos os documentos de textos como o conjunto de suas palavras: D1 = Estou assistindo a uma aula de Big Data, mas tudo que aprendi foi Haskell durante a aula! D2 = Hoje aprendi Haskell na aula, será que o que aprendi será útil na minha vida? 23

Textos como conjuntos Se representarmos os documentos de textos como o conjunto de suas palavras: D1 = {Estou, assistindo, a, uma, aula, de, Big, Data, mas, tudo, que, aprendi, foi, Haskell, durante, aula!} D2 = {Hoje, aprendi, Haskell, na, aula, será, que, o, útil, minha, vida?} 24

Textos como conjuntos Calculando a similaridade de Jaccard, temos: D1 D2 = {que, aprendi, Haskell} D1 D2 = {Estou, assistindo, a, uma, aula, de, Big, Data, mas, tudo, que, aprendi, foi, Haskell, durante, aula!, Hoje, na, aula, será, o, útil, minha, vida?} J(D1, D2) = 3 24 = 0.125 Essa representação é conhecida como Bag-of-Words, em que geramos os atributos do texto como atributos categóricos. 25

Normalização do Texto Pode ser interessante padronizar a forma do texto para termos serem considerados como um elemento único do conjunto independente de como é escrito. Por exemplo: Estou, estou, estou, aula!, aula, aula?, útil, util. D1 = {estou, assistindo, a, uma, aula, de, big, data, mas, tudo, que, aprendi, foi, haskell, durante, aula} D2 = {hoje, aprendi, haskell, na, aula, sera, que, o, util, minha, vida} J(D1, D2) = 4 23 = 0.17 26

Eliminação de atributos irrelevantes Podemos eliminar palavras que não apresentam significado sozinhas: D1 = {estou, assistindo, aula, big, data, tudo, aprendi, haskell, durante, aula} D2 = {hoje, aprendi, haskell, aula, sera, util, minha, vida} J(D1, D2) = 4 14 = 0.28 27

Bag-of-Words type Doc = String type Token = String bagofwords :: [Doc] -> [[Token]] bagofwords docs = naovazio $ map tokeniza docs where tokeniza doc = nub $ filter maisde2 $ map normaliza (words doc) normaliza palavra = map tolower $ filter isalphanum palavra maisde2 palavra = (length palavra) > 2 naovazio xs = filter (not. null) xs 28

Bag-of-Words A função tolower converte um caractere maiúsculo para minúsculo, e a função isalphanum retorna verdadeiro se o caractere é uma letra do alfabeto ou um número. 29

Fluxo dos Dados O fluxo dos dados pode ser descrito com o seguinte fluxograma: map tokeniza words map normaliza filter isalphanum map tolower naovazio nub filter maisde2 30

Term-Frequency Se um termo aparece repetidas vezes em um documento, isso significa que ele pode ter uma importância maior do que os outros termos. No nosso exemplo, a repetição do termo Haskell indica um dos temas dos nossos documentos. 31

Term-Frequency A informação de frequência pode ser importante para a representação de nossos documentos. Podemos fazer então: fn(t, d) = f (t, d), d com f (t, d) sendo a frequência do termo t no documento d e d a quantidade de termos no documento d. 32

Term-Frequency A ideia para computar os vetores TF é primeiro representar cada documento como uma lista (token, 1.0) e, em seguida: Ordenar essa lista pelo token Agrupar os itens com mesmo token Somar os valores em cada grupo Dividir os valores pelo número de tokens 33

TF type Freq = Double tf :: [Doc] -> [[(Token, Freq)]] tf docs = naovazio $ map tokeniza docs where tokeniza doc = fn $ map normtupla (words doc) normtupla w = (normaliza w, 1.0) 34

TF fn :: [(Token, Double)] -> [(Token, Freq)] A partir desse momento trabalharemos frequentemente com bases de dados representadas como listas de tuplas. Essas tuplas devem ser encaradas como chave e valor, respectivamente. Para tornar o código mais legível, vamos definir as funções mapbykey, foldbykey, groupbykey, sortbykey 35

mapbykey mapbykey aplica a função g apenas no valor da tupla, deixando a chave intacta: mapbykey g = map (\(k,v) -> (k, g v)) 36

foldbykey foldbykey assume uma lista de tuplas chave-valor em que todas as chaves são iguais. Essa função aplica foldl1 apenas nos valores das tuplas, resultando em uma tupla (k, v) em que k é a chave de todas as tuplas e v o resultado da operação fold: foldbykey g = foldl1 (\(k1,v1) (k2,v2) -> (k1, g v1 v2)) 37

sortbykey sortbykey ordena uma lista de tuplas pela chave: sortbykey = sortby ordenatupla ordenatupla :: (Ord a) => (a, t) -> (a, t) -> Ordering ordenatupla (a1,b1) (a2,b2) a1 < a2 = LT a1 > a2 = GT a1 == a2 = EQ 38

groupbykey groupbykey agrupa uma lista ordenada de tuplas gerando uma lista de listas, com cada lista agrupando as tuplas de mesma chave: groupbykey = groupby agrupatupla agrupatupla :: (Eq a) => (a, t0) -> (a, t0) -> Bool agrupatupla (a1, b1) (a2, b2) = a1==a2 groupbykey [(1,0.1), (1,0.2), (2,0.1)] == [ [(1,0.1),(1,0.2)], [2,0.1] ] 39

TF fn :: [(Token, Double)] -> [(Token, Freq)] fn tokens = mapbykey (/n) $ map (foldbykey (+)) $ groupbykey $ sortbykey tokens where n = length tokens 40

Fluxo dos Dados O fluxo dos dados pode ser descrito com o seguinte fluxograma: map tokeniza words map normaliza sortbykey groupbykey mapbykey map foldbykey 41

Inverse Document Frequency Algumas palavras aparecem com uma frequência muito superior as demais, como: e, que, ou, etc. Essas palavras não costumam apresentar um significado discriminatório e, portanto, podem ter um peso menor. Para isso podemos multiplicar o TF por: idf (t) = log D {d D : t D} 42

TF-IDF Como veremos mais adiante, é possível pensar no vetor IDF como uma matriz associativa. Para isso utilizaremos o HashMap do Haskell. idf :: [[(Token, Freq)]] -> M.HashMap Token Freq idf corpus = M.fromList $ mapbykey (\v -> log (n/v)) $ map (foldbykey (+)) $ groupbykey $ sortbykey $ map (\ (k,v) -> (k,1)) $ concat corpus where n = length corpus 43

HashMap -- importa a biblioteca HashMap.Strict apelidade de M import qualified Data.HashMap.Strict as M -- cria um mapa M.HashMap Integer Double da lista de tuplas mapa = M.fromList [(1, 0.1), (2, 0.3), (3, 0.04)] mapa M.! 2 -- retorna 0.3 concat [ [1,2], [3,4] ] = [1,2,3,4] 44

TF-IDF tfidf :: [[(Token, Freq)]] -> M.HashMap Token Freq -> [[(Token, Freq)]] tfidf tf idf = map multidf tf where multidf = mapbykey (\(k,v) -> (k, v * (idf M.! k)) ) 45

Fluxo dos Dados O fluxo dos dados pode ser descrito com o seguinte fluxograma: map multidf mapbykey concat map sortbykey fromlist mapbykey map foldbykey groupbykey 46

Padrões Recorrentes

Padrões de sequência de funções Nos exemplos anteriores, podemos perceber um padrão recorrente de chamada de funções utilizadas em diversas soluções: map (foldbykey (+)) $ groupbykey $ sortbykey Esse padrão precede a chamada de uma função map que transforma um valor em uma tupla chave-valor (k, v). 49

Padrões de sequência de funções Basicamente esse padrão combina os valores das tuplas com a mesma chave utilizando uma função (nos exemplos utilizamos (+)). É interessante, então, criar a função: combine :: Ord k => (v -> v -> v) -> [(k, v)] -> [(k, v)] combine f xs = map (foldbykey f) $ groupbykey $ sortbykey xs Com isso, muitas funções se tornam sequências de combine. map. 50

fn fn :: [(Token, Double)] -> [(Token, Freq)] fn tokens = mapbykey (/n) $ combine (+) tokens where n = length tokens 51

idf Como veremos mais adiante, é possível pensar no vetor IDF como uma matriz associativa. Para isso utilizaremos o HashMap do Haskell. idf :: [[(Token, Freq)]] -> M.HashMap Token Freq idf corpus = M.fromList $ mapbykey (\v -> log (n/v)) $ combine (+) $ mapbykey (\v -> 1) $ concat corpus where n = length corpus 52

Padronizando e Normalizando os Atributos

Padronização Muitos algoritmos de Aprendizado de Máquina supõem que os valores dos atributos seguem N(0, 1). Se um atributo não segue esse padrão, pode dominar a função-objetivo e se tornar importante demais. 53

Padronização Dado uma matriz de dados X, podemos padronizar os valores de cada um de seus elementos como: ˆX i,j = X i,j X i,j σ j 54

Padronização padroniza :: [[Double]] -> [[Double]] padroniza x = mapcolunas padroniza x padroniza :: [Double] -> [Double] padroniza x = devmedia./ sigma where media xs = (sum xs) / n devmedia = x.- (media x) sigma = sqrt $ media $ devmedia.** 2 n = length x 55

Fluxo dos Dados O fluxo dos dados pode ser descrito com o seguinte fluxograma: mapcolunas padroniza media devmedia./.** 2 media 56

Escalonamento Algoritmos baseados em métodos de gradiente tendem a se beneficiar quando os atributos estão entre [0, 1]. ˆX i,j = X i,j min X :,j max X :,j min X :,j 57

Padronização maxminscale :: [[Double]] -> [[Double]] maxminscale x = mapcolunas maxminscale x maxminscale :: [Double] -> [Double] maxminscale x = map scale x where scale xi = (xi - minimum x) / (maximum x - minimum x) 58

Normalização Finalmente podemos normalizar cada amostra da base utilizando a normalização de vetores: X i,j ˆX i,j = X i p 59

Padronização normaliza :: [[Double]] -> [[Double]] normaliza x = map normaliza x where normaliza xi = xi./ (norma xi) norma xi = sqrt. sum $ xi.^ 2 60

Paralelizando o Pré-Processamento

Paralelizando chunks Conforme vimos na aula anterior, ao paralelizar um programa objetivamos minimizar o número de sparks e tentar distribuir a tarefa de forma homogênea entre as threads. 62

Paralelizando chunks Para isso adotamos a estratégia de dividir nossos dados em pedaços (denominados chunks), processar cada chunk em paralelo e, em seguida, juntar os resultados. 63

Paralelizando chunks Vamos continuar utilizando o tipo ChunksOf definido anteriormente para representar nossos arquivos distribuídos entre diversas máquinas. 64

Paralelizando Leitura dos Dados Com isso, nossa função de processamento dos dados em paralelo simplesmente aplica a função transformdata em cada um dos chunks em paralelo. transformdatapar :: ChunksOf [Objeto] -> ChunksOf [Objeto ] transformdatapar chunks = (map transformdata chunks using parlist rdeepseq) Note que nenhuma alteração é necessária para a função transformdata que continuará recebendo o tipo [Objeto] e retornando [Objeto ]. 65

Paralelizando a Padronização Na padronização, não podemos calcular as três partes da equação em paralelo. Além disso, temos um outro desafio, recebemos pedaços de linhas, mas temos que trabalhar com as colunas: padroniza :: [[Double]] -> [[Double]] padroniza x = mapcolunas padroniza x padroniza :: [Double] -> [Double] padroniza x = (x.- media)./ sigma where media = (sum x) / n sigma = sqrt $ sum $ (x.- media).** 2 n = fromintegral $ length x 66

Paralelizando a Padronização Primeiro, vamos alterar a assinatura da função para sabermos onde queremos chegar: padronizapar :: ChunksOf [[Double]] -> ChunksOf [[Double]] padronizapar chunks = parmap padroniza chunks where padroniza = map (\xi -> (xi.-. media)./. desvio) media = mapreduce id (.+.) chunks desvio = map (\x -> sqrt (x/n)) $ mapreduce desvquad (.+.) chunks desvquad xi = (xi.-. media).**2 n = sum $ map length chunks 67

Paralelizando a Normalização A implementação paralela de normaliza pode ser feita diretamente aplicando a versão sequencial em cada chunk. normalizapar :: ChunksOf [[Double]] -> ChunksOf [[Double]] normalizapar chunks = parmap normaliza chunks normaliza :: [[Double]] -> [[Double]] normaliza x = map normaliza x where normaliza xi = xi./ (norma xi) norma xi = sqrt. sum $ xi.^ 2 68

Paralelizando o TF Da forma que organizamos o algoritmo de TF, utilizando map e combine, basta aplicar a função tf em cada chunk. tfpar :: ChunksOf [Doc] -> ChunksOf [[(Token, Freq)]] tfpar chunks = parmap tf chunks tf :: [[Token]] -> [[(Token, Freq)]] tf docs = map normfreq docs where normfreq doc = fn $ map (\w -> (w, 1.0)) doc 69

Paralelizando a o IDF Para paralelizar o IDF, precisamos calcular a contagem de quantos documentos contém cada token em cada chunk. Em seguida, é necessário combinar os resultados de cada chunk para então calcular o idf. idfpar :: ChunksOf [[(Token, Freq)]] -> M.HashMap Token Freq idfpar chunks = M.fromList $ mapbykey (\v -> log (n/v)) $ combine (+) $ concat $ (map idf chunks using parlist rdeepseq) where n = sum $ map length chunks idf :: [[(Token, Freq)]] -> [(Token, Freq)] idf corpus = combine (+) $ map (\(k,v) -> (k,1) ) $ concat corpus 70

Padrão de paralelismo Note que o padrão de paralelismo do cálculo do IDF difere dos anteriores pois é necessário o uso do combine no lugar de foldl1 e a aplicação de concat na saída do map. 71

Padrão de paralelismo Uma função genérica pode ser escrita da seguinte forma e aplicada em muitas situações em que trabalhamos com lista de tuplas: mapreducebykey :: (NFData k, NFData v, Ord k) => (a -> (k, v)) -> (v -> v -> v) -> ChunksOf [a mapreducebykey f g xs = combine g $ concat $ (map f xs using parlist rdeepseq) where f xi = combine g $ map f xi 72

Padrão de paralelismo Nossa função idfpar ficaria: idfpar :: ChunksOf [[(Token, Freq)]] -> M.HashMap Token Freq idfpar chunks = M.fromList $ mapbykey (\v -> log (n/v)) $ mapreducebykey (\(k,v) -> (k,1)) (+) $ parmap concat chunks where n = sum $ map length chunks 73