A transformação dos dados é uma etapa importante do processo de análise, muitos algoritmos de Machine Learning esperam receber os valores padronizados. Muitas vezes quando falamos em padronização ou normalização de variáveis estamos nos referindo a mesma coisa: transformar todas as variáveis na mesma ordem de grandeza, ou seja, trazer os valores para a mesma escala de valores.

Quando realizamos a padronização (por meio do Score Z) obtemos como resultado dados centralizados em uma média igual a 0 e desvio padrão igual a 1. Por outro lado, quando realizamos a normalização, o nosso resultado se encontra em um intevalo de 0 a 1, já se tivermos números negativos o intervalo será de -1 a 1.

O objetivo desse post é analisar como diferentes tecnicas de normalização/padronização alteram as escalas e distribuição dos dados. Aplicaremos diferentes técnicas e verificaremos sua distribuição e sua assimetria.

# Carregando pacote para cálculo de assimetria
library(e1071)

# Trazendo dataset iris
data("iris")
head(iris, 2)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
hist(iris$Sepal.Length)

skewness(iris$Sepal.Length)
## [1] 0.3086407

Normalização Segundo a Amplitude:

Normalmente adotamos a normalização amplitudional quando temos no conjunto de dados unidades muito diferentes ou dispersões muito heterogêneas.

Score Z (Padronização):

\[ (x - μ) / σ \]

Onde: μ - média σ - desvio padrão

score_z = scale(iris$Sepal.Length, center = T)
hist(score_z)

skewness(score_z)
## [1] 0.3086407

O coeficiente de assimetria se mantém o mesmo para ambos os conjuntos de dados.

Escala Min-Max (Normalização):

\[(x - min) / (max - min)\]

Onde: min - valor mínimo da variável max - valor máximo da variável

# Criando função para cálculo
f_minmax <- function(x){
  return((x - min(x))/(max(x)-min(x)))
}
minmax <- f_minmax(iris$Sepal.Length)
hist(minmax)

skewness(minmax)
## [1] 0.3086407

O coeficiente de assimetria se mantém o mesmo para ambos os conjuntos de dados.

Caso tivessemos valores negativos deveriamos usar a fórmula abaixo, para manter o intervalo de valores entre 1 e -1.

\[(x - ((max + min) / 2)) / ((max - min) / 2)\]

# Função para valores negativos
minmax_neg <- function(x){
  return((x - ((max(x) + min(x)) / 2)) / ((max(x) - min(x)) / 2))
}
Log K:

Nesse método o intervalo de valores ficará entre 0 e 1.

\[x / (10^k)\] Para o menor k tal que \[max |x|/10^k = 1\]

f_log <- function(x){
  k <- log10(abs(max(x)))
  return(x/(10^k))
}

amp_log <- f_log(iris$Sepal.Length)
hist(amp_log)

skewness(amp_log)
## [1] 0.3086407

O coeficiente de assimetria se mantém o mesmo que antes da normalização.

Normalização Distribucional:

Normalmente adotamos esse tipo de normalização quando queremos obter simetria dos dados, remoção de valores extremos, etc.

Raiz Quadrada:

\[√x\]

raizQ <- sqrt(iris$Sepal.Length)
hist(raizQ)

skewness(raizQ)
## [1] 0.1743117

A partir da normalização distribucional obtemos uma maior simetria dos dados, alterando o coeficiente de assimetria.

Log:

\[\log x\]

norm_log <- log(iris$Sepal.Length)
hist(norm_log)

skewness(norm_log)
## [1] 0.04272597
Inversa Negativa:

\[-1/x\]

inversaN <- function(x){
  return((-1) / x)
}

invNorm <- inversaN(iris$Sepal.Length)
hist(invNorm)

skewness(invNorm)
## [1] -0.2135547
Raiz Cúbica:

\[{}3\sqrt{x}\]

cubica <- function(x){
  return(x^(1/3))
}

raizC <- cubica(iris$Sepal.Length)
hist(raizC)

skewness(raizC)
## [1] 0.1301586
Log1p:

O log1p é uma boa opção quando temos grande quantidade de dados nulos em nosso conjunto.

\[\log(1+x)\]

logp <- log1p(iris$Sepal.Length)
hist(logp)

skewness(logp)
## [1] 0.08093967

Podemos ver o efeito de uma série de possiveis técnicas de normalização para o conjunto de dados, muitas vezes a escolha varia de um conjunto para outro. A melhor alternativa em alguns casos é aplica todos e verificar em qual o modelo performa melhor.