我有一个名为spam的数据集,其中包含58列和约3500行与垃圾邮件相关的数据。

我计划将来在这个数据集上运行一些线性回归,但我想事先做一些预处理,并将列标准化,使其具有零平均值和单位方差。

有人告诉我,最好的方法是用R,所以我想问,如何用R实现归一化?我已经正确加载了数据,我只是在寻找一些包或方法来执行这个任务。


当前回答

折叠包提供了最快的缩放函数-在c++中使用Welfords在线算法实现:

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

library(collapse)
library(microbenchmark)
microbenchmark(fscale(dat), scale(dat))

Unit: milliseconds
        expr       min       lq      mean    median        uq      max neval cld
 fscale(dat)  27.86456  29.5864  38.96896  30.80421  43.79045 313.5729   100  a 
  scale(dat) 357.07130 391.0914 489.93546 416.33626 625.38561 793.2243   100   b

此外:fscale是S3通用的向量、矩阵和数据帧,还支持分组和/或加权缩放操作,以及缩放到任意均值和标准偏差。

其他回答

在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)。

这是三年前的。不过,我还是觉得有必要补充以下几点:

最常见的归一化是z变换,其中减去平均值并除以变量的标准差。结果将是mean=0, sd=1。

为此,你不需要任何包装。

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

就是这样。

再说一次,尽管这是一个老问题,但它非常相关!我发现了一个简单的方法来规范化某些列,而不需要任何包:

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列已经规范化。不需要软件包:-)

在我碰巧发现这条线索之前,我也有同样的问题。我有用户依赖的列类型,所以我写了一个for循环遍历它们并获得所需的列。也许有更好的方法,但这个方法很好地解决了问题:

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

作为。向量是一个必要的部分,因为scale做rownames x 1矩阵这通常不是你想要的在data。frame中。

您还可以使用数据轻松地将数据规范化。clusterSim包中的归一化函数。它提供了不同的数据规范化方法。

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

参数

x 向量,矩阵或数据集 类型 归一化类型: N0 -没有归一化

N1 -标准化((x-mean)/sd)

N2 -位置标准化((x-median)/mad)

N3 -单元化((x-mean)/range)

N3a -位置单元化(x-median /range)

N4 -最小值为零的单元化((x-min)/范围)

N5 -归一化范围<-1,1> ((x-mean)/max(abs(x-mean)))

N5a -位置归一化范围<-1,1> ((x-median)/max(abs(x-median)))

N6 -商变换(x/sd)

N6a -位置商变换(x/mad)

N7 -商变换(x/range)

N8 -商变换(x/max)

N9 -商数变换(x/mean)

N9a -位置商变换(x/median)

N10 -商变换(x/sum)

n11 -商变换(x/√(SSQ))

N12 -归一化((x-mean)/根号(sum((x-mean)^2))

N12a -位置归一化((x-median)/平方根(sum(x-median)^2))

N13 -归一化,中心点为0 ((x-midrange)/(range/2))

归一化 "列" -由变量归一化,"行" -由对象归一化