Стандартизировать столбцы данных в R

У меня есть набор данных под названием spam, который содержит 58 столбцов и приблизительно 3500 строк данных, относящихся к спам-сообщениям.

Я планирую запустить некоторую линейную регрессию в этом наборе данных в будущем, но я бы хотел сделать предварительную обработку заранее и стандартизировать столбцы, чтобы иметь нулевое среднее и единичную дисперсию.

Мне сказали, что лучше всего это сделать с R, поэтому я хотел бы спросить , как я могу добиться нормализации с помощью R? Я уже правильно загрузил данные, и я просто ищу некоторые пакеты или методы для выполнения этой задачи.

Ответ 1

Я должен предположить, что вы хотели сказать, что вам нужно среднее значение 0 и стандартное отклонение 1. Если ваши данные находятся в фрейме данных и все столбцы являются числовыми, вы можете просто вызвать функцию scale для данных делать то, что вы хотите.

dat <- data.frame(x = rnorm(10, 30, .2), y = runif(10, 3, 5))
scaled.dat <- scale(dat)

# check that we get mean of 0 and sd of 1
colMeans(scaled.dat)  # faster version of apply(scaled.dat, 2, mean)
apply(scaled.dat, 2, sd)

Использование встроенных функций классно. Как этот кот:

enter image description here

Ответ 2

Понимая, что вопрос старый и один ответ принят, я предоставлю другой для справки.

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

library(dplyr)

set.seed(1234)
dat <- data.frame(x = rnorm(10, 30, .2), 
                  y = runif(10, 3, 5),
                  z = runif(10, 10, 20))
dat

dat2 <- dat %>% mutate_each_(funs(scale(.) %>% as.vector), 
                             vars=c("y","z"))
dat2

что дает мне это:

> dat
          x        y        z
1  29.75859 3.633225 14.56091
2  30.05549 3.605387 12.65187
3  30.21689 3.318092 13.04672
4  29.53086 3.079992 15.07307
5  30.08582 3.437599 11.81096
6  30.10121 4.621197 17.59671
7  29.88505 4.051395 12.01248
8  29.89067 4.829316 12.58810
9  29.88711 4.662690 19.92150
10 29.82199 3.091541 18.07352

и

> dat2 <- dat %>% mutate_each_(funs(scale(.) %>% as.vector), 
>                              vars=c("y","z"))
> dat2
          x          y           z
1  29.75859 -0.3004815 -0.06016029
2  30.05549 -0.3423437 -0.72529604
3  30.21689 -0.7743696 -0.58772361
4  29.53086 -1.1324181  0.11828039
5  30.08582 -0.5946582 -1.01827752
6  30.10121  1.1852038  0.99754666
7  29.88505  0.3283513 -0.94806607
8  29.89067  1.4981677 -0.74751378
9  29.88711  1.2475998  1.80753470
10 29.82199 -1.1150515  1.16367556

EDIT 1 (2016): Адресованный юлианский комментарий: вывод scale представляет собой матрицу Nx1, поэтому в идеале мы должны добавить as.vector для преобразования типа матрицы обратно в векторный тип. Спасибо, Джулиан!

ОБНОВЛЕНИЕ 2 (2019): Цитировать Duccio A. комментарий: Для последней версии dplyr (версия 0.8) вам нужно изменить dplyr :: funcs со списком, например, dat %>% mutate_each_(list(~scale(.) %>% as.vector), vars=c("y","z"))

Ответ 3

Это 3 года. Тем не менее, я чувствую, что должен добавить следующее:

Наиболее распространенной нормировкой является z-преобразование, где вы вычитаете среднее значение и делите на стандартное отклонение переменной. Результат будет иметь среднее value = 0 и sd = 1.

Для этого вам не нужен пакет.

zVar <- (myVar - mean(myVar)) / sd(myVar)

Что это.

Ответ 4

Пакет Caret предоставляет методы для предварительной обработки данных (например, центрирование и масштабирование). Вы также можете использовать следующий код:

library(caret)
# Assuming goal class is column 10
preObj <- preProcess(data[, -10], method=c("center", "scale"))
newData <- predict(preObj, data[, -10])

