Це відносно стара тема, але я нещодавно зіткнувся з цим питанням у своїй роботі і натрапив на цю дискусію. На це питання відповіли, але я вважаю, що небезпека нормалізації рядків, коли це не одиниця аналізу (див. Відповідь 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)
EDIT
Після деякого гуглінгу опинився на цій сторінці, де симуляції демонструють подібну поведінку, і пропонується, щоб кореляція, запроваджена центром середнього рядка, становила .- 1/ ( р - 1 )