Questo è un thread relativamente vecchio ma di recente ho riscontrato questo problema nel mio lavoro e mi sono imbattuto in questa discussione. Alla domanda è stata data una risposta, ma sento che il pericolo di normalizzare le righe quando non è l'unità di analisi (vedi la risposta di @ DJohnson sopra) non è stato affrontato.
Il punto principale è che la normalizzazione delle righe può essere dannosa per qualsiasi analisi successiva, come il vicino più vicino o il k-media. Per semplicità, terrò la risposta specifica per centrare la media delle righe.
Per illustrarlo, userò i dati gaussiani simulati agli angoli di un ipercubo. Fortunatamente R
c'è una comoda funzione per questo (il codice è alla fine della risposta). Nel caso 2D è semplice che i dati centrati sulla media delle righe cadano su una linea che passa attraverso l'origine a 135 gradi. I dati simulati vengono quindi raggruppati utilizzando k-mean con il numero corretto di cluster. I dati e i risultati del clustering (visualizzati in 2D usando PCA sui dati originali) appaiono così (gli assi per il grafico più a sinistra sono diversi). Le diverse forme dei punti nei grafici di raggruppamento si riferiscono all'assegnazione del cluster di verità e i colori sono il risultato del raggruppamento di k-medie.
I cluster in alto a sinistra e in basso a destra vengono tagliati a metà quando i dati sono centrati sulla riga. Quindi le distanze dopo il centraggio della media delle righe vengono distorte e non sono molto significative (almeno basate sulla conoscenza dei dati).
Non così sorprendente in 2D, e se usassimo più dimensioni? Ecco cosa succede con i dati 3D. La soluzione di clustering dopo il centraggio della media delle righe è "errata".
E simile con i dati 4D (ora mostrato per brevità).
Perché sta succedendo? Il centraggio della media delle righe spinge i dati in uno spazio in cui alcune funzionalità si avvicinano rispetto ad altre. Ciò dovrebbe riflettersi nella correlazione tra le funzionalità. Diamo un'occhiata a quello (prima sui dati originali e poi sui dati centrati sulla media delle righe per i casi 2D e 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
Quindi sembra che il centraggio della media delle righe stia introducendo correlazioni tra le caratteristiche. In che modo ciò è influenzato dal numero di funzioni? Possiamo fare una semplice simulazione per capirlo. Il risultato della simulazione è mostrato sotto (di nuovo il codice alla fine).
Pertanto, con l'aumentare del numero di funzioni, l'effetto del centraggio della media delle righe sembra diminuire, almeno in termini di correlazioni introdotte. Ma abbiamo appena usato dati casuali distribuiti uniformemente per questa simulazione (come è comune quando si studia la maledizione della dimensionalità ).
Quindi cosa succede quando utilizziamo dati reali? Come molte volte la dimensione intrinseca dei dati è inferiore, la maledizione potrebbe non essere applicabile . In tal caso, immagino che il centraggio della media delle righe possa essere una scelta "sbagliata" come mostrato sopra. Naturalmente, per fare affermazioni definitive è necessaria un'analisi più rigorosa.
Codice per la simulazione di clustering
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)
}
Codice per aumentare la simulazione delle funzionalità
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)
MODIFICARE
- 1 / ( p - 1 )