Hos*_*ser 185 r normalization
我有一个名为的数据集spam,其中包含58个列和大约3500行与垃圾邮件相关的数据.
我打算将来在这个数据集上运行一些线性回归,但我想事先做一些预处理,并将列标准化为零均值和单位方差.
我被告知最好的方法是使用R,所以我想问一下如何用R实现规范化?我已经正确加载了数据,我只是在寻找一些包或方法来执行此任务.
Das*_*son 487
我必须假设您想要表示平均值为0且标准偏差为1.如果您的数据位于数据框中且所有列都是数字,则可以简单地调用scale数据上的函数来执行您想要的操作.
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)
Run Code Online (Sandbox Code Playgroud)
使用内置函数是优雅的.喜欢这只猫:

akh*_*med 78
意识到问题是陈旧的,一个答案被接受,我将提供另一个答案供参考.
scale受到它扩展所有变量这一事实的限制.下面的解决方案允许仅扩展特定的变量名称,同时保持其他变量不变(并且可以动态生成变量名称):
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
Run Code Online (Sandbox Code Playgroud)
这给了我这个:
> 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
Run Code Online (Sandbox Code Playgroud)
和
> 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
Run Code Online (Sandbox Code Playgroud)
编辑:解决了Julian的评论:输出scale是Nx1矩阵,所以理想情况下我们应该添加一个as.vector将矩阵类型转换回矢量类型.谢谢朱利安!
小智 57
这是3岁.不过,我觉得我必须添加以下内容:
最常见的归一化是z变换,您可以减去均值并除以变量的标准差.结果将是mean = 0和sd = 1.
为此,您不需要任何包.
zVar <- (myVar - mean(myVar)) / sd(myVar)
Run Code Online (Sandbox Code Playgroud)
而已.
小智 21
'Caret'包提供了预处理数据的方法(例如居中和缩放).您还可以使用以下代码:
library(caret)
# Assuming goal class is column 10
preObj <- preProcess(data[, -10], method=c("center", "scale"))
newData <- predict(preObj, data[, -10])
Run Code Online (Sandbox Code Playgroud)
更多细节:http://www.inside-r.org/node/86978
小智 15
当我使用Dason所说的解决方案时,我得到了一个数字向量(我的df的缩放值),而不是得到一个数据帧.
如果有人遇到同样的问题,你必须在代码中添加as.data.frame(),如下所示:
df.scaled <- as.data.frame(scale(df))
Run Code Online (Sandbox Code Playgroud)
我希望这对有同样问题的人有用!
Sam*_*agd 13
您还可以使用clusterSim包中的data.Normalization函数轻松规范化数据.它提供了不同的数据规范化方法.
data.Normalization (x,type="n0",normalization="column")
Run Code Online (Sandbox Code Playgroud)
参数
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 /范围)
n8 - 商变换(x/max)
n9 - 商变换(x /均值)
n9a - 位置商变换(x /中位数)
n10 - 商变换(x/sum)
n11 - 商变换(x/sqrt(SSQ))
n12 - 归一化((x-mean)/ sqrt(sum((x-mean)^ 2)))
n12a - 位置归一化((x-median)/ sqrt(sum((x-median)^ 2)))
n13 - 归零,零为中心点((x-midrange)/(range/2))
规范化
"列" - 按变量归一化,"行" - 按对象归一化
使用dplyrv0.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
Run Code Online (Sandbox Code Playgroud)
可以使用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
Run Code Online (Sandbox Code Playgroud)
由reprex软件包(v0.2.0)创建于2018-04-24。
小智 7
同样,即使这是一个老问题,它也是非常相关的!我找到了一种简单的方法来规范化某些列而无需任何包:
normFunc <- function(x){(x-mean(x, na.rm = T))/sd(x, na.rm = T)}
Run Code Online (Sandbox Code Playgroud)
例如
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)
Run Code Online (Sandbox Code Playgroud)
您将看到y和z列已标准化.不需要包裹:-)
比例可用于完整数据框和特定列。对于特定的列,可以使用以下代码:
trainingSet[, 3:7] = scale(trainingSet[, 3:7]) # For column 3 to 7
trainingSet[, 8] = scale(trainingSet[, 8]) # For column 8
Run Code Online (Sandbox Code Playgroud)
全数据帧
trainingSet <- scale(trainingSet)
Run Code Online (Sandbox Code Playgroud)