programing

R의 데이터 열 표준화

minimums 2023. 6. 27. 22:03
반응형

R의 데이터 열 표준화

데이터 집합이 있습니다.spam58개의 열과 스팸 메시지와 관련된 약 3500개의 데이터 행이 포함되어 있습니다.

앞으로 이 데이터 집합에 대해 선형 회귀 분석을 실행할 계획이지만, 사전 처리를 통해 평균 및 단위 분산이 0이 되도록 열을 표준화하고 싶습니다.

이 문제를 해결하는 가장 좋은 방법은 R과 함께 하는 것이라고 들었는데, 어떻게 하면 R과의 정규화를 달성할 수 있는지 묻고 싶습니다.이미 데이터를 제대로 로드했으며 이 작업을 수행할 몇 가지 패키지나 방법을 찾고 있습니다.

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)

내장된 기능을 사용하는 것은 고급스럽습니다.이 고양이처럼:

enter image description here

질문이 오래되고 하나의 답변이 받아들여진다는 것을 깨닫고, 다른 답변을 참고할 수 있도록 제공하겠습니다.

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_at(c("y", "z"), ~(scale(.) %>% as.vector))
dat2

그래서 이런 생각이 듭니다.

> 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

그리고.

> dat2 <- dat %>% mutate_at(c("y", "z"), ~(scale(.) %>% as.vector))
> 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

EDIT 1(2016):Julian의 논평을 다루었습니다: 출력.scaleNx1 매트릭스이므로 이상적으로 추가해야 합니다.as.vector행렬 형식을 다시 벡터 형식으로 변환합니다.감사합니다, 줄리안!

EDIT 2 (2019):Duccio A.의 의견을 인용합니다.최신 dplyr(버전 0.8)의 경우 dplyr:: funcs with list를 다음과 같이 변경해야 합니다.dat %>% mutate_each_(list(~scale(.) %>% as.vector), vars=c("y","z"))

EDIT 3(2020):@mj_whales 덕분에: 이전 솔루션은 더 이상 사용되지 않으며 이제 사용해야 합니다.mutate_at.

이 아이는 3살입니다.그래도 다음 사항을 추가해야 한다고 생각합니다.

가장 일반적인 정규화는 평균을 빼고 변수의 표준 편차로 나누는 z-변환입니다.결과는 평균=0 및 sd=1이 됩니다.

그것을 위해, 당신은 어떤 소포도 필요하지 않습니다.

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

바로 그겁니다.

'Caret' 패키지는 데이터를 사전 처리하는 방법(예: 센터링 및 스케일링)을 제공합니다.다음 코드를 사용할 수도 있습니다.

library(caret)
# Assuming goal class is column 10
preObj <- preProcess(data[, -10], method=c("center", "scale"))
newData <- predict(preObj, data[, -10])

더 자세한 정보: http://www.inside-r.org/node/86978

데이슨이 제시한 솔루션을 사용했을 때, 결과적으로 데이터 프레임을 얻는 대신 숫자의 벡터(내 df의 축척 값)를 얻었습니다.

누군가가 같은 문제를 겪고 있는 경우 다음과 같이 코드에 as.data.frame()을 추가해야 합니다.

df.scaled <- as.data.frame(scale(df))

이것이 같은 이슈를 가지고 있는 ppl에 유용하기를 바랍니다!

또한 데이터를 사용하여 데이터를 쉽게 정규화할 수 있습니다.clusterSim 패키지의 정규화 함수입니다.다른 데이터 정규화 방법을 제공합니다.

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

논쟁들

x
또는 집합 " ", " "는 " " " 입니다.
: - : n0 - 정규화 없음

n1 - 표준화((x-제곱)/sd)

n2 - 위치 표준화((x-표준)/매드)

n3 - 단위화((x-sigma)/범위)

n3a - 위치 단위화((x-module)/범위)

n4 - 최소값이 0인 단위화((x-min)/범위)

