zscore标准化步骤_z-score的标准化究竟怎么弄?

在学习「数据挖掘导论」的数据预处理时,里面谈到了变量变换,我联想到了在基因表达量分析时的常见操作,例如FPKM,TPM,CPM,log对数变换。比如说在文章里面会见到如下的描述

The size factor of each cell was computed using a pooling strategy implemented in the R function computeSumFactors. Normalized counts were then computed by dividing the counts for each cell by the size factor for that cell. A log2 transformation was applied to normalized counts.

变量转换有什么好处,需要注意些什么呢?「数据挖掘导论」讨论了两种重要的变量变换类型: 简单函数变换和规范化。

简单变换是使用一个简单数学函数分别作用于每一个值,例如log转换,求绝对值,求倒数等。统计学中,变量变换(例如log转换)常用于将不具有高斯(正态)分布的数据变换成具有高斯(正态)分布的数据。在数据挖掘领域可以用来进行数据压缩。这类变换需要我们了解数据在变化前后的后果,例如负数取倒数之后的大小关系会发生倒转。

标准化(standardization)或规范化(normalization)的目标是使整个值的集合具有特定的属性。使用这两个术语需要特别注意使用这两个词的上下文。书中提到"在数据挖掘界,这两个术语常常可互换,然而,在统计学中,术语规范化可能与使得变量正态化相混淆"。虽然从中文的角度来看,规范化和正态化明显不一样,但是从英文的角度看,正态分布翻译自normal distribution, 很容易从normal联想到normalization。当然也有将normalization翻译成归一化,即将原来数据值通过

转换到0,1之间。统计学的变量标准化指的就是对原来的数据基于均值和标准差计算z-score(公式如下), 不过考虑到均值和标准差受到离群点波动很大,可以用中位数替代均值,用绝对标准差替代标准差。

R语言中做标准化常用到一个函数scale,它的功能是对矩阵的列进行中心化和(或)缩放

scale(x, center = TRUE, scale = TRUE)

参数就3个,基本上我用的时候就提供第一个输入,举个例子

> x 

> y 

> y

[,1]

[1,] -1.2649111

[2,] -0.6324555

[3,]  0.0000000

[4,]  0.6324555

[5,]  1.2649111

attr(,"scaled:center")

[1] 3

attr(,"scaled:scale")

[1] 1.581139

之前我都是这样子用的,也没有思考过这到底它到底做了些什么。最近为了彻底搞懂它的两个参数,我翻了它的源代码。

代码总共38行,第一部分是关于center参数,也就是中心化。它先判断center是否是逻辑值还是数值向量。如果是逻辑值,则当center=TRUE时它会计算每一列的均值,然后调用sweep按列分别减去均值。如果判定center是一个数值向量时,就是为sweep手动指定每一列的中心值。

if (is.logical(center)) {

if (center) {

center 

}

}

else {

if(!is.numeric(center)) center 

if (length(center) == nc)

else

stop("length of "center" must equal the number of columns of "x"")

}

第二部分是关于scale,决定数据如何缩放。如果是逻辑值且为真时,默认用下面的函数计算每一列的缩放系数,然后用sweep按列除以每列系数

这个计算的结果就是样本标准差,因为

如果是数值向量,则用sweep以给定数值按列相除。

if (is.logical(scale)) {

if (scale) {

sqrt(sum(v^2) / max(1, length(v) - 1L))

}

scale 

}

}

else {

if(!is.numeric(scale)) scale 

if (length(scale) == nc)

else

stop("length of "scale" must equal the number of columns of "x"")

}

最后一部分是设置输出结果的属性。

if(is.numeric(center)) attr(x, "scaled:center") 

if(is.numeric(scale )) attr(x, "scaled:scale" ) 

那么默认参数下,我们就是对矩阵按列进行z-score的标准化。检验标准很简单,计算标准化的数据的均值和标准差,因为z-score的结果就是让数据服从均值为0,标准差为1的正态分布。

> mean(y)

0

> sd(y)

1

这解决了我多年的疑惑,为啥我在R语言中就是找不到zscore这个函数,因为scale默认情况下就是实现z-score的变换。当然R语言取名scale也是有它的道理,比方说数据中存在离群值,我们应该选择不容易受离群值影响的中位数替代均值,选择绝对平均偏差, 中位数绝对偏差或四分位数极差来替换方差。

# 默认参数

> x 

> scale(x)

[,1]       [,2]

[1,] -1.2649111 -0.4505747

[2,] -0.6324555 -0.4483330

[3,]  0.0000000 -0.4460914

[4,]  0.6324555 -0.4438497

[5,]  1.2649111  1.7888488

...

# 替换后

> x 

> scale(x,

center = apply(x, 2, median),

scale = apply(x, 2, function(x){

sum(abs(x - mean(x))) / (length(x)-1)

})

)

[,1]         [,2]

[1,] -1.3333333 -0.005012531

[2,] -0.6666667 -0.002506266

[3,]  0.0000000  0.000000000

[4,]  0.6666667  0.002506266

[5,]  1.3333333  2.498746867

...

此外,它还能实现其他形式的数据转换,例如归一化,即将数据的范围缩放到0到1之间

scale = apply(x,2,function(x) {max(x)-min(x)})

)

最后总结一下:

数据的变量转换有两类,简单变换和标准化/规范化,无论是何种变换都要看它的具体公式

R语言的scale默认就是计算原始数据的z-score, 通过调整center和scale可以实现多种形式的数据转换。

你可能感兴趣的:(zscore标准化步骤)