Как можно использовать оценку плотности ядра как метод кластеризации 1D в scikit learn?

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

Есть ли лучший способ выполнить эту задачу?

Ответы на некоторые другие сообщения упоминают KDE (оценка плотности ядра), но это метод оценки плотности, как это будет работать?

Я вижу, как KDE возвращает плотность, но как мне сказать, чтобы разделить данные на ящики?

Как мне установить фиксированное количество ячеек, не зависящих от данных (это одно из моих требований)?

В частности, как бы это сделать, используя scikit learn?

Мой входной файл выглядит так:

 str ID     sls
 1           10
 2           11 
 3            9
 4           23
 5           21
 6           11  
 7           45
 8           20
 9           11
 10          12

Я хочу сгруппировать номер sls в кластеры или контейнеры, чтобы:

Cluster 1: [10 11 9 11 11 12] 
Cluster 2: [23 21 20] 
Cluster 3: [45] 

И мой выходной файл будет выглядеть так:

 str ID     sls    Cluster ID  Cluster centroid
    1        10       1               10.66
    2        11       1               10.66
    3         9       1               10.66 
    4        23       2               21.33   
    5        21       2               21.33
    6        11       1               10.66
    7        45       3               45
    8        20       2               21.33
    9        11       1               10.66 
    10       12       1               10.66

Ответы

Ответ 1

Введите код самостоятельно. Тогда это лучше подходит для вашей проблемы!

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

%matplotlib inline

from numpy import array, linspace
from sklearn.neighbors.kde import KernelDensity
from matplotlib.pyplot import plot

a = array([10,11,9,23,21,11,45,20,11,12]).reshape(-1, 1)
kde = KernelDensity(kernel='gaussian', bandwidth=3).fit(a)
s = linspace(0,50)
e = kde.score_samples(s.reshape(-1,1))
plot(s, e)

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

from scipy.signal import argrelextrema
mi, ma = argrelextrema(e, np.less)[0], argrelextrema(e, np.greater)[0]
print "Minima:", s[mi]
print "Maxima:", s[ma]
> Minima: [ 17.34693878  33.67346939]
> Maxima: [ 10.20408163  21.42857143  44.89795918]

Таким образом, ваши кластеры

print a[a < mi[0]], a[(a >= mi[0]) * (a <= mi[1])], a[a >= mi[1]]
> [10 11  9 11 11 12] [23 21 20] [45]

и визуально, мы сделали это разделение:

plot(s[:mi[0]+1], e[:mi[0]+1], 'r',
     s[mi[0]:mi[1]+1], e[mi[0]:mi[1]+1], 'g',
     s[mi[1]:], e[mi[1]:], 'b',
     s[ma], e[ma], 'go',
     s[mi], e[mi], 'ro')

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

Мы разрезаем красные маркеры. Зеленые маркеры - наши лучшие оценки для кластерных центров.