收藏

让scale给整不会了

2024-12-07  本文已影响0人  生信云笔记

  数据处理时经常需要做各种处理,如标准化和归一化,在R里面可以借助scale函数来轻松完成。默认情况下,该函数做的事情可以用下面的公式概括:
z = \frac{x - \mu}{\sigma}其中 x 是原始数据点,μ 是数据的均值,σ 是数据的标准差,z 是标准化后的值。

vec <- 1:5
scale(vec)
           [,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

  可知,该函数默认参数(center=TRUEscale=TRUE)条件下对数据做了标准正态化处理,这也是通常情况下的需求。虽然该函数很简单,但做的事情却不止于此。通过调整这两个参数也可以单独只做center,或者scale,即只做公式的上面或者下面。

scale(vec, scale=F)
     [,1]
[1,]   -2
[2,]   -1
[3,]    0
[4,]    1
[5,]    2
attr(,"scaled:center")
[1] 3

  只做center很容易理解,即每一个值都减去均值,也就是处理后的数据均值为0。

scale(vec, center=F)
          [,1]
[1,] 0.2696799
[2,] 0.5393599
[3,] 0.8090398
[4,] 1.0787198
[5,] 1.3483997
attr(,"scaled:scale")
[1] 3.708099

  当只做scale时,结果就有点不同寻常,为什么是每个数除以均方根而不是标准差呢?先来看看两者的计算公式:
标准差:\sigma = \sqrt{\frac{1}{n-1}\sum_{i=1}^{n}(x_i - \mu)^2}

均方根:\sigma = \sqrt{\frac{1}{n-1}\sum_{i=1}^{n}x_i ^2}

  回顾上面的公式可知,标准差可以拆分成两部分:中心化和均方根。事实上,scale函数的代码实现也正是如此,先做中心化,然后计算均方根,现在再回头看上面的代码不同组合的结果就理所当然了。

  当然,scale的参数不仅可以是默认的布尔值,也可以是具体的数字,这也增加了函数的可能性,让函数可以做更多的事情,比如下面的代码:

scale(vec, center=3)
           [,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

  向量vec的均值为3,如果将center参数设置为3,则其结果与默认参数一致,这样可以说明scale函数的代码实现是先做中心化,然后计算均方根。

  这样一来scale函数可就很灵活了,虽然很简单,却可以省却很多时间,比如做个归一化也很方便:

# 映射到[ 0, 1]
scale(vec, center=min(vec), scale=max(vec)-min(vec))
     [,1]
[1,] 0.00
[2,] 0.25
[3,] 0.50
[4,] 0.75
[5,] 1.00
attr(,"scaled:center")
[1] 1
attr(,"scaled:scale")
[1] 4

# 比如映射到[ -1, 1]
scale(vec, scale=max(vec)-min(vec))
      [,1]
[1,] -0.50
[2,] -0.25
[3,]  0.00
[4,]  0.25
[5,]  0.50
attr(,"scaled:center")
[1] 3
attr(,"scaled:scale")
[1] 4

  用工具,精髓在于一句话:知其道,用奇妙!这样站在巨人的肩膀上仰望才不会一眼迷茫!与君共勉。

上一篇 下一篇

猜你喜欢

热点阅读