Como normalizar dados em r
Na maioria dos casos, quando as pessoas falam em “normalizar” as variáveis em um conjunto de dados, elas querem dizer que desejam dimensionar os valores de forma que a variável tenha média 0 e desvio padrão de 1.
O motivo mais comum para padronizar variáveis é quando você está executando algum tipo de análise multivariada (ou seja, deseja entender o relacionamento entre diversas variáveis preditoras e uma variável de resposta) e deseja que cada variável contribua igualmente para a análise.
Quando as variáveis são medidas em escalas diferentes, muitas vezes não contribuem igualmente para a análise. Por exemplo, se os valores de uma variável variam de 0 a 100.000 e os valores de outra variável variam de 0 a 100, será atribuído maior peso na análise à variável com maior intervalo.
Isso é comum quando uma variável mede algo como salário (US$ 0 a US$ 100.000) e outra variável mede algo como idade (0 a 100 anos).
Ao padronizar as variáveis, podemos ter certeza de que cada variável contribui igualmente para a análise. Existem duas maneiras comuns de normalizar (ou “escalar”) variáveis:
- Normalização Mín-Máx: (X – min(X)) / (max(X) – min(X))
- Padronização do escore Z: (X – μ) / σ
Mostraremos então como implementar essas duas técnicas em R.
Como normalizar (ou “escalar”) variáveis em R
Para cada um dos exemplos a seguir, usaremos a íris do conjunto de dados R integrado para ilustrar como normalizar ou dimensionar variáveis em R:
#view first six rows of iris dataset
head(iris)
# 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
#3 4.7 3.2 1.3 0.2 setosa
#4 4.6 3.1 1.5 0.2 setosa
#5 5.0 3.6 1.4 0.2 setosa
#6 5.4 3.9 1.7 0.4 setosa
Normalização Mín-Máx.
A fórmula para normalização min-max é:
(X – min(X))/(máx(X) – min(X))
Para cada valor de uma variável, simplesmente encontramos a distância entre esse valor e o valor mínimo e depois dividimos pelo intervalo.
Para implementar isso em R, podemos definir uma função simples e então usar laply para aplicar essa função às colunas do conjunto de dados iris que desejamos:
#define Min-Max normalization function min_max_norm <- function (x) { (x - min(x)) / (max(x) - min(x)) } #apply Min-Max normalization to first four columns in iris dataset iris_norm <- as.data.frame(lapply(iris[1:4], min_max_norm)) #view first six rows of normalized iris dataset head(iris_norm) # Sepal.Length Sepal.Width Petal.Length Petal.Width #1 0.22222222 0.6250000 0.06779661 0.04166667 #2 0.16666667 0.4166667 0.06779661 0.04166667 #3 0.11111111 0.5000000 0.05084746 0.04166667 #4 0.08333333 0.4583333 0.08474576 0.04166667 #5 0.19444444 0.6666667 0.06779661 0.04166667 #6 0.30555556 0.7916667 0.11864407 0.12500000
Observe que cada uma das colunas agora possui valores entre 0 e 1. Observe também que a quinta coluna “Espécies” foi removida deste quadro de dados. Podemos adicioná-lo facilmente usando o seguinte código:
#add back Species column iris_norm$Species <- iris$Species #view first six rows of iris_norm head(iris_norm) # Sepal.Length Sepal.Width Petal.Length Petal.Width Species #1 0.22222222 0.6250000 0.06779661 0.04166667 setosa #2 0.16666667 0.4166667 0.06779661 0.04166667 setosa #3 0.11111111 0.5000000 0.05084746 0.04166667 setosa #4 0.08333333 0.4583333 0.08474576 0.04166667 setosa #5 0.19444444 0.6666667 0.06779661 0.04166667 setosa #6 0.30555556 0.7916667 0.11864407 0.12500000 setosa
Padronização de pontuação Z
A desvantagem da técnica de normalização min-max é que ela aproxima os valores dos dados da média. Se quisermos garantir que os valores discrepantes sejam mais ponderados do que outros valores, uma padronização de pontuação z é uma técnica melhor para implementar.
A fórmula para padronizar o escore z é a seguinte:
(X – μ) / σ
Para cada valor de uma variável, simplesmente subtraímos o valor médio da variável e depois dividimos pelo desvio padrão da variável.
Para implementar isso em R, temos várias opções:
1. Padronize uma variável
Se quisermos simplesmente padronizar uma variável em um conjunto de dados, como Sepal.Width no conjunto de dados iris , podemos usar o seguinte código:
#standardize Sepal.Width iris$Sepal.Width <- (iris$Sepal.Width - mean(iris$Sepal.Width)) / sd(iris$Sepal.Width) head(iris) # Sepal.Length Sepal.Width Petal.Length Petal.Width Species #1 5.1 1.01560199 1.4 0.2 setosa #2 4.9 -0.13153881 1.4 0.2 setosa #3 4.7 0.32731751 1.3 0.2 setosa #4 4.6 0.09788935 1.5 0.2 setosa #5 5.0 1.24503015 1.4 0.2 setosa #6 5.4 1.93331463 1.7 0.4 setosa
Os valores Sepal.Width agora são escalonados de forma que a média seja 0 e o desvio padrão seja 1. Podemos até verificar isso se quisermos:
#find mean of Sepal.Width mean(iris$Sepal.Width) #[1] 2.034094e-16 #basically zero #find standard deviation of Sepal.Width sd(iris$Sepal.Width) #[1] 1
2. Padronize múltiplas variáveis usando a função de escala
Para normalizar múltiplas variáveis, pode-se simplesmente usar a função de escala . Por exemplo, o código a seguir mostra como dimensionar as primeiras quatro colunas do conjunto de dados da íris :
#standardize first four columns of iris dataset
iris_standardize <- as.data.frame(scale(iris[1:4]))
#view first six rows of standardized dataset
head(iris_standardize)
# Sepal.Length Sepal.Width Petal.Length Petal.Width
#1 -0.8976739 1.01560199 -1.335752 -1.311052
#2 -1.1392005 -0.13153881 -1.335752 -1.311052
#3 -1.3807271 0.32731751 -1.392399 -1.311052
#4 -1.5014904 0.09788935 -1.279104 -1.311052
#5 -1.0184372 1.24503015 -1.335752 -1.311052
#6 -0.5353840 1.93331463 -1.165809 -1.048667
Observe que a função de escala , por padrão, tenta normalizar cada coluna em um quadro de dados. Portanto, receberíamos um erro se tentássemos usar scale(iris) porque a coluna Species não é numérica e não pode ser padronizada:
scale(iris) #Error in colMeans(x, na.rm = TRUE): 'x' must be numeric
No entanto, é possível padronizar apenas certas variáveis em um quadro de dados enquanto mantém todas as outras variáveis iguais usando o pacote dplyr . Por exemplo, o código a seguir padroniza as variáveis Sepal.Width e Sepal.Length , mantendo todas as outras variáveis iguais:
#load dplyr package library(dplyr) #standardize Sepal.Width and Sepal.Length iris_new <- iris %>% mutate_each_(list(~scale(.) %>% as.vector), vars = c("Sepal.Width","Sepal.Length")) #view first six rows of new data frame head(iris_new) # Sepal.Length Sepal.Width Petal.Length Petal.Width Species #1 -0.8976739 1.01560199 1.4 0.2 setosa #2 -1.1392005 -0.13153881 1.4 0.2 setosa #3 -1.3807271 0.32731751 1.3 0.2 setosa #4 -1.5014904 0.09788935 1.5 0.2 setosa #5 -1.0184372 1.24503015 1.4 0.2 setosa #6 -0.5353840 1.93331463 1.7 0.4 setosa
Observe que Sepal.Length e Sepal.Width são padronizados de forma que ambas as variáveis tenham média 0 e desvio padrão de 1, enquanto as outras três variáveis no quadro de dados permanecem inalteradas.