Classificação Multirrótulo: Propriedades dos Dados Multirrótulo - Parte 4
Oi pessoal!!! Vamos continuar com nossa série? No artigo passado paramos em como fazer obter o total de ocorrências de pares de rótulos. Vamos começar este artigo a partir dai!
Frequência de pares de rótulos
Hoje vamos usar um comando bem longo para executar uma tarefa que deve ser aplicada em várias colunas ao mesmo tempo. Primeiro vou passar o comando e em seguida vou explicar os seus componentes:
map_dfr(.x = combn(names(labels), 2, simplify = FALSE),
~ labels %>%
select(.x) %>%
summarise(pair_1 = .x[1],
pair_2 = .x[2],
n = sum(rowSums(select(., everything()) == 1) == 2)))
A função map_dfr() aplica uma função a cada elemento de uma lista ou vetor retornando um dataframe e ela é construída da seguinte forma:
map_dfr(.x, .f, ..., .id = NULL)
O primeiro argumento desta função é o .x que é a própria lista ou vetor que queremos manipular - em nosso caso é uma outra função (combn). O segundo argumento .f é uma função, uma "fórmula" ou um vetor que queremos aplicar. Em nosso caso .f envolve a aplicação de uma função em várias colunas.
Quero reforçar aqui que é sempre importante consultar a documentação oficial da Linguagem! Clique aqui para ler mais sobre map_dfr().
A função combn() gera todas as combinações dos elementos de x tomados "m" de cada vez e ela é construída da seguinte forma:
combn(x, m, FUN = NULL, simplify = TRUE, ...)
O primeiro argumento da função combn() é o dataframe (x), o segundo argumento (m) é o número de elementos que deve ser escolhido. Em nosso caso, m=2 pois queremos as combinações de pares. Simplify = FALSE faz com que seja retornada uma lista com o resultado. Clique aqui para ler mais sobre combn()
O símbolo %>% é chamado de operador pipe e ele é uma função cujo objetivo é simplificar comandos em que os resultados devem passar para outros comandos. Legal, né?! Pois, então, é uma facilidade, mais um recurso do R para você usar.
O pipe faz parte do pacote magrittr, o qual fornece um conjunto de operadores para melhorar a estrutura do código em R. Com o pipe a gente consegue passar e modificar um objeto para uma função ao mesmo tempo! Interessante!!!! Quer ver um exemplo bem simples pra entender a lógica?
library(magrittr)
# comando original
x <- "10" # atribui a string 10 à x
x <- as.numeric(x) # converte a string 10 em número
# comando com pipe
x <- "10" # atribui a string 10 à x
x %>% as.numeric # passa e modifica x
Muito prático! No comando original, a gente passa o x como parâmetro para a função as.numeric mas, com o pipe, isso não é necessário! Então o que estamos fazendo em nosso comando é algo como um encadeamento, onde vamos encadeando os resultados de várias funções até chegar no que queremos! Se quiser saber mais sobre o pipe, sugiro ler a documentação oficial.
Um outro operador presente aqui é o ~ que é chamado de operador tilde. Não vou me alongar em explicar detalhes desse operador pois é algo muito mais avançado e não há necessidade para pânico neste momento! No nosso comando podemos entender ~ labels como "entenda que aqui você deve usar todos os rótulos".
O comando select() que vem logo em seguida de ~ labels %>% é utilizado para selecionar colunas usando os seus nomes e tipos. Em nosso caso, queremos os pares de colunas que estão em .x. Vejam, neste ponto .x serão as duas colunas que queremos calcular a co-ocorrência e elas vão se modificando através da função combn() que foi definida primeiro!
Por último, temos o comando summarise() que é responsável por criar um novo dataframe e sua forma é:
summarise(.data, ..., .groups = NULL)
onde .data é o dataframe, as reticências podem ser outros parâmetros quaisquer, e groups refere-se a grupo. De acordo com a documentação oficial, o dataframe resultante terá a quantidade de linhas necessárias para cada combinação de variáveis agrupadas.
Em nosso caso, estamos agrupando os resultados por cada combinação de colunas. Notem que dentro de summarise estão pair_1 = .x[1] e pair_2 = x[2], indicando quem é o primeiro e o segundo rótulo que está sendo avaliado naquele momento. Depois nós temos n = sum(rowSums(select(., everything()) == 1) == 2)), que, basicamente, faz a soma das linhas das colunas selecionadas.
A função everything() seleciona todas as variáveis e a função select() seleciona um subconjunto de colunas. Portanto, usando everything dentro de select somos capazes de selecionar todas as variáveis que nos interessam, que no caso do nosso problema são todas as instâncias que têm valor igual 1.
A função rowSums() literalmente soma linhas enquanto sum() soma todos os valores. Portanto, esse trechinho do código está encontrando pra nós o total de ocorrências de 2 rótulos. Esse resultado é encadeado com o comando summarise para construir o dataframe que queremos obter como resposta.
Finalizando, o comando vai executar para todas as combinações de pares de rótulos o cálculo que desejamos e retornar para nós uma tabela com os valores. Podemos também armazenar o resultado desse comando em uma variável e assim ser capazes de usá-lo depois:
resultado = map_dfr(.x = combn(names(labels), 2, simplify = FALSE),
~ labels %>%
select(.x) %>%
summarise(par_a = .x[1],
par_b = .x[2],
n = sum(rowSums(select(., everything()) == 1) == 2)))
Aqui eu mudei pair_1 e pair_2 para par_a e par_b, apenas para demonstrar que essas variáveis também são os nomes que aparecerão como resultado no dataframe. Podemos também mudar o nome da ultima coluna:
names(resultado)[3] = "coocorrencia"
A função names() nos permite fazer isso. Coloquei o numero 3 ali entre colchetes pois quero mudar apenas o nome da terceira coluna! Outra coisa que podemos fazer é ordenar o dataframe pela co-ocorrência:
arrange(resultado,desc(coocorrencia))
Esse comando vai ordenar a frequência do maior para o menor valor.
Notamos que o par de rótulos que menos ocorre no dataset é o black e o orange, enquanto que o mais frequente é o red com white!
Finalizando
Pessoal, vou finalizando o artigo de hoje por aqui! No próximo artigo vamos falar de outras características! Te vejo lá =)
Este artigo foi escrito por Elaine Cecília Gatto - Cissa e publicado originalmente em Prensa.li.