Подробнее: http://www.inside-r.org/node/86978

Ответ 5

Когда я использовал решение, указанное Dason, вместо получения кадра данных в результате, я получил вектор чисел (масштабированные значения моего df).

Если у кого-то возникают те же проблемы, вам необходимо добавить as.data.frame() в код, например:

df.scaled <- as.data.frame(scale(df))

Надеюсь, это будет полезно для ppl с той же проблемой!

Ответ 6

Вы можете легко нормализовать данные и использовать данные. Функция нормирования в пакете clusterSim. Он обеспечивает различный метод нормализации данных.

    data.Normalization (x,type="n0",normalization="column")

Аргументы

х
вектор, матрица или набор данных тип
тип нормализации: n0 - без нормализации

n1 - стандартизация ((x-mean)/sd)

n2 - позиционная стандартизация ((x-median)/mad)

n3 - унификация ((среднее значение х)/диапазон)

n3a - позиционная унификация ((x-медиана)/диапазон)

n4 - унификация с нулевым минимумом ((x-min)/range)

n5 - нормализация в диапазоне от -1 -1,1 ((среднее значение x)/max (абс (среднее по x)))

n5a - позиционная нормализация в диапазоне < -1,1 > ((x-median)/max (абс (x-медиана)))

n6 - факторное преобразование (x/sd)

n6a - трансформация позиционного отношения (x/mad)

n7 - факторное преобразование (x/range)

n8 - факторное преобразование (x/max)

n9 - факторное преобразование (x/mean)

n9a - преобразование позиционного отношения (x/медиана)

n10 - факторное преобразование (x/sum)

n11 - преобразование частного (x/sqrt (SSQ))

n12 - нормализация ((x-mean)/sqrt (sum ((x-mean) ^ 2)))

n12a - позиционная нормализация ((x-медиана)/sqrt (сумма ((x-медиана) ^ 2)))

n13 - нормализация с нулем, являющаяся центральной точкой ((x-midrange)/(диапазон/2))

Нормализация
"column" - нормализация переменной, "строка" - нормализация по объекту

Ответ 7

С помощью dplyr v0.7.4 все переменные можно масштабировать с помощью mutate_all():

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(tibble)

set.seed(1234)
dat <- tibble(x = rnorm(10, 30, .2), 
              y = runif(10, 3, 5),
              z = runif(10, 10, 20))

dat %>% mutate_all(scale)
#> # A tibble: 10 x 3
#>         x      y       z
#>     <dbl>  <dbl>   <dbl>
#>  1 -0.827 -0.300 -0.0602
#>  2  0.663 -0.342 -0.725 
#>  3  1.47  -0.774 -0.588 
#>  4 -1.97  -1.13   0.118 
#>  5  0.816 -0.595 -1.02  
#>  6  0.893  1.19   0.998 
#>  7 -0.192  0.328 -0.948 
#>  8 -0.164  1.50  -0.748 
#>  9 -0.182  1.25   1.81  
#> 10 -0.509 -1.12   1.16

Определенные переменные могут быть исключены с помощью mutate_at():

dat %>% mutate_at(scale, .vars = vars(-x))
#> # A tibble: 10 x 3
#>        x      y       z
#>    <dbl>  <dbl>   <dbl>
#>  1  29.8 -0.300 -0.0602
#>  2  30.1 -0.342 -0.725 
#>  3  30.2 -0.774 -0.588 
#>  4  29.5 -1.13   0.118 
#>  5  30.1 -0.595 -1.02  
#>  6  30.1  1.19   0.998 
#>  7  29.9  0.328 -0.948 
#>  8  29.9  1.50  -0.748 
#>  9  29.9  1.25   1.81  
#> 10  29.8 -1.12   1.16

Создано в 2018-04-24 пакетом представлений (v0.2.0).

Ответ 8

Опять же, хотя это старый вопрос, он очень актуален! И я нашел простой способ нормализовать определенные столбцы без необходимости каких-либо пакетов:

normFunc <- function(x){(x-mean(x, na.rm = T))/sd(x, na.rm = T)}

Например,

x<-rnorm(10,14,2)
y<-rnorm(10,7,3)
z<-rnorm(10,18,5)
df<-data.frame(x,y,z)

