Иерархическая кластеризация с координатами и непространственными параметрами

#r #spatial #hierarchical-clustering

#r #пространственная #иерархическая кластеризация

Вопрос:

Допустим, у меня есть этот набор данных, содержащий центроид каждой деревни (x_cent, y_cent), а также несколько непространственных параметров, таких как общая численность населения и количество начальных школ, дороги с твердым покрытием и размер деревни.

 set.seed(1234)

dat <-
  expand.grid(
    district         = c(1:2),
    sub_district     = c(1:7),
    sub_sub_district = c(1:19), 
    village_id       = c(1:2) 
  ) %>% 
  dplyr::group_by(district, sub_district, sub_sub_district, village_id) %>%
  dplyr::mutate(
    # Total population
    tot_pop = rnorm(n = 1, mean = 100, sd = 5000),
    # Number of primary schools
    p_schl = rnorm(n = 1, mean = 2, sd = 6),
    # Paved road
    p_road = sample(0:1, size = dplyr::row_number(), replace = FALSE)
  ) %>% 
  dplyr::group_by(district, sub_district, sub_sub_district, village_id) %>% 
  dplyr::mutate(
    # Size of village in hectares
    town_hec = rnorm(n = 1, mean = 300, sd = 320)
  ) %>% 
  dplyr::group_by(district, sub_district, sub_sub_district, village_id) %>%
  dplyr::mutate(
    # Coordinates
    x_cent = rnorm(n = 1, mean = 99.9, sd = 0.66), 
    y_cent = rnorm(n = 1, mean = 33.3, sd = 0.33)
  ) %>% 
  dplyr::ungroup()
  

Я хочу создавать кластеры деревень на основе пространственной близости, а также этих непространственных параметров (tot_pop, p_schl, p_road и town_hec). Я также хочу взвесить алгоритм таким образом, чтобы пространственная близость была важнее, чем сопоставление по другим ковариатам. Наконец, я хочу иметь возможность ограничивать количество наблюдений для каждого кластера.

Я предполагаю, что это будет модель иерархической кластеризации, но я не уверен, как реализовать это в R, и возможна ли кластеризация по пространственным и непространственным ковариатам.

Заранее спасибо за любые предложения.

Ответ №1:

Поскольку метод иерархической кластеризации зависит от матрицы расстояний, простой способ придать больший вес некоторой переменной — это масштабировать эти переменные в соответствии с важностью, которую вы хотите, чтобы они имели, перед вычислением матрицы расстояний.

Комментарии:

1. Спасибо @Wawvi — как бы вы порекомендовали реализовать свое предложение в этом контексте?

2. Вы можете масштабировать свои непространственные параметры до [0; 1], а координаты x и y — до [0; 4], если хотите, чтобы пространственные параметры имели вес в 4 раза больше, чем ваши непространственные параметры. Затем вычислите матрицу расстояний для этих масштабируемых переменных с помощью функции dist(), которую затем можно передать в hclust() .

3. Понятно — спасибо за разъяснение. Я собираюсь добавить возможное решение, используя пакет scclust в разделе ответов.

Ответ №2:

Потенциальное решение, помеченное как ответ на данный момент:

Сначала измените масштаб переменных, которые вы хотите включить в свою матрицу расстояний. В этом случае я присваиваю больший вес (10) переменным координат (x_cent и y_cent).

 dat$x_cent <- scales::rescale(dat$x_cent, to = c(0, 10))
dat$y_cent <- scales::rescale(dat$y_cent, to = c(0, 10))
dat$tot_pop <- scales::rescale(dat$tot_pop, to = c(0, 1))
  

Во-вторых, подмножество данных, включающее только ковариаты, с помощью которых вы вычисляете расстояние:

 dat <- dat[, c("x_cent", "y_cent", "tot_pop")]
  

Затем вычислите матрицу расстояний:

 dist <- distances::distances(as.data.frame(dat))
  

Вычислите кластеры с помощью scclust пакета и добавьте значения к исходному набору данных. Этот пакет позволяет вам вводить ограничения на размер вашего кластера.

 clust <- scclust::hierarchical_clustering(distances = dist, size_constraint = 10)
final <- dplyr::bind_cols(dat, clust) %>% dplyr::rename(block = `...4`)
  

Вы можете видеть, сколько наблюдений существует в кластере:

 investigate_cluster <- dplyr::group_by(final, block) %>% dplyr::summarise(count = length(block))

head(investigate_cluster)

# A tibble: 6 x 2
  block     count
  <scclust> <int>
1 0            10
2 1            10
3 2            10
4 3            10
5 4            10
6 5            10
  

И легко визуализируйте свои кластеры:

 ggplot(final, mapping = aes(x = x_cent, y = y_cent, color = factor(block)))  
  geom_point()  
  ggConvexHull::geom_convexhull(alpha = .5, aes(fill = factor(block)))  
  theme_bw()   
  theme(legend.position = "none")
  

введите описание изображения здесь