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 que tengan media cero y varianza unitaria.
Me han dicho que la mejor manera de hacerlo es con R, así 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.
fuente
Al darme cuenta de que la pregunta es antigua y se acepta una respuesta, proporcionaré otra respuesta como referencia.
scale
está limitado por el hecho de que escala todas las variables . La solución a continuación permite escalar solo nombres de variables específicos mientras conserva otras variables sin cambios (y los nombres de las variables podrían generarse dinámicamente):lo que me da esto:
y
EDIT 1 (2016) : Abordó el comentario de Julian: la salida de
scale
es una matriz Nx1, por lo que idealmente deberíamos agregar unas.vector
para convertir el tipo de matriz en un tipo de vector. Gracias julian!EDIT 2 (2019) : Citando el comentario de Duccio A.: Para la última versión de dplyr (versión 0.8) necesita cambiar dplyr :: funcs con lista, como
dat %>% mutate_each_(list(~scale(.) %>% as.vector), vars=c("y","z"))
EDIT 3 (2020) : Gracias a @mj_whales: la solución anterior está en desuso y ahora tenemos que usarla
mutate_at
.fuente
f(g(x))
, se vería mejor si uno escribex %>% g %>% f
. En otras palabras,dat %>% mutate_each_(funs(scale),vars=c("y","z"))
es justomutate_each_(dat,funs(scale),vars=c("y","z"))
. El operador ayuda mucho cuando una cadena es muy larga ya quef(g(h(i(j(x)))))
puede ser muy difícil de leer.dplyr
(versión 0.8) que necesita para el cambiodplyr::funcs
conlist
, comodat %>% mutate_each_(list(~scale(.) %>% as.vector), vars=c("y","z"))
mutate_each_()
ahora está en desuso. Puedes usarmutate_at()
en su lugar. La nueva forma de hacerlo sería:dat2 <- dat %>% mutate_at(c("y", "z"), scale)
Esto tiene 3 años. Aún así, siento que tengo que 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 su variable. El resultado tendrá media = 0 y sd = 1.
Para eso, no necesitas ningún paquete.
Eso es.
fuente
mutate(var = (var - mean(var))/sd(var))
.myVar <- (zVar * sd(zVar)) + mean(zVar)
, ¿verdad?newVar <- (zVar * sd(myVar)) + mean(myVar)
. Tienes que usar la media / sd original. A medida que lo escribiste, multiplicarássd(zVar)=1
y agregarásmean(zVar)=0
, para que nada cambie :)El paquete 'Caret' proporciona métodos para preprocesar datos (por ejemplo, centrado y escalado). También puede usar el siguiente código:
Más detalles: http://www.inside-r.org/node/86978
fuente
Cuando utilicé la solución establecida 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 tenga el mismo problema, debe agregar as.data.frame () al código, así:
¡Espero que esto sea útil para las personas que tienen el mismo problema!
fuente
train_dt[-24] <- scale(train_dt[-24])
donde "24" es el número de columna que se excluiráPuede normalizar fácilmente los datos también utilizando datos. Función de normalización en el paquete clusterSim. Proporciona diferentes métodos de normalización de datos.
Argumentos
x tipo de normalización
tipo vector, matriz o conjunto
de datos: n0 - sin normalización
n1 - estandarización ((x-mean) / sd)
n2 - estandarización posicional ((x-mediana) / mad)
n3 - unitización ((media x) / rango)
n3a - unitización posicional ((mediana de x) / rango)
n4 - unitización con cero mínimo ((x-min) / rango)
n5 - normalización en el rango <-1,1> ((x-mean) / max (abs (x-mean)))
n5a - normalización posicional en el rango <-1,1> ((x-mediana) / max (abs (x-mediana)))
n6 - transformación del cociente (x / sd)
n6a - transformación del cociente posicional (x / mad)
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 como punto central ((rango medio x) / (rango / 2))
normalización
"columna" - normalización por variable, "fila" - normalización por objeto
fuente
Con
dplyr
v0.7.4 todas las variables se pueden escalar usandomutate_all()
:Las variables específicas se pueden excluir usando
mutate_at()
:Creado el 24/04/2018 por el paquete reprex (v0.2.0).
fuente
Una vez más, a pesar de que esta es una vieja pregunta, ¡es muy relevante! Y he encontrado una manera simple de normalizar ciertas columnas sin la necesidad de ningún paquete:
Por ejemplo
Verá que las columnas y y z se han normalizado. No se necesitan paquetes :-)
fuente
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:
Marco de datos completo
fuente
El
dplyr
paquete tiene dos funciones que hacen esto.Para mutar columnas específicas de una tabla de datos, puede usar la función
mutate_at()
. Para mutar todas las columnas, puede usarmutate_all
.El siguiente es un breve ejemplo para usar estas funciones para estandarizar datos.
Mutar columnas específicas:
Mutar todas las columnas:
fuente
Antes de encontrar este hilo, tuve el mismo problema. Tenía tipos de columnas dependientes del usuario, así que escribí un
for
bucle que los revisaba y obtenía las columnas necesariasscale
'd. Probablemente hay mejores formas de hacerlo, pero esto resolvió el problema perfectamente:as.vector
es una parte necesaria, porque resultó quescale
hace unarownames x 1
matriz que generalmente no es lo que quieres tener en tudata.frame
.fuente
Utiliza el paquete "recomenderlab". Descargue e instale el paquete. Este paquete tiene un comando "Normalizar" incorporado. También le permite elegir uno de los muchos métodos de normalización, a saber, 'centro' o 'puntaje Z'. Siga el siguiente ejemplo:
fuente
La función de normalización del paquete BBMisc fue la herramienta adecuada para mí, ya que puede manejar los valores de NA.
Aquí está cómo usarlo:
Dado el siguiente conjunto de datos,
Los valores normalizados se pueden obtener así:
donde el método calculado a mano simplemente ignora las colmuns que contienen NA:
(NormalizedHuman se hace una lista de NA ...)
Con respecto a la selección de columnas específicas para el cálculo, se puede emplear un método genérico como este:
fuente
@BBKim dio la mejor respuesta, pero se puede hacer más corto. Me sorprende que a nadie se le haya ocurrido todavía.
dat <- data.frame(x = rnorm(10, 30, .2), y = runif(10, 3, 5)) dat <- apply(dat, 2, function(x) (x - mean(x)) / sd(x))
fuente