Извлечение полезной информации из 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 

Если это то, что вы хотите сделать, то вы можете просто rbindfit$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
Другие вопросы по тегам