df[2:3] <- apply(df[2:3], 2, normFunc)

Вы увидите, что столбцы y и z нормализованы. Пакеты не нужны :-)

Ответ 9

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

trainingSet[, 3:7] = scale(trainingSet[, 3:7]) # For column 3 to 7
trainingSet[, 8] = scale(trainingSet[, 8]) # For column 8 

Полный фрейм данных

trainingSet <- scale(trainingSet)

Ответ 10

Прежде чем я нашел эту тему, у меня была та же проблема. У меня были пользовательские типы столбцов, поэтому я написал цикл for, проходящий через них, и получив необходимые столбцы scale 'd. Есть, вероятно, лучшие способы сделать это, но это решило проблему просто отлично:

 for(i in 1:length(colnames(df))) {
        if(class(df[,i]) == "numeric" || class(df[,i]) == "integer") {
            df[,i] <- as.vector(scale(df[,i])) }
        }

as.vector - необходимая часть, потому что оказалось, что scale имеет матрицу rownames x 1, которая обычно не является тем, что вы хотите иметь в своем data.frame.

Ответ 11

Пакет dplyr имеет две функции, которые делают это.

> require(dplyr)

Чтобы изменить определенные столбцы таблицы данных, вы можете использовать функцию mutate_at(). Чтобы изменить все столбцы, вы можете использовать mutate_all.

Ниже приведен краткий пример использования этих функций для стандартизации данных.

Изменять конкретные столбцы:

dt = data.table(a = runif(3500), b = runif(3500), c = runif(3500))
dt = data.table(dt %>% mutate_at(vars("a", "c"), scale)) # can also index columns by number, e.g., vars(c(1,3))

> apply(dt, 2, mean)
            a             b             c 
 1.783137e-16  5.064855e-01 -5.245395e-17 

> apply(dt, 2, sd)
        a         b         c 
1.0000000 0.2906622 1.0000000 

Изменить все столбцы:

dt = data.table(a = runif(3500), b = runif(3500), c = runif(3500))
dt = data.table(dt %>% mutate_all(scale))

> apply(dt, 2, mean)
            a             b             c 
-1.728266e-16  9.291994e-17  1.683551e-16 

> apply(dt, 2, sd)
a b c 
1 1 1 

Ответ 12

Используйте пакет "recommenderlab". Загрузите и установите пакет. Этот пакет имеет команду "Нормализовать" в построенной. Он также позволяет вам выбрать один из многих методов нормализации, а именно "центр" или "Z-оценка", Выполните следующий пример:

## create a matrix with ratings
m <- matrix(sample(c(NA,0:5),50, replace=TRUE, prob=c(.5,rep(.5/6,6))),nrow=5, ncol=10, dimnames = list(users=paste('u', 1:5, sep=&rdquo;), items=paste('i', 1:10, sep=&rdquo;)))

## do normalization
r <- as(m, "realRatingMatrix")
#here, 'centre' is the default method
r_n1 <- normalize(r) 
#here "Z-score" is the used method used
r_n2 <- normalize(r, method="Z-score")

r
r_n1
r_n2

## show normalized data
image(r, main="Raw Data")
image(r_n1, main="Centered")
image(r_n2, main="Z-Score Normalization")

Ответ 13

Функция normalize из пакета BBMisc была для меня подходящим инструментом, поскольку она может работать со значениями NA.

Вот как это можно использовать:

Учитывая следующий набор данных,

    ASR_API     <- c("CV",  "F",    "IER",  "LS-c", "LS-o")
    Human       <- c(NA,    5.8,    12.7,   NA, NA)
    Google      <- c(23.2,  24.2,   16.6,   12.1,   28.8)
    GoogleCloud <- c(23.3,  26.3,   18.3,   12.3,   27.3)
    IBM     <- c(21.8,  47.6,   24.0,   9.8,    25.3)
    Microsoft   <- c(29.1,  28.1,   23.1,   18.8,   35.9)
    Speechmatics    <- c(19.1,  38.4,   21.4,   7.3,    19.4)
    Wit_ai      <- c(35.6,  54.2,   37.4,   19.2,   41.7)
    dt     <- data.table(ASR_API,Human, Google, GoogleCloud, IBM, Microsoft, Speechmatics, Wit_ai)
