열 정규화의 이유는 동일한 척도로 측정되지 않더라도 피쳐에 동일한 가중치를 부여하기 때문에 이해하지만, 가장 가까운 이웃 문헌에서는 종종 열과 행이 정규화됩니다. 행 정규화 란 무엇입니까? 왜 행을 정규화합니까? 구체적으로, 행 정규화의 결과는 행 벡터 간의 유사성 / 거리에 어떻게 영향을 줍니까?
열 정규화의 이유는 동일한 척도로 측정되지 않더라도 피쳐에 동일한 가중치를 부여하기 때문에 이해하지만, 가장 가까운 이웃 문헌에서는 종종 열과 행이 정규화됩니다. 행 정규화 란 무엇입니까? 왜 행을 정규화합니까? 구체적으로, 행 정규화의 결과는 행 벡터 간의 유사성 / 거리에 어떻게 영향을 줍니까?
답변:
이것은 상대적으로 오래된 스레드이지만 최근에 내 작업 에서이 문제가 발생 하여이 토론을 우연히 발견했습니다. 질문에 대한 답변이 있지만 분석 단위가 아닐 때 행을 정규화 할 위험이 있다고 생각합니다 (위의 @DJohnson의 답변 참조).
요점은 정규화 행이 가장 가까운 이웃 또는 k- 평균과 같은 후속 분석에 해로울 수 있다는 것입니다. 간단하게하기 위해 행의 평균을 중심으로 특정 답변을 유지합니다.
이를 설명하기 위해 하이퍼 큐브의 모서리에 시뮬레이션 된 가우스 데이터를 사용합니다. 운 좋게도 R
편리한 기능이 있습니다 (코드는 답변의 끝에 있습니다). 2D 경우에 행 평균 데이터는 135도에서 원점을 통과하는 선에 놓이는 것이 간단합니다. 그런 다음 시뮬레이션 된 데이터는 올바른 수의 군집을 가진 k- 평균을 사용하여 군집화됩니다. 데이터와 클러스터링 결과 (원래 데이터에서 PCA를 사용하여 2D로 시각화)는 다음과 같습니다 (가장 왼쪽 플롯의 축이 다름). 군집 그림에서 점의 다른 모양은지면 진실 군집을 나타내며 색상은 k- 평균 군집의 결과입니다.
데이터가 행 중심에 있으면 왼쪽 상단 및 오른쪽 하단 클러스터가 반으로 줄어 듭니다. 따라서 행 중심을 중심으로 한 거리는 왜곡되어 그다지 의미가 없습니다 (최소한 데이터에 대한 지식을 바탕으로).
2D에서 그렇게 놀라운 것은 아니지만 더 많은 치수를 사용하면 어떻게 될까요? 다음은 3D 데이터에서 발생하는 일입니다. 행 평균 센터링 후 클러스터링 솔루션은 "나쁜"것입니다.
그리고 4D 데이터와 유사합니다 (이제 간결하게 표시됨).
왜 이런 일이 발생합니까? 행 중심을 중심으로 데이터는 일부 기능이 다른 기능보다 가까이있는 공간으로 이동합니다. 이는 기능 간의 상관 관계에 반영되어야합니다. 먼저 살펴보십시오 (먼저 원본 데이터와 2D 및 3D 사례의 행 평균 중심 데이터).
[,1] [,2]
[1,] 1.000 -0.001
[2,] -0.001 1.000
[,1] [,2]
[1,] 1 -1
[2,] -1 1
[,1] [,2] [,3]
[1,] 1.000 -0.001 0.002
[2,] -0.001 1.000 0.003
[3,] 0.002 0.003 1.000
[,1] [,2] [,3]
[1,] 1.000 -0.504 -0.501
[2,] -0.504 1.000 -0.495
[3,] -0.501 -0.495 1.000
따라서 행 중심을 중심으로 기능 간의 상관 관계를 도입하는 것처럼 보입니다. 이것은 여러 기능의 영향을 어떻게 받습니까? 간단한 시뮬레이션으로 알아낼 수 있습니다. 시뮬레이션 결과는 다음과 같습니다 (끝 부분의 코드).
따라서 기능의 수가 증가함에 따라 행 평균 중심화의 효과는 도입 된 상관 관계 측면에서 최소한 감소하는 것처럼 보입니다. 그러나 우리는이 시뮬레이션에 균일하게 분포 된 랜덤 데이터를 사용했습니다 ( 차원 의 저주를 연구 할 때 일반적 임).
실제 데이터를 사용하면 어떻게됩니까? 데이터의 고유 차원이 여러 번 낮을 수록 저주는 적용되지 않을 수 있습니다 . 이러한 경우 행 평균 중심화가 위에 표시된 것처럼 "나쁜"선택 일 수 있습니다. 물론, 명확한 주장을하기 위해서는보다 엄격한 분석이 필요합니다.
클러스터링 시뮬레이션을위한 코드
palette(rainbow(10))
set.seed(1024)
require(mlbench)
N <- 5000
for(D in 2:4) {
X <- mlbench.hypercube(N, d=D)
sh <- as.numeric(X$classes)
K <- length(unique(sh))
X <- X$x
Xc <- sweep(X,2,apply(X,2,mean),"-")
Xr <- sweep(X,1,apply(X,1,mean),"-")
show(round(cor(X),3))
show(round(cor(Xr),3))
par(mfrow=c(1,1))
k <- kmeans(X,K,iter.max = 1000, nstart = 10)
kc <- kmeans(Xc,K,iter.max = 1000, nstart = 10)
kr <- kmeans(Xr,K,iter.max = 1000, nstart = 10)
pc <- prcomp(X)
par(mfrow=c(1,4))
lim <- c(min(min(X),min(Xr),min(Xc)), max(max(X),max(Xr),max(Xc)))
plot(X[,1], X[,2], xlim=lim, ylim=lim, xlab="Feature 1", ylab="Feature 2",main="Data",col=1,pch=1)
points(Xc[,1], Xc[,2], col=2,pch=2)
points(Xr[,1], Xr[,2], col=3,pch=3)
legend("topleft",legend=c("Original","Center-cols","Center-rows"),col=c(1,2,3),pch=c(1,2,3))
abline(h=0,v=0,lty=3)
plot(pc$x[,1], pc$x[,2], col=rainbow(K)[k$cluster], xlab="PC 1", ylab="PC 2", main="Cluster original", pch=sh)
plot(pc$x[,1], pc$x[,2], col=rainbow(K)[kc$cluster], xlab="PC 1", ylab="PC 2", main="Cluster center-col", pch=sh)
plot(pc$x[,1], pc$x[,2], col=rainbow(K)[kr$cluster], xlab="PC 1", ylab="PC 2", main="Cluster center-row", pch=sh)
}
피처 시뮬레이션 증가를위한 코드
set.seed(2048)
N <- 1000
Cmax <- c()
Crmax <- c()
for(D in 2:100) {
X <- matrix(runif(N*D), nrow=N)
C <- abs(cor(X))
diag(C) <- NA
Cmax <- c(Cmax, max(C, na.rm=TRUE))
Xr <- sweep(X,1,apply(X,1,mean),"-")
Cr <- abs(cor(Xr))
diag(Cr) <- NA
Crmax <- c(Crmax, max(Cr, na.rm=TRUE))
}
par(mfrow=c(1,1))
plot(Cmax, ylim=c(0,1), ylab="Max. cor.", xlab="#Features",col=1,pch=1)
points(Crmax, ylim=c(0,1), col=2, pch=2)
legend("topright", legend=c("Original","Center-row"),pch=1:2,col=1:2)
편집하다
다양한 형식의 행 정규화가 있으며 OP는 어떤 형식을 염두에 두지 않습니다.
각 행이 규범화되는 특정 형식의 행 정규화 (유클리드 규범 정규화) (유클리드 규범으로 나눔)는 조용합니다.
예를 들어, 원본 데이터가이 이미지의 검은 점처럼 중앙에 있고 행 정규화를 적용하면 붉은 별이 나타납니다.
library(car)
p = 2
n = 1000
m = 10
C = matrix(.9, p, p)
diag(C) = 1
set.seed(123)
x = matrix(runif(n * p, -1, 1), n, p) %*% chol(C)
z = sweep(x, 1, sqrt(rowSums(x * x)), FUN = '/')
plot(rbind(x, z), pch = 16, type = 'n', ann = FALSE, xaxt = 'n', yaxt = 'n')
points(x, pch = 16)
points(z, pch = 8, col = 'red')
녹색 점은 원본 데이터에서 적은 수의 특이 치를 나타냅니다. 행 정규화 변환을 적용하면 파란색 별표가 나타납니다.
x_1 = sweep(matrix(runif(m * p, -1, 1), m, p), 2, c(2, -2))
z_1 = sweep(x_1, 1, sqrt(rowSums(x_1 * x_1)), FUN = '/')
plot(rbind(x, x_1, z, z_1), pch = 16, type = 'n', ann = FALSE, xaxt = 'n', yaxt = 'n')
points(x, pch = 16)
points(x_1, pch = 16, col = 'green')
points(z, pch = 8, col = 'red')
points(z_1, pch = 8, col = 'blue')
데이터, 오염 된 버전 및 행 정규화 된 변환에 차례로 맞춰진 형상 행렬 (또는 등고선 타원)을 비교하여 가장 명확하게 볼 수 있습니다.
ellipse(crossprod(rbind(x, x_1)) / (n + m - 1) / det(crossprod(rbind(x, x_1)) / (n + m - 1))^(1 / p), center = rep(0, p), col = 'green', radius = 1)
ellipse(crossprod(rbind(z, z_1)) / (n + m - 1) / det(crossprod(rbind(z, z_1)) / (n + m - 1))^(1 / p), center = rep(0, p), col = 'red', radius = 1)
ellipse(crossprod(rbind(x)) / (n - 1) / det(crossprod(rbind(x)) / (n - 1))^(1 / p), center = rep(0, p), col = 'black', radius = 1)
행 정규화를 수행 해야하는 몇 가지 필드 별 이유 가 있습니다. 텍스트 분석에서 포함 된 단어의 히스토그램으로 텍스트를 나타내는 것이 일반적입니다. 각 줄의 단어 수부터 시작하여 원시 표준화는이를 히스토그램으로 바꿉니다.
그리고 계산 이유 . 희소 행렬로 작업하는 경우 데이터를 열별로 쉽게 중앙에 배치하고 크기를 조정할 수 없습니다. 고밀도 매트릭스에 포함하면 데이터가 너무 커서 메모리에 맞지 않을 수 있습니다. 그러나 행 단위로 조정해도 필요한 총 메모리 양에는 영향을 미치지 않습니다.