我有一个名为spam的数据集,其中包含58列和约3500行与垃圾邮件相关的数据。
我计划将来在这个数据集上运行一些线性回归,但我想事先做一些预处理,并将列标准化,使其具有零平均值和单位方差。
有人告诉我,最好的方法是用R,所以我想问,如何用R实现归一化?我已经正确加载了数据,我只是在寻找一些包或方法来执行这个任务。
我有一个名为spam的数据集,其中包含58列和约3500行与垃圾邮件相关的数据。
我计划将来在这个数据集上运行一些线性回归,但我想事先做一些预处理,并将列标准化,使其具有零平均值和单位方差。
有人告诉我,最好的方法是用R,所以我想问,如何用R实现归一化?我已经正确加载了数据,我只是在寻找一些包或方法来执行这个任务。
当前回答
在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
由reprex包于2018-04-24创建(v0.2.0)。
其他回答
我假设你想要的是均值为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)
使用内置函数是有品位的。比如这只猫:
下面的代码可能是实现这一目标的最短方法。
dataframe <- apply(dataframe, 2, scale)
使用“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")
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
当我使用Dason提出的解决方案时,而不是得到一个数据帧作为结果,我得到了一个数字向量(我的df的缩放值)。
为了防止有人遇到同样的问题,你必须在代码中添加as.data.frame(),就像这样:
df.scaled <- as.data.frame(scale(df))
我希望这对有同样问题的人有用!