> dt
   ASR_API Human Google GoogleCloud  IBM Microsoft Speechmatics Wit_ai
1:      CV    NA   23.2        23.3 21.8      29.1         19.1   35.6
2:       F   5.8   24.2        26.3 47.6      28.1         38.4   54.2
3:     IER  12.7   16.6        18.3 24.0      23.1         21.4   37.4
4:    LS-c    NA   12.1        12.3  9.8      18.8          7.3   19.2
5:    LS-o    NA   28.8        27.3 25.3      35.9         19.4   41.7

Нормализованные значения можно получить следующим образом:

> dtn <- normalize(dt, method = "standardize", range = c(0, 1), margin = 1L, on.constant = "quiet")
> dtn
   ASR_API      Human     Google GoogleCloud         IBM  Microsoft Speechmatics      Wit_ai
1:      CV         NA  0.3361245   0.2893457 -0.28468670  0.3247336  -0.18127203 -0.16032655
2:       F -0.7071068  0.4875320   0.7715885  1.59862532  0.1700986   1.55068347  1.31594762
3:     IER  0.7071068 -0.6631646  -0.5143923 -0.12409420 -0.6030768   0.02512682 -0.01746131
4:    LS-c         NA -1.3444981  -1.4788780 -1.16064578 -1.2680075  -1.24018782 -1.46198764
5:    LS-o         NA  1.1840062   0.9323361 -0.02919864  1.3762521  -0.15435044  0.32382788

где метод вычисления вручную игнорирует колмуны, содержащие NA:

> dt %>% mutate(normalizedHuman = (Human - mean(Human))/sd(Human)) %>% 
+ mutate(normalizedGoogle = (Google - mean(Google))/sd(Google)) %>% 
+ mutate(normalizedGoogleCloud = (GoogleCloud - mean(GoogleCloud))/sd(GoogleCloud)) %>% 
+ mutate(normalizedIBM = (IBM - mean(IBM))/sd(IBM)) %>% 
+ mutate(normalizedMicrosoft = (Microsoft - mean(Microsoft))/sd(Microsoft)) %>% 
+ mutate(normalizedSpeechmatics = (Speechmatics - mean(Speechmatics))/sd(Speechmatics)) %>% 
+ mutate(normalizedWit_ai = (Wit_ai - mean(Wit_ai))/sd(Wit_ai))
  ASR_API Human Google GoogleCloud  IBM Microsoft Speechmatics Wit_ai normalizedHuman normalizedGoogle
1      CV    NA   23.2        23.3 21.8      29.1         19.1   35.6              NA        0.3361245
2       F   5.8   24.2        26.3 47.6      28.1         38.4   54.2              NA        0.4875320
3     IER  12.7   16.6        18.3 24.0      23.1         21.4   37.4              NA       -0.6631646
4    LS-c    NA   12.1        12.3  9.8      18.8          7.3   19.2              NA       -1.3444981
5    LS-o    NA   28.8        27.3 25.3      35.9         19.4   41.7              NA        1.1840062
  normalizedGoogleCloud normalizedIBM normalizedMicrosoft normalizedSpeechmatics normalizedWit_ai
1             0.2893457   -0.28468670           0.3247336            -0.18127203      -0.16032655
2             0.7715885    1.59862532           0.1700986             1.55068347       1.31594762
3            -0.5143923   -0.12409420          -0.6030768             0.02512682      -0.01746131
4            -1.4788780   -1.16064578          -1.2680075            -1.24018782      -1.46198764
5             0.9323361   -0.02919864           1.3762521            -0.15435044       0.32382788

(нормализованный человек составлен список НС...)

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

data_vars <- df_full %>% dplyr::select(-ASR_API,-otherVarNotToBeUsed)
meta_vars <- df_full %>% dplyr::select(ASR_API,otherVarNotToBeUsed)
data_varsn <- normalize(data_vars, method = "standardize", range = c(0, 1), margin = 1L, on.constant = "quiet")
dtn <- cbind(meta_vars,data_varsn)