Jest to stosunkowo stary wątek, ale ostatnio spotkałem się z tym problemem w swojej pracy i natknąłem się na tę dyskusję. Odpowiedzi na to pytanie, ale uważam, że nie wyeliminowano niebezpieczeństwa normalizacji wierszy, gdy nie jest to jednostka analizy (patrz odpowiedź @ DJohnson powyżej).
Najważniejsze jest to, że normalizowanie wierszy może być szkodliwe dla każdej późniejszej analizy, na przykład najbliższego sąsiada lub k-średnich. Dla uproszczenia zachowam odpowiedź dotyczącą centrowania wierszy.
Aby to zilustrować, użyję symulowanych danych gaussowskich w rogach hipersześcianu. Na szczęście R
jest do tego wygodna funkcja (kod znajduje się na końcu odpowiedzi). W przypadku 2D jest oczywiste, że dane wyśrodkowane na rzędzie spadną na linię przechodzącą przez punkt początkowy pod kątem 135 stopni. Symulowane dane są następnie grupowane za pomocą k-średnich z prawidłową liczbą klastrów. Dane i wyniki grupowania (wizualizowane w 2D przy użyciu PCA na oryginalnych danych) wyglądają tak (osie dla wykresu najbardziej na lewo są różne). Różne kształty punktów na wykresach grupowania odnoszą się do przypisania klastra z podstawową prawdą, a kolory są wynikiem grupowania k-średnich.
Klastry u góry po lewej i po prawej u dołu zostają przecięte na pół, gdy dane są wyśrodkowane na środkowej linii. Tak więc odległości po centrowaniu średniego rzędu ulegają zniekształceniu i nie są zbyt znaczące (przynajmniej w oparciu o znajomość danych).
Nie jest to tak zaskakujące w 2D, co jeśli zastosujemy więcej wymiarów? Oto, co dzieje się z danymi 3D. Rozwiązanie grupujące po centrowaniu średniej rzędów jest „złe”.
I podobnie z danymi 4D (teraz pokazanymi dla zwięzłości).
Dlaczego to się dzieje? Centrowanie średniej rzędów wypycha dane do przestrzeni, w której niektóre funkcje są bliższe niż w innym przypadku. Powinno to znaleźć odzwierciedlenie w korelacji między funkcjami. Spójrzmy na to (najpierw na oryginalne dane, a następnie na dane ze średnim rzędem dla przypadków 2D i 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
Wygląda więc na to, że centrowanie średnich rzędów wprowadza korelacje między funkcjami. Jak wpływa na to liczba funkcji? Możemy wykonać prostą symulację, aby to rozgryźć. Wynik symulacji pokazano poniżej (ponownie kod na końcu).
Zatem wraz ze wzrostem liczby cech efekt centrowania średniej rzędów wydaje się zmniejszać, przynajmniej pod względem wprowadzonych korelacji. Ale do tej symulacji wykorzystaliśmy po prostu równomiernie rozłożone losowe dane (co jest powszechne przy badaniu przekleństwa wymiarowości ).
Co się dzieje, gdy wykorzystujemy prawdziwe dane? Ponieważ wiele razy istotna wymiarowość danych jest niższa, klątwa może nie mieć zastosowania . W takim przypadku zgaduję, że centrowanie średnich rzędów może być „złym” wyborem, jak pokazano powyżej. Oczywiście, bardziej rygorystyczna analiza jest potrzebna do sformułowania ostatecznych roszczeń.
Kod do symulacji klastrowania
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)
}
Kod zwiększający symulację funkcji
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)
EDYTOWAĆ
Po pewnym googlowaniu skończyło się na tej stronie, gdzie symulacje pokazują podobne zachowanie i sugerują, że korelacja wprowadzona przez centrowanie średniego rzędu wynosi .- 1 / ( p - 1 )