Извлечение полезной информации из K-Means о главных компонентах
Я работаю с относительно большим набором данных (используя только около 1/32 его, но это подмножество составляет примерно 50000x9000). Чтобы выполнить анализ этого, я предпринял несколько шагов для уменьшения размерности, чтобы затем применить алгоритм кластеризации.
Взгляните на следующий фрейм данных:
set.seed(340)
df = data.frame(replicate(10,sample(0:10,size = 10,replace = TRUE)))
> df
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
1 4 9 4 6 9 4 2 5 8 8
2 5 8 2 0 4 6 1 1 0 10
3 1 7 6 3 5 9 6 0 7 1
4 0 6 8 6 6 0 5 5 10 10
5 2 0 5 8 2 10 8 2 1 5
6 3 9 10 2 8 5 2 10 3 10
7 9 0 1 0 6 8 9 6 5 0
8 5 6 9 3 10 4 4 8 6 9
9 8 7 6 2 10 9 9 7 1 10
10 0 7 2 6 1 6 3 2 3 9
Каждый ряд представляет человека, и каждая переменная говорит о том, как часто этот человек демонстрировал это качество. Скажем, я выполняю анализ основных компонентов с помощью princomp() и собираю первые четыре компьютера для использования в качестве k.
pc = princomp(df)
new_df = cbind(pc$loadings[,1],pc$loading[,2],pc$loadings[,3],pc$loadings[,4])
fit = kmeans(new_df,2)
Из этого я могу вывести, какой кластер имеет высокие значения каких основных компонентов, где я могу использовать нагрузки, чтобы увидеть, что каждый основной компонент является общей мерой. Тем не менее, я хотел бы в конечном итоге связать эту информацию с моим исходным набором данных. Есть ли способ, которым я могу кластеризовать каждого человека в исходных данных в кластер, созданный из средства k в анализе главных компонентов? Или я неправильно понимаю концепцию PCA.
1 ответ
pc$loadings
находит координаты входных переменных, а не отдельных лиц. Так kmeans(new_df,2)
классифицирует переменные, а не отдельные лица. Чтобы убедиться в этом, попробуйте свой код с 10x5 data.frame вместо 10x10: вы получите только 5 кластерных координат:
df = data.frame(replicate(5,sample(0:10,size = 10,replace = TRUE)))
pc = princomp(df)
new_df = cbind(pc$loadings[,1],pc$loading[,2],pc$loadings[,3],pc$loadings[,4])
fit = kmeans(new_df,2)
fit$cluster
X1 X2 X3 X4 X5
2 2 1 2 2
Если это то, что вы хотите сделать, то вы можете просто rbind
fit$cluster
на ваш оригинальный data.frame, и у вас будет кластер ваших переменных.
df <- rbind(df,fit$cluster)
Однако, если вы намеревались кластеризовать отдельных лиц, то есть строк вашего исходного data.frame, вам необходимо выполнить кластеризацию по координатам строк, полученным в результате анализа основного компонента. Я не знаю, как получить доступ к тем в princomp
, но другие методы PCA позволяют это легко. FactoMineR::PCA
выводит список с координатами строки ($ind$coord
) и координаты столбца ($var$coord
).
library(FactoMineR)
pf <- PCA(df,graph=FALSE)
fit <- kmeans(pf$ind$coord[,1:4],2)
fit$cluster
1 2 3 4 5 6 7 8 9 10
1 2 1 1 1 2 1 1 1 2
Чтобы добавить их в ваш оригинальный data.frame:
df$cluster <- fit$cluster