Это довольно старая тема, но я недавно столкнулся с этой проблемой в своей работе и наткнулся на это обсуждение. На вопрос был дан ответ, но я чувствую, что опасность нормализации строк, когда она не является единицей анализа (см. Ответ @ DJohnson выше), не была рассмотрена.
Суть в том, что нормализация строк может быть вредна для любого последующего анализа, такого как «ближайший сосед» или «k-средних». Для простоты я оставлю ответ конкретным для центрирования рядов.
Чтобы проиллюстрировать это, я буду использовать смоделированные гауссовские данные в углах гиперкуба. К счастью, R
есть удобная функция для этого (код находится в конце ответа). В двумерном случае просто, что средне-центрированные данные упадут на линию, проходящую через начало координат на 135 градусов. Имитированные данные затем группируются с использованием k-средних с правильным количеством кластеров. Данные и результаты кластеризации (визуализируются в 2D с использованием PCA на исходных данных) выглядят следующим образом (оси для самого левого графика отличаются). Различные формы точек на графиках кластеризации относятся к назначению кластера "правда-земля", а цвета являются результатом кластеризации 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)
РЕДАКТИРОВАТЬ
- 1 / ( р - 1 )