Кластерный анализ в R: оптимальная кластеризация, когда АЛГОРИТМ НЕ ПРИМЕНЯЛСЯ

#r #cluster-analysis

Вопрос:

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

Код кластеризации является:

 threshold <- 0.9
df$cluster_9 <- graph_from_adjacency_matrix(abs(cor(t(df))) > threshold) %>% 
  components() %>%
  membership() %>%
  as.vector()
 

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

Для этого я мог бы рассчитать скорректированный R2 кластеров с различными пороговыми значениями, но без целевой кластеризации мне не хватает идеи о том, как ее рассчитать.

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

1. Вам нужен метод кластеризации, определяющий, как группировать узлы графа в кластеры. Я не вижу такого метода, как hclust или kmeans в вашем коде. Или вы хотите сравнить дендрограммы?

2. @danlooo Я не использовал ни один из этих методов. Я вручную сгруппировал экземпляры, корреляция которых превышает 0,9. Это и есть метод кластеризации

Ответ №1:

Вы можете создать таблицу с одним пороговым значением в строке, а затем создать столбцы для вектора компонентов и показателя для оценки (например, количество кластеров).:

 library(tidyverse)
library(igraph)
#> 
#> Attaching package: 'igraph'
#> The following objects are masked from 'package:dplyr':
#> 
#>     as_data_frame, groups, union
#> The following objects are masked from 'package:purrr':
#> 
#>     compose, simplify
#> The following object is masked from 'package:tidyr':
#> 
#>     crossing
#> The following object is masked from 'package:tibble':
#> 
#>     as_data_frame
#> The following objects are masked from 'package:stats':
#> 
#>     decompose, spectrum
#> The following object is masked from 'package:base':
#> 
#>     union

df <-
  diamonds %>%
  select(where(is.numeric)) %>%
  head(10)


tibble(threshold = seq(0, 1, by = 0.1)) %>%
  mutate(
    clustering = threshold %>% map(~ {
      graph_from_adjacency_matrix(abs(cor(df)) > .x) %>%
        components() %>%
        membership() %>%
        as.vector()
    }),
    n_clusters = clustering %>% map_int(~ .x %>%
      unique() %>%
      length())
  )
#> # A tibble: 11 x 3
#>    threshold clustering n_clusters
#>        <dbl> <list>          <int>
#>  1       0   <dbl [7]>           1
#>  2       0.1 <dbl [7]>           1
#>  3       0.2 <dbl [7]>           1
#>  4       0.3 <dbl [7]>           1
#>  5       0.4 <dbl [7]>           1
#>  6       0.5 <dbl [7]>           1
#>  7       0.6 <dbl [7]>           3
#>  8       0.7 <dbl [7]>           4
#>  9       0.8 <dbl [7]>           4
#> 10       0.9 <dbl [7]>           4
#> 11       1   <dbl [7]>           7
 

Создано 2021-09-08 пакетом reprex (v2.0.1)

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

1. Это уже хорошее начало, но я хотел бы проанализировать эффективность кластеризации с различными пороговыми значениями. В n_cluster ничего не говорится о качестве. Как я мог бы интегрировать в ваш код, например, скорректированную меру R2?

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

3. Эй, @danlooo, как будет выглядеть код, если я применю оценку силуэта в вашем коде для автоматического выбора наилучшего порога для кластеризации?