Получить 100 выборок, ближайших к центроидам каждого кластера после того, как K означает кластеризацию с использованием R

Я пытаюсь уменьшить размер входных данных, сначала выполняя кластеризацию K-средних в R, а затем отбирая 50–100 выборок для каждого репрезентативного кластера для последующей классификации и выбора функций.

Первоначальный набор данных был разделен на 80/20, а затем 80% пошло на обучение с использованием K-средств. Я знаю, что входные данные имеют 2 столбца меток и 110 столбцов числовых переменных. Из столбца на этикетке я знаю, что существует 7 различных лекарств. Параллельно я протестировал метод локтя, чтобы найти оптимальное значение K для числа кластеров, оно составляет около 8. Я выбрал 10, чтобы иметь больше кластеров данных для выборки для нисходящего потока.

Теперь я закончил запуск модели ‹- Kmeans (), список вывода немного запутал меня в том, что делать. Поскольку мне нужно масштабировать только числовые переменные для ввода в функцию kmeans, членство в выходном кластере больше не имеет этих меток обработки. Я могу преодолеть это, добавив членство в кластере к исходной таблице обучающих данных.

Тогда для 10 центроидов, как мне узнать, что это за метки? Я не могу просто сделать

training_set$centroids <- model$centroids

И самый важный вопрос, как мне найти 100 выборок на кластер, которые близки к их соответствующему центроиду? Я видел здесь одно сообщение на Python, но ресурсов R. Вывести 50 ближайших образцов в каждый кластерный центр с помощью библиотеки scikit-learn.k-means Есть указатели?


person ML33M    schedule 01.11.2020    source источник


Ответы (1)


Для начала нам нужен воспроизводимый пример ваших данных:

set.seed(42)
x <- matrix(runif(150), 50, 3)
kmeans.x <- kmeans(x, 10)

Теперь вы хотите найти наблюдения в исходных данных x, которые наиболее близки к центроидам, вычисленным и сохраненным как kmeans.x. Мы используем функцию get.knnx() в пакете FNN. Мы просто получим 5 ближайших наблюдений для каждого из 10 кластеров.

library(FNN)
y <- get.knnx(x, kmeans.x$centers, 5)
str(y)
# List of 2
#  $ nn.index: int [1:10, 1:5] 42 40 50 22 39 47 11 7 8 16 ...
#  $ nn.dist : num [1:10, 1:5] 0.1237 0.0669 0.1316 0.1194 0.1253 ...
y$nn.index[1, ]
# [1] 42 38  3 22 43
idx1 <- sort(y$nn.index[1, ])
cbind(idx1, x[idx1, ])
#      idx1                          
# [1,]    3 0.28614 0.3984854 0.21657
# [2,]   22 0.13871 0.1404791 0.41064
# [3,]   38 0.20766 0.0899805 0.11372
# [4,]   42 0.43577 0.0002389 0.08026
# [5,]   43 0.03743 0.2085700 0.46407

Индексы строк ближайших соседей хранятся в nn.index, поэтому для первого кластера 5 ближайших наблюдений - это 42, 38, 3, 22, 43.

person dcarlson    schedule 01.11.2020
comment
Это фантастика!!!!!!!!!!!!!!! Именно такого результата я и желал. Это так мило! - person ML33M; 02.11.2020
comment
так что я также прав, чтобы предположить, что в y ‹- get.knnx (x, kmeans.x $ center, 5), вместо того, чтобы помещать в свой обучающий набор данных x, я могу фактически сначала масштабировать (мой общий набор данных), и поместил мой общий набор данных в эту строку, чтобы он выловил ближайших соседей, которых я хочу, из всего набора данных. - person ML33M; 02.11.2020
comment
или я просто объединяю вещи, которые не должны так поступать @dcarlson - person ML33M; 02.11.2020
comment
и, наконец, извините. в cbind (idx1, x [idx1,]), потому что данные x фактически являются только числовой частью исходных данных, скажем x ‹- m [, -c (1,2)]. Итак, я попытался cbind (idx1, m [idx1,]), похоже, это сработало, таким образом я знаю фактическую этикетку лекарства в каждом кластере. Это правильный код? или он просто случайным образом добавит idx1 к моим исходным данным m - person ML33M; 02.11.2020
comment
Да, вы можете ввести общий набор данных, поскольку я не ограничивал поиск фактически засекреченными наблюдениями. Да, вы можете использовать другую матрицу / фрейм данных, если в нем будут те же наблюдения в том же порядке. - person dcarlson; 02.11.2020