Как нормализовать данные в R


В большинстве случаев, когда люди говорят о «нормализации» переменных в наборе данных, это означает, что они хотели бы масштабировать значения так, чтобы переменная имела среднее значение 0 и стандартное отклонение 1.

Наиболее распространенной причиной нормализации переменных является проведение некоторого типа многомерного анализа (т. е. вы хотите понять взаимосвязь между несколькими переменными-предикторами и переменной-откликом) и вы хотите, чтобы каждая переменная вносила равный вклад в анализ.

Когда переменные измеряются в разных масштабах, они часто не вносят одинакового вклада в анализ. Например, если значения одной переменной находятся в диапазоне от 0 до 100 000, а значения другой переменной — в диапазоне от 0 до 100, переменной с большим диапазоном будет присвоен больший вес при анализе.

Это обычное дело, когда одна переменная измеряет что-то вроде зарплаты (от 0 до 100 000 долларов), а другая переменная измеряет что-то вроде возраста (от 0 до 100 лет).

Нормируя переменные, мы можем быть уверены, что каждая переменная вносит одинаковый вклад в анализ. Два распространенных способа нормализации (или «масштабирования») переменных включают:

  • Минимальная-максимальная нормализация: (X – min(X)) / (max(X) – min(X))
  • Стандартизация Z-показателя : (X – μ) / σ

Далее мы покажем, как реализовать обе эти техники в R.

Как нормализовать (или масштабировать) переменные в R

Для каждого из следующих примеров мы будем использовать встроенную радужную оболочку набора данных R, чтобы проиллюстрировать, как нормализовать или масштабировать переменные в 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

Мин-макс нормализация

Формула нормализации мин-макс:

(Х – мин(Х))/(макс(Х) – мин(Х))

Для каждого значения переменной мы просто находим, насколько далеко это значение от минимального значения, а затем делим на диапазон.

Чтобы реализовать это в R, мы можем определить простую функцию, а затем использовать lapply , чтобы применить эту функцию к любым столбцам в наборе данных радужной оболочки , которые нам нужны:

#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

Обратите внимание, что каждый из столбцов теперь имеет значения в диапазоне от 0 до 1. Также обратите внимание, что пятый столбец «Виды» был исключен из этого фрейма данных. Мы можем легко добавить его обратно, используя следующий код:

#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

Стандартизация Z-оценки

Недостатком метода нормализации минимум-максимум является то, что он приближает значения данных к среднему значению. Если мы хотим убедиться, что выбросы получают больший вес, чем другие значения, лучше всего реализовать стандартизацию z-оценки.

Формула стандартизации z-оценки:

(X – μ) / σ

Для каждого значения переменной мы просто вычитаем среднее значение переменной, а затем делим на стандартное отклонение переменной.

Чтобы реализовать это в R, у нас есть несколько разных вариантов:

1. Стандартизируйте одну переменную

Если мы просто хотим стандартизировать одну переменную в наборе данных, например, Sepal.Width в наборе данных радужной оболочки , мы можем использовать следующий код:

#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

Значения Sepal.Width теперь масштабируются таким образом, что среднее значение равно 0, а стандартное отклонение равно 1. Мы даже можем проверить это, если захотим:

#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. Стандартизируйте несколько переменных, используя функцию масштабирования.

Чтобы стандартизировать несколько переменных, мы можем просто использовать функцию масштабирования.Например, следующий код показывает, как масштабировать первые четыре столбца набора данных радужной оболочки :

#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

Обратите внимание, что функция масштабирования по умолчанию пытается стандартизировать каждый столбец во фрейме данных. Таким образом, мы получили бы ошибку, если бы попытались использовать масштаб (радужную оболочку) , потому что столбец « Виды » не является числовым и не может быть стандартизирован:

scale(iris)

#Error in colMeans(x, na.rm = TRUE) : 'x' must be numeric

Однако с помощью пакета dplyr можно стандартизировать только определенные переменные во фрейме данных, сохраняя при этом неизменными все остальные переменные. Например, следующий код стандартизирует переменные Sepal.Width и Sepal.Length , сохраняя при этом все остальные переменные одинаковыми:

#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

Обратите внимание, что Sepal.Length и Sepal.Width стандартизированы таким образом, что обе переменные имеют среднее значение 0 и стандартное отклонение 1, в то время как другие три переменные во фрейме данных остаются неизменными.