Il s'agit d'un fil relativement ancien, mais j'ai récemment rencontré ce problème dans mon travail et suis tombé sur cette discussion. La question a été répondue, mais je pense que le danger de normaliser les lignes quand ce n'est pas l'unité d'analyse (voir la réponse de @ DJohnson ci-dessus) n'a pas été abordé.
Le point principal est que la normalisation des lignes peut être préjudiciable à toute analyse ultérieure, comme le plus proche voisin ou k-means. Par souci de simplicité, je garderai la réponse spécifique au centrage moyen des lignes.
Pour l'illustrer, j'utiliserai des données gaussiennes simulées aux coins d'un hypercube. Heureusement, R
il y a une fonction pratique pour cela (le code est à la fin de la réponse). Dans le cas 2D, il est simple que les données centrées sur la ligne moyenne tombent sur une ligne passant par l'origine à 135 degrés. Les données simulées sont ensuite regroupées à l'aide de k-moyennes avec un nombre correct de grappes. Les données et les résultats de regroupement (visualisés en 2D en utilisant PCA sur les données d'origine) ressemblent à ceci (les axes du tracé le plus à gauche sont différents). Les différentes formes des points dans les tracés de regroupement se réfèrent à l'affectation des clusters de vérité au sol et les couleurs sont le résultat du regroupement des k-moyennes.
Les grappes en haut à gauche et en bas à droite sont divisées par deux lorsque les données sont centrées sur la moyenne des lignes. Ainsi, les distances après le centrage de la ligne moyenne sont déformées et ne sont pas très significatives (au moins sur la base de la connaissance des données).
Pas si surprenant en 2D, que se passe-t-il si nous utilisons plus de dimensions? Voici ce qui se passe avec les données 3D. La solution de clustering après le centrage de la moyenne des lignes est "mauvaise".
Et similaire avec les données 4D (maintenant présentées par souci de concision).
Pourquoi cela arrive-t-il? Le centrage de la ligne moyenne pousse les données dans un espace où certaines fonctionnalités se rapprochent plus qu'elles ne le sont autrement. Cela devrait se refléter dans la corrélation entre les caractéristiques. Examinons cela (d'abord sur les données d'origine, puis sur les données centrées sur la moyenne des lignes pour les cas 2D et 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
Il semble donc que le centrage moyen des lignes introduit des corrélations entre les entités. Comment cela est-il affecté par le nombre de fonctionnalités? Nous pouvons faire une simulation simple pour comprendre cela. Les résultats de la simulation sont présentés ci-dessous (encore une fois le code à la fin).
Ainsi, à mesure que le nombre de caractéristiques augmente, l'effet du centrage de la ligne moyenne semble diminuer, au moins en termes de corrélations introduites. Mais nous venons d'utiliser des données aléatoires uniformément réparties pour cette simulation (comme cela est courant lors de l'étude de la malédiction de la dimensionnalité ).
Alors, que se passe-t-il lorsque nous utilisons des données réelles? Autant de fois la dimensionnalité intrinsèque des données est plus faible, la malédiction peut ne pas s'appliquer . Dans un tel cas, je suppose que le centrage de la moyenne des lignes pourrait être un "mauvais" choix comme indiqué ci-dessus. Bien entendu, une analyse plus rigoureuse est nécessaire pour formuler des allégations définitives.
Code de simulation de 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)
}
Code pour augmenter la simulation des fonctionnalités
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)
ÉDITER
−1/(p−1)