R의 데이터 열 표준화
데이터 집합이 있습니다.spam
58개의 열과 스팸 메시지와 관련된 약 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)
내장된 기능을 사용하는 것은 고급스럽습니다.이 고양이처럼:
질문이 오래되고 하나의 답변이 받아들여진다는 것을 깨닫고, 다른 답변을 참고할 수 있도록 제공하겠습니다.
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의 논평을 다루었습니다: 출력.scale
Nx1 매트릭스이므로 이상적으로 추가해야 합니다.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=”), items=paste('i', 1:10, sep=”)))
## 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
'programing' 카테고리의 다른 글
SQL Server 2005의 기존 열 뒤에 새 열을 추가하기 위한 SQL 쿼리 (0) | 2023.06.27 |
---|---|
다른 위치에 있는 디렉토리에서 특정 Laravel 5 경로에 액세스 (0) | 2023.06.27 |
Oracle - 필드에 소문자가 있는 위치를 선택합니다. (0) | 2023.06.27 |
반환된 열의 이름을 Pandas Aggregate 함수에 지정하시겠습니까? (0) | 2023.06.27 |
실행 총계 / 실행 잔액 계산 (0) | 2023.06.27 |