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
Normalmente adotamos a normalização amplitudional quando temos no conjunto de dados unidades muito diferentes ou dispersões muito heterogêneas.
\[ (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.
\[(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))
}
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.
Normalmente adotamos esse tipo de normalização quando queremos obter simetria dos dados, remoção de valores extremos, etc.
\[√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 x\]
norm_log <- log(iris$Sepal.Length)
hist(norm_log)
skewness(norm_log)
## [1] 0.04272597
\[-1/x\]
inversaN <- function(x){
return((-1) / x)
}
invNorm <- inversaN(iris$Sepal.Length)
hist(invNorm)
skewness(invNorm)
## [1] -0.2135547
\[{}3\sqrt{x}\]
cubica <- function(x){
return(x^(1/3))
}
raizC <- cubica(iris$Sepal.Length)
hist(raizC)
skewness(raizC)
## [1] 0.1301586
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.