R Неконтролируемая кластеризация по группам (?) - PullRequest
0 голосов
/ 07 июня 2019

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

Я собираюсь объяснить это на основе двух графиков, которые Вы можете найти ниже (каждый график описывает одну группу):

Участок 1 для Группы 1 : enter image description here

Мы можем видеть, что есть много точек, лежащих почти на одной оси y -> и я пытаюсь выяснить , как найти группы, имеющие такое "распределение точек"

Ниже у нас есть график 2 из Группа 2 , который не показывает такого "распределения точек"

enter image description here

Здесь мы можем найти данные , которые соответствуют обоим графикам выше :

structure(list(Group = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1), 
    x = c(100L, 150L, 250L, 287L, 312L, 387L, 475L, 550L, 837L, 
    937L, 987L, 1087L, 1175L, 1300L, 1325L, 1487L, 1662L, 1700L, 
    1725L, 1812L, 1912L, 2412L, 3012L, 3562L, 4162L, 4762L, 5362L, 
    5750L, 5712L, 6225L, 6825L, 6887L, 7237L, 7850L, 7800L, 7937L, 
    7975L, 8275L, 8362L, 8662L, 8725L, 8950L, 9100L, 9312L, 9400L, 
    9600L, 550L, 612L, 1962L, 5412L, 8425L, 9375L, 5412L), y = c(493L, 
    482L, 479L, 476L, 481L, 479L, 474L, 480L, 480L, 491L, 489L, 
    490L, 485L, 485L, 485L, 479L, 482L, 482L, 482L, 482L, 484L, 
    489L, 491L, 489L, 496L, 498L, 500L, 0L, 498L, 500L, 502L, 
    506L, 497L, 0L, 495L, 506L, 497L, 494L, 498L, 500L, 496L, 
    499L, 496L, 495L, 495L, 498L, 442L, 447L, 394L, 465L, 806L, 
    700L, 502L)), row.names = c(23L, 24L, 25L, 26L, 27L, 28L, 
29L, 30L, 31L, 32L, 33L, 34L, 35L, 36L, 37L, 38L, 39L, 40L, 41L, 
42L, 43L, 44L, 45L, 46L, 47L, 48L, 49L, 51L, 52L, 53L, 54L, 55L, 
56L, 57L, 58L, 59L, 60L, 61L, 62L, 63L, 64L, 65L, 66L, 67L, 68L, 
69L, 574L, 575L, 576L, 577L, 578L, 579L, 815L), class = "data.frame")

Краткое объяснение:

Group   x   y
1 100 493
1 150 482
1 250 479
1 287 476
1 312 481
1 387 479

У нас есть каждая группа (1 и 2), координаты х и у.

Мой подход до сих пор:

Я округлил ось Y до 20, используя этот код

    round_any = function(x, accuracy, f=round){f(x/ accuracy) * accuracy} # function to round the y 
data$y_rd <- round_any(data$y, 20)

Я сделал это, потому что обычно указываетне кладите специально на одну и ту же строку y ..

Кроме того, я использовал этот код для создания кластеров для каждой группы на основе координаты x для каждой y_rd (округленная координата y):

    data$id <- paste(data$Group, data$y_rd, sep = "_") # create id that contains Group and y_rd values
    res2 <- tapply(data$x, INDEX = data$id, function(x) kmeans(x,2)) # kmeans with fixed number of clusters    
    res3 <- lapply(names(res2), function(x) data.frame(y=x, Centers=res2[[x]]$centers, Size=res2[[x]]$size))     
    res3 <- do.call(rbind, res3)

Однако это не работает так, как мне нужно, поскольку я не могу определить фиксированный номер кластера для каждой группы и y_rd ...

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

Результат, который я хотел бы получить:

Group Cluster MaxPoints
1      1         3
1      2         20
1      3         7

enter image description here

Я открыт для любых идей или советов, которые помогли бы мне найти группы, демонстрирующие такой сбор.Спасибо!

1 Ответ

1 голос
/ 07 июня 2019

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

Поскольку кажется, что наиболее важной переменной является y, вы можете попробоватьчтобы изучить его в группах, затем примените k-средства к группам «победителей».

Сначала вы можете попытаться обнаружить группы, которые предположительно имеют «линейное» распределение, просматривая какой-то блокпост или гистограммы.:

dats %>% ggplot(aes(y_rd)) + geom_histogram() + facet_wrap(vars(Group)) + theme_light()

enter image description here

Теперь кажется, что есть группа с длинной линией и меньшим кластером (1) и группа с большим количеством маленьких кластеров(2). Так что в этом случае вы можете разделить ваши данные на группы, которые имеют два кластера (и длинную линию), с 1, и группу со многими «маленькими кластерами» без длинной строки (2).Идея состоит в том, чтобы разделить ваши 100 групп на «нет длинной линии», «длинная линия и 1 маленький кластер», «длинная линия и 2 маленьких кластера» и так далее.Имея их, вы можете разделить набор данных и выполнить кластеризацию.В этом случае мы отбрасываем вторую группу и используем k-среднее с 2 центрами для второй, поскольку кажется, что она имеет длинную линию и еще один небольшой кластер.

vec <- c(1)  # vector of groups that seems they've long line

 # a loop to cluster them: clearly this is fixed to two clusters, looking at the
 # histograms you can do n loop, one for similar distributions
listed <- list()
for (i in vec){
  clustering <- kmeans(dats[dats$Group == 1,c(4)],2)
  listed[[i]] <- data.frame(dats[dats$Group == i,c(4)],cl = clustering$cluster)
}

Теперь вы можете построить ее:

library(ggplot2)
ggplot(listed[[1]], aes(x,y, color = as.factor(cl))) + geom_point() + theme_light()

enter image description here

...