我有一个名为spam的数据集,其中包含58列和约3500行与垃圾邮件相关的数据。
我计划将来在这个数据集上运行一些线性回归,但我想事先做一些预处理,并将列标准化,使其具有零平均值和单位方差。
有人告诉我,最好的方法是用R,所以我想问,如何用R实现归一化?我已经正确加载了数据,我只是在寻找一些包或方法来执行这个任务。
我有一个名为spam的数据集,其中包含58列和约3500行与垃圾邮件相关的数据。
我计划将来在这个数据集上运行一些线性回归,但我想事先做一些预处理,并将列标准化,使其具有零平均值和单位方差。
有人告诉我,最好的方法是用R,所以我想问,如何用R实现归一化?我已经正确加载了数据,我只是在寻找一些包或方法来执行这个任务。
当前回答
再说一次,尽管这是一个老问题,但它非常相关!我发现了一个简单的方法来规范化某些列,而不需要任何包:
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列已经规范化。不需要软件包:-)
其他回答
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
我假设你想要的是均值为0,标准差为1。如果你的数据在一个数据框架中,所有的列都是数值的,你可以简单地调用数据上的缩放函数来做你想做的事情。
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)
使用内置函数是有品位的。比如这只猫:
意识到这个问题已经很老了,一个答案已经被接受了,我将提供另一个答案供参考。
缩放是有限的,因为它缩放所有变量。下面的解决方案只允许缩放特定的变量名,同时保持其他变量不变(变量名可以动态生成):
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_at(c("y", "z"), ~(scale(.) %>% as.vector))
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
and
> dat2 <- dat %>% mutate_at(c("y", "z"), ~(scale(.) %>% as.vector))
> 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
编辑1(2016):处理朱利安的评论:规模的输出是Nx1矩阵,所以理想情况下,我们应该添加一个as。向量,将矩阵类型转换回向量类型。谢谢朱利安!
编辑2(2019):引用杜乔·A。对于最新的dplyr(0.8版本),您需要更改dplyr::funcs with list,如dat %>% mutate_each_(list(~scale(.) %>% as.vector), vars=c("y","z"))
EDIT 3(2020):感谢@mj_whales:旧的解决方案已弃用,现在我们需要使用mutate_at。
这是三年前的。不过,我还是觉得有必要补充以下几点:
最常见的归一化是z变换,其中减去平均值并除以变量的标准差。结果将是mean=0, sd=1。
为此,你不需要任何包装。
zVar <- (myVar - mean(myVar)) / sd(myVar)
就是这样。
使用“recommderlab”包。下载并安装软件包。 这个包内置了一个命令“Normalize”。它还允许你从众多归一化方法中选择一种即"中心"或" 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=”), 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")