n5 - 범위 <-1,1>의 정규화(((x-max)/max(abs(x-max))

n5a - <-1,1> 범위의 위치 정규화(((x-sigma))/max(abs(x-sigma))

n6 - 백분율 변환(x/sd)

n6a - 위치 계수 변환(x/mad)

n7 - 백분율 변환(x/범위)

n8 - 백분율 변환(x/max)

n9 - 백분율 변환(x/sigma)

n9a - 위치 계수 변환(x/σ)

n10 - 백분율 변환(x/sum)

n11 - 계수 변환(x/sqrt(SSQ))

n12 - 정규화((x-제곱)/sqrt(합(x-제곱)^2))

n12a - 위치 정규화((x-θ)/sqrt(sum(x-θ)^2))

n13 - 0을 중심점으로 하는 정규화((x-sigma)/(range/2)


"열" - 변수에 의한 정규화, "행" - 개체에 의한 정규화

와 함께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 패키지(v0.2.0)에 의해 2018-04-24에 생성되었습니다.

다시, 비록 이것이 오래된 질문이지만, 그것은 매우 관련이 있습니다!패키지 없이도 특정 열을 정규화할 수 있는 간단한 방법을 찾았습니다.

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 열이 정규화된 것을 확인할 수 있습니다.패키지 필요 없음 :-)

축척은 전체 데이터 프레임과 특정 열 모두에 사용할 수 있습니다.특정 열에 대해 다음 코드를 사용할 수 있습니다.

trainingSet[, 3:7] = scale(trainingSet[, 3:7]) # For column 3 to 7
trainingSet[, 8] = scale(trainingSet[, 8]) # For column 8 

전체 데이터 프레임

trainingSet <- scale(trainingSet)

축소 패키지는 Welfords Online Algorithm을 사용하여 C++로 구현된 가장 빠른 확장 기능을 제공합니다.

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패키지에는 이를 수행하는 두 가지 기능이 있습니다.

> require(dplyr)

데이터 테이블의 특정 열을 변환하려면 다음 함수를 사용할 수 있습니다.mutate_at()모든 열을 변환하려면 다음을 사용합니다.mutate_all.

다음은 이러한 기능을 사용하여 데이터를 표준화하는 간단한 예입니다.

특정 열 변환:

dt = data.table(a = runif(3500), b = runif(3500), c = runif(3500))
dt = data.table(dt %>% mutate_at(vars("a", "c"), scale)) # can also index columns by number, e.g., vars(c(1,3))

> apply(dt, 2, mean)
            a             b             c 
 1.783137e-16  5.064855e-01 -5.245395e-17 

> apply(dt, 2, sd)
        a         b         c 
1.0000000 0.2906622 1.0000000 

모든 열 음소거:

dt = data.table(a = runif(3500), b = runif(3500), c = runif(3500))
dt = data.table(dt %>% mutate_all(scale))

> apply(dt, 2, mean)
            a             b             c 
-1.728266e-16  9.291994e-17  1.683551e-16 

> apply(dt, 2, sd)
a b c 
1 1 1 

이 스레드를 발견하기 전에도 같은 문제가 있었습니다.사용자 종속 열 유형이 있어서 다음을 작성했습니다.for한 열을 은 그 들 고 을 얻 는 열 루 프 을 한 요scale 수 를 잘 d. 더 나은 방법이 있을 수 있지만, 이는 문제를 잘 해결되었습니다.

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

as.vector필요한 부분입니다, 왜냐하면 그것은 드러났기 때문입니다.scale?rownames x 1 여러분이 .data.frame.

@BBK 김은 거의 대부분 최고의 대답을 했지만, 그것은 단지 더 짧게 할 수 있습니다.아직 아무도 그것을 생각해내지 못했다니 놀랍군요.

dat <- data.frame(x = rnorm(10, 30, .2), y = runif(10, 3, 5)) dat <- apply(dat, 2, function(x) (x - mean(x)) / sd(x))

패키지 "recommenderlab"을 사용합니다.패키지를 다운로드하여 설치합니다.이 패키지에는 "정상화" 명령이 내장되어 있습니다.또한 '중심' 또는 'Z-점수'와 같은 여러 정규화 방법 중 하나를 선택할 수 있습니다. 다음 예를 따르십시오.

## create a matrix with ratings
m <- matrix(sample(c(NA,0:5),50, replace=TRUE, prob=c(.5,rep(.5/6,6))),nrow=5, ncol=10, dimnames = list(users=paste('u', 1:5, sep=&rdquo;), items=paste('i', 1:10, sep=&rdquo;)))

## do normalization
r <- as(m, "realRatingMatrix")
#here, 'centre' is the default method
r_n1 <- normalize(r) 
#here "Z-score" is the used method used
r_n2 <- normalize(r, method="Z-score")

r
r_n1
r_n2

## show normalized data
image(r, main="Raw Data")
image(r_n1, main="Centered")
image(r_n2, main="Z-Score Normalization")

아래 코드가 이를 위한 가장 빠른 방법일 수 있습니다.

dataframe <- apply(dataframe, 2, scale)

BBMisc 패키지의 정규화 기능은 NA 값을 처리할 수 있기 때문에 저에게 적합한 도구였습니다.

사용 방법은 다음과 같습니다.

다음과 같은 데이터 집합이 주어지면,

    ASR_API     <- c("CV",  "F",    "IER",  "LS-c", "LS-o")
    Human       <- c(NA,    5.8,    12.7,   NA, NA)
    Google      <- c(23.2,  24.2,   16.6,   12.1,   28.8)
    GoogleCloud <- c(23.3,  26.3,   18.3,   12.3,   27.3)
    IBM     <- c(21.8,  47.6,   24.0,   9.8,    25.3)
    Microsoft   <- c(29.1,  28.1,   23.1,   18.8,   35.9)
    Speechmatics    <- c(19.1,  38.4,   21.4,   7.3,    19.4)
    Wit_ai      <- c(35.6,  54.2,   37.4,   19.2,   41.7)
    dt     <- data.table(ASR_API,Human, Google, GoogleCloud, IBM, Microsoft, Speechmatics, Wit_ai)
> dt
   ASR_API Human Google GoogleCloud  IBM Microsoft Speechmatics Wit_ai
1:      CV    NA   23.2        23.3 21.8      29.1         19.1   35.6
2:       F   5.8   24.2        26.3 47.6      28.1         38.4   54.2
3:     IER  12.7   16.6        18.3 24.0      23.1         21.4   37.4
4:    LS-c    NA   12.1        12.3  9.8      18.8          7.3   19.2
5:    LS-o    NA   28.8        27.3 25.3      35.9         19.4   41.7

정규화된 값은 다음과 같이 얻을 수 있습니다.

> dtn <- normalize(dt, method = "standardize", range = c(0, 1), margin = 1L, on.constant = "quiet")
> dtn
   ASR_API      Human     Google GoogleCloud         IBM  Microsoft Speechmatics      Wit_ai
1:      CV         NA  0.3361245   0.2893457 -0.28468670  0.3247336  -0.18127203 -0.16032655
2:       F -0.7071068  0.4875320   0.7715885  1.59862532  0.1700986   1.55068347  1.31594762
3:     IER  0.7071068 -0.6631646  -0.5143923 -0.12409420 -0.6030768   0.02512682 -0.01746131
4:    LS-c         NA -1.3444981  -1.4788780 -1.16064578 -1.2680075  -1.24018782 -1.46198764
5:    LS-o         NA  1.1840062   0.9323361 -0.02919864  1.3762521  -0.15435044  0.32382788

여기서 수동 계산 방법은 NA를 포함하는 Colmun을 무시합니다.

> dt %>% mutate(normalizedHuman = (Human - mean(Human))/sd(Human)) %>% 
+ mutate(normalizedGoogle = (Google - mean(Google))/sd(Google)) %>% 
+ mutate(normalizedGoogleCloud = (GoogleCloud - mean(GoogleCloud))/sd(GoogleCloud)) %>% 
+ mutate(normalizedIBM = (IBM - mean(IBM))/sd(IBM)) %>% 
+ mutate(normalizedMicrosoft = (Microsoft - mean(Microsoft))/sd(Microsoft)) %>% 
+ mutate(normalizedSpeechmatics = (Speechmatics - mean(Speechmatics))/sd(Speechmatics)) %>% 
+ mutate(normalizedWit_ai = (Wit_ai - mean(Wit_ai))/sd(Wit_ai))
  ASR_API Human Google GoogleCloud  IBM Microsoft Speechmatics Wit_ai normalizedHuman normalizedGoogle
1      CV    NA   23.2        23.3 21.8      29.1         19.1   35.6              NA        0.3361245
2       F   5.8   24.2        26.3 47.6      28.1         38.4   54.2              NA        0.4875320
3     IER  12.7   16.6        18.3 24.0      23.1         21.4   37.4              NA       -0.6631646
4    LS-c    NA   12.1        12.3  9.8      18.8          7.3   19.2              NA       -1.3444981
5    LS-o    NA   28.8        27.3 25.3      35.9         19.4   41.7              NA        1.1840062
  normalizedGoogleCloud normalizedIBM normalizedMicrosoft normalizedSpeechmatics normalizedWit_ai
1             0.2893457   -0.28468670           0.3247336            -0.18127203      -0.16032655
2             0.7715885    1.59862532           0.1700986             1.55068347       1.31594762
3            -0.5143923   -0.12409420          -0.6030768             0.02512682      -0.01746131
4            -1.4788780   -1.16064578          -1.2680075            -1.24018782      -1.46198764
5             0.9323361   -0.02919864           1.3762521            -0.15435044       0.32382788

(정규화됨)인간은 NA의 목록이 됩니다...)

계산을 위한 특정 열 선택과 관련하여 다음과 같은 일반적인 방법을 사용할 수 있습니다.

data_vars <- df_full %>% dplyr::select(-ASR_API,-otherVarNotToBeUsed)
meta_vars <- df_full %>% dplyr::select(ASR_API,otherVarNotToBeUsed)
data_varsn <- normalize(data_vars, method = "standardize", range = c(0, 1), margin = 1L, on.constant = "quiet")
dtn <- cbind(meta_vars,data_varsn)

언급URL : https://stackoverflow.com/questions/15215457/standardize-data-columns-in-r

반응형