R中的归一化功能

时间:2015-02-17 14:33:21

标签: r normalization

我有一个我想要变换的矩阵,这样变换后的数据集中的每个特征的均值为0,方差为1。

我尝试使用以下代码:

scale <- function(train, test) 
{   
trainmean <- mean(train)
trainstd <- sd(train)
xout <- test
for (i in 1:length(train[1,])) {
    xout[,i] = xout[,i] - trainmean(i)
}
for (i in 1:lenght(train[1,])) {
    xout[,i] = xout[,i]/trainstd[i]
}

}
invisible(xout)

normalized <- scale(train, test)
然而,这对我不起作用。我是在正确的轨道上吗?

编辑:我对语法很新!

2 个答案:

答案 0 :(得分:10)

您可以使用内置的scale功能。

这是一个例子,我们用0和1之间的随机均匀变量填充矩阵并居中并将它们缩放为0均值和单位标准差:

m <- matrix(runif(1000), ncol=4)    
m_scl <- scale(m)

确认列平均值为0(在容差范围内)且标准偏差为1:

colMeans(m_scl)
# [1] -1.549004e-16 -2.490889e-17 -6.369905e-18 -1.706621e-17

apply(m_scl, 2, sd)
# [1] 1 1 1 1

有关详细信息,请参阅?scale

要编写自己的规范化函数,可以使用:

my_scale <- function(x) {
  apply(m, 2, function(x) {
    (x - mean(x))/sd(x)
  }) 
}

m_scl <- my_scale(m)

或以下,在较大的矩阵上可能更快

my_scale <- function(x) sweep(sweep(x, 2, colMeans(x)), 2, apply(x, 2, sd), '/')

答案 1 :(得分:2)

建议另一个自己编写的规范化函数避免使用apply,这比我的经验慢于矩阵计算:

m = matrix(rnorm(5000, 2, 3), 50, 100)

m_centred = m - m%*%rep(1,dim(m)[2])%*%rep(1, dim(m)[2])/dim(m)[2]
m_norm = m_centred/sqrt(m_centred^2%*%rep(1,dim(m)[2])/(dim(m)[2]-1))%*%rep(1,dim(m)[2])

## Verirication
rowMeans(m_norm)
apply(m_norm, 1, sd)

(注意,这里考虑行向量)