#r #cluster-analysis
#r #кластерный анализ
Вопрос:
Я хочу применить иерархический кластерный анализ с R. Я знаю о hclust()
функции, но не знаю, как использовать это на практике; я застрял с подачей данных в функцию и обработкой выходных данных.
Я также хотел бы сравнить иерархическую кластеризацию с той, что создана kmeans()
. Опять же, я не уверен, как вызвать эту функцию или использовать / манипулировать выводом из нее.
Мои данные похожи на:
## dummy data
require(MASS)
set.seed(1)
dat <- data.frame(mvrnorm(100, mu = c(2,6,3),
Sigma = matrix(c(10, 2, 4,
2, 3, 0.5,
4, 0.5, 2), ncol = 3)))
Комментарии:
1. Я попытался улучшить исходный вопрос, потому что (и я не независимый наблюдатель, но …) Я думаю, что ответы здесь, по крайней мере, полезны и заслуживают того, чтобы остаться здесь. Пожалуйста, помогите, отредактировав его, если вы можете улучшить дальше.
2. @Гэвин Симпсон: Ты святой, и я вновь открыл вопрос. Я также удалил все ранее опубликованные комментарии, поскольку они больше не актуальны (не говоря уже о реальном бельме на глазу), и уберу их, как только вы их увидите.
3. Действительно ли имеет смысл в значительной степени заменять устаревший вопрос, которому больше года, и на который следует ответить знаменитым «прочитайте руководство» или «Google для «hclust R tutorial»»? Кроме того, я не удивлюсь, если здесь уже есть 10 дубликатов.
4. Затем закройте вопрос как дублирующий. Затем ответ может быть объединен или сохранен. Если бы не было хороших ответов, я бы согласился, но есть, и люди пытались удалить это только из-за качества вопроса. По крайней мере, вопрос теперь не воняет. Совет по Meta — делать то, что я сделал.
5. @BoltClock Спасибо за это. Я также отредактировал ответ, чтобы он больше соответствовал отредактированному вопросу. Комментарий к ответу теперь не помешало бы прояснить, если у вас будет такая возможность. Я могу удалить некоторые из своих, но те, что находятся в OP, потребуют некоторого внимания к модификации. Будет отмечено позже.
Ответ №1:
Для иерархического кластерного анализа внимательно ознакомьтесь с ?hclust
и запустите его примеры. Альтернативные функции находятся в пакете cluster, который поставляется с R. Кластеризация k-means доступна в function kmeans()
, а также в cluster
пакете.
Простой иерархический кластерный анализ показанных вами фиктивных данных будет выполнен следующим образом:
## dummy data first
require(MASS)
set.seed(1)
dat <- data.frame(mvrnorm(100, mu = c(2,6,3),
Sigma = matrix(c(10, 2, 4,
2, 3, 0.5,
4, 0.5, 2), ncol = 3)))
Вычислите матрицу различий, используя евклидовы расстояния (вы можете использовать любое расстояние, которое вы хотите)
dij <- dist(scale(dat, center = TRUE, scale = TRUE))
Затем сгруппируйте их, скажем, используя иерархический метод группового среднего
clust <- hclust(dij, method = "average")
Вывод результата дает нам:
R> clust
Call:
hclust(d = dij, method = "average")
Cluster method : average
Distance : euclidean
Number of objects: 100
Plot the dendrogram
но этот простой вывод противоречит сложному объекту, которому требуются дополнительные функции для извлечения или использования содержащейся в нем информации:
R> str(clust)
List of 7
$ merge : int [1:99, 1:2] -12 -17 -40 -30 -73 -23 1 -52 -91 -45 ...
$ height : num [1:99] 0.0451 0.0807 0.12 0.1233 0.1445 ...
$ order : int [1:100] 84 14 24 67 46 34 49 36 41 52 ...
$ labels : NULL
$ method : chr "average"
$ call : language hclust(d = dij, method = "average")
$ dist.method: chr "euclidean"
- attr(*, "class")= chr "hclust"
Дендрограмма может быть сгенерирована с помощью plot()
метода ( hang
получает метки в нижней части дендрограммы вдоль оси x и cex
просто уменьшает все метки до 70% или нормального размера)
plot(clust, hang = -0.01, cex = 0.7)
Допустим, нам нужно 3-кластерное решение, сократите дендрограмму, чтобы создать 3 группы, и верните членство в кластере
R> cutree(clust, k = 3)
[1] 1 2 1 2 2 3 2 2 2 3 2 2 3 1 2 2 2 2 2 2 2 2 2 1 2 3 2 1 1 2 2 2 2 1 1 1 1
[38] 2 2 2 1 3 2 2 1 1 3 2 1 2 2 1 2 1 2 2 3 1 2 3 2 2 2 3 1 3 1 2 2 2 3 1 2 1
[75] 1 2 3 3 3 3 1 3 2 1 2 2 2 1 2 2 1 2 2 2 2 2 3 1 1 1
То есть cutree()
возвращает вектор той же длины, что и количество кластеризованных наблюдений, элементы которого содержат идентификатор группы, к которой принадлежит каждое наблюдение. Членство — это идентификатор листа, в который попадает каждое наблюдение, когда дендрограмма обрезается на указанной высоте или, как сделано здесь, на соответствующей высоте, чтобы обеспечить указанное количество групп.
Возможно, этого вам достаточно для продолжения?
Для k-средних мы бы сделали это
set.seed(2) ## *k*-means uses a random start
klust <- kmeans(scale(dat, center = TRUE, scale = TRUE), centers = 3)
klust
что дает
> klust
K-means clustering with 3 clusters of sizes 41, 27, 32
Cluster means:
X1 X2 X3
1 0.04467551 0.69925741 -0.02678733
2 1.11018549 -0.01169576 1.16870206
3 -0.99395950 -0.88605526 -0.95177110
Clustering vector:
[1] 3 1 3 2 2 3 1 1 1 1 2 1 1 3 2 3 1 2 1 2 2 1 1 3 2 1 1 3 3 1 2 2 1 3 3 3 3
[38] 1 2 2 3 1 2 2 3 3 1 2 3 2 1 3 1 3 2 2 1 3 2 1 2 1 1 1 3 1 3 2 1 2 1 3 1 3
[75] 3 1 1 1 1 1 3 1 2 3 1 1 1 3 1 1 3 2 2 1 2 2 3 3 3 3
Within cluster sum of squares by cluster:
[1] 47.27597 31.52213 42.15803
(between_SS / total_SS = 59.3 %)
Available components:
[1] "cluster" "centers" "totss" "withinss" "tot.withinss"
[6] "betweenss" "size"
Здесь мы получаем некоторую информацию о компонентах объекта, возвращаемого kmeans()
. $cluster
Компонент выдаст вектор принадлежности, сопоставимый с выводом, который мы видели ранее из cutree()
:
R> klust$cluster
[1] 3 1 3 2 2 3 1 1 1 1 2 1 1 3 2 3 1 2 1 2 2 1 1 3 2 1 1 3 3 1 2 2 1 3 3 3 3
[38] 1 2 2 3 1 2 2 3 3 1 2 3 2 1 3 1 3 2 2 1 3 2 1 2 1 1 1 3 1 3 2 1 2 1 3 1 3
[75] 3 1 1 1 1 1 3 1 2 3 1 1 1 3 1 1 3 2 2 1 2 2 3 3 3 3
В обоих случаях обратите внимание, что я также масштабирую (стандартизирую) данные, чтобы позволить сравнивать каждую переменную в общем масштабе. Для данных, измеренных в разных «единицах» или в разных масштабах (как здесь с разными средними и отклонениями), это важный этап обработки данных, если результаты должны быть значимыми или не зависеть от переменных, имеющих большие отклонения.
Комментарии:
1. @sridher ошибка, загрузите свои данные в R. Существует множество способов сделать это в зависимости от формата ваших данных. Я думаю, вам нужно сделать шаг назад и прочитать некоторые вводные руководства по R, а именно «Введение в R» и руководство «Импорт / экспорт данных R», оба доступны здесь: cran.r-project.org/manuals.html
2. Мой набор данных состоит из csv-файла …. я импортировал его в консоль, используя эту функцию > data1 <- read.csv(file.choose(), header = TRUE) теперь data1 — это мой набор данных… с этого момента я не могу этого сделать …. пожалуйста, можете ли вы объяснить упоминание этой переменной data1, чтобы я мог получать кластеры…
3. извините, что беспокою вас … но моя голова только что предоставила огромный набор данных и попросила меня сделать это за 2 дня 🙁 …. но я совершенно новичок в этом … пожалуйста, не обращайте внимания на глупые вопросы… но для меня это не глупо!
4. Итак, в моем коде
dat
играет роль вашdata1
. Итак, посмотрите на мой код и заменитеdat
наdata1
во всех вызовах функций. Теперь, сработает это или нет, будет зависеть от того, какие типы данных есть в вашем,data1
и поскольку у меня их нетdata1
, я не могу сказать, будет ли код работать с вашими данными или нет.5. Это самое высокое соотношение качества ответа / вопроса, которое я видел за последнее время.