transformar - Estandarizar las columnas de datos en R
normalize data in r (10)
Tengo un conjunto de datos llamado spam
que contiene 58 columnas y aproximadamente 3500 filas de datos relacionados con mensajes de spam.
Planeo ejecutar alguna regresión lineal en este conjunto de datos en el futuro, pero me gustaría hacer un preprocesamiento de antemano y estandarizar las columnas para tener una media cero y una unidad de varianza.
Me han dicho que la mejor manera de hacerlo es con R, por lo que me gustaría preguntar cómo puedo lograr la normalización con R ? Ya tengo los datos cargados correctamente y solo estoy buscando algunos paquetes o métodos para realizar esta tarea.
Al darme cuenta de que la pregunta es antigua y que se acepta una respuesta, proporcionaré otra respuesta para referencia.
scale
está limitada por el hecho de que escala todas las variables . La siguiente solución permite escalar solo nombres de variables específicos mientras se conservan otras variables sin cambios (y los nombres de las variables se pueden generar dinámicamente):
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
que me da esto:
> 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
y
> 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 : respondió el comentario de Julian: el resultado de la scale
es la matriz Nx1, por lo que idealmente deberíamos agregar un as.vector
para as.vector
a convertir el tipo de matriz en un vector. Gracias Julian!
Antes de que encontrara este hilo, tuve el mismo problema. Tenía tipos de columnas dependientes del usuario, así que escribí un ciclo for
revisarlas y obtener las columnas necesarias '' scale
''. Probablemente haya mejores formas de hacerlo, pero esto resolvió el problema muy bien:
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
es una parte necesaria, porque resultó que scale
hace rownames x 1
matrix, que generalmente no es lo que quiere tener en su data.frame
.
Con dplyr
v0.7.4 todas las variables se pueden escalar usando 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
Las variables específicas se pueden excluir usando 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
Creado en 2018-04-24 por el paquete reprex (v0.2.0).
Cuando utilicé la solución indicada por Dason, en lugar de obtener un marco de datos como resultado, obtuve un vector de números (los valores escalados de mi df).
En caso de que alguien esté teniendo el mismo problema, debe agregar as.data.frame () al código, así:
df.scaled <- as.data.frame(scale(df))
¡Espero que esto sea útil para personas que tienen el mismo problema!
El paquete ''Caret'' proporciona métodos para preprocesar datos (por ejemplo, centrado y escalado). También podría usar el siguiente código:
library(caret)
# Assuming goal class is column 10
preObj <- preProcess(data[, -10], method=c("center", "scale"))
newData <- predict(preObj, data[, -10])
Más detalles: http://www.inside-r.org/node/86978
Esto tiene 3 años. Aún así, siento que debo agregar lo siguiente:
La normalización más común es la transformación z , donde se resta la media y se divide por la desviación estándar de la variable. El resultado tendrá mean = 0 y sd = 1.
Para eso, no necesitas ningún paquete.
zVar <- (myVar - mean(myVar)) / sd(myVar)
Eso es.
La escala se puede usar tanto para el marco de datos completo como para columnas específicas. Para columnas específicas, se puede usar el siguiente código:
trainingSet[, 3:7] = scale(trainingSet[, 3:7]) # For column 3 to 7
trainingSet[, 8] = scale(trainingSet[, 8]) # For column 8
Marco de datos completo
trainingSet <- scale(trainingSet)
También puede normalizar fácilmente los datos utilizando datos. Función de normalización en el paquete clusterSim. Proporciona un método diferente de normalización de datos.
data.Normalization (x,type="n0",normalization="column")
Argumentos
X
vector, matriz o tipo de conjunto de datos
tipo de normalización: n0 - sin normalización
n1 - estandarización ((x-mean) / sd)
n2 - estandarización posicional ((x-mediana) / enojada)
n3 - unitización ((x-media) / rango)
n3a - unitización posicional ((x-mediana) / rango)
n4 - unitización con mínimo cero ((x-min) / rango)
n5 - normalización en el rango <-1,1> ((x-media) / max (abs (x-media)))
n5a - normalización posicional en rango <-1,1> ((x-mediana) / max (abs (x-mediana)))
n6 - transformación del cociente (x / sd)
n6a - transformación del cociente posicional (x / enojado)
n7 - transformación del cociente (x / rango)
n8 - transformación del cociente (x / max)
n9 - transformación del cociente (x / media)
n9a - transformación del cociente posicional (x / mediana)
n10 - transformación del cociente (x / suma)
n11 - transformación del cociente (x / sqrt (SSQ))
n12 - normalización ((x-mean) / sqrt (sum ((x-mean) ^ 2)))
n12a - normalización posicional ((x-mediana) / sqrt (suma ((x-mediana) ^ 2)))
n13 - normalización con cero siendo el punto central ((x-rango medio) / (rango / 2))
normalización
"columna" - normalización por variable, "fila" - normalización por objeto
Tengo que suponer que quisiste decir que querías una media de 0 y una desviación estándar de 1. Si tus datos están en un marco de datos y todas las columnas son numéricas, puedes simplemente llamar a la función de scale
en los datos para hacer lo que quieras .
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)
El uso de funciones integradas es elegante. Como este gato:
Use el paquete "recommenderlab". Descargue e instale el paquete. Este paquete tiene un comando "Normalizar" en construido. También le permite elegir uno de los muchos métodos para la normalización, a saber, ''centro'' o ''Z-score''. Siga el siguiente ejemplo:
## 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=”), items=paste(''i'', 1:10, sep=”)))
## 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")