15

Potrzebuję skupić prosty jednoczynnikowy zestaw danych w ustalonej liczbie klastrów. Technicznie byłoby bliżej do binowania lub sortowania danych, ponieważ jest to tylko 1D, ale mój szef nazywa to grupowaniem, więc zamierzam trzymać się tej nazwy. Obecna metoda używana przez system, na którym się znajduję, to K-środki, ale to wydaje się przesadą.W jaki sposób można użyć oszacowania gęstości jądra jako metody grupowania 1D w nauce scikit?

Czy istnieje lepszy sposób wykonania tego zadania?

Odpowiedzi na niektóre inne posty wymieniają KDE (Estymacja gęstości jądra), ale to jest metoda szacowania gęstości, jak by to działało?

Widzę, jak KDE zwraca gęstość, ale jak mam powiedzieć, aby podzielić dane do pojemników?

Jak mam stałą liczbę pojemników niezależnych od danych (to jedno z moich wymagań)?

Mówiąc dokładniej, jak można to wykorzystać, ucząc się scikita?

Mój plik wejściowy wygląda następująco:

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

Chcę grupy liczbę SLS w klastry lub pojemników, tak że:

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

A mój plik wyjściowy będzie wyglądać następująco:

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 
+0

Na czym polega problem k-średnich? Wydajność? –

+0

kmeans jest bardziej wydajny niż kde – lejlot

+0

@ DavidMaust 1) Kiedy próbowałem uruchomić k-średnich sklearn na jednowymiarowych danych, zacząłem dostawać błędy. Musiałem go oszukać, ponieważ posiadałem klaster na danych 2d, które były identycznymi kopiami oryginalnych danych 1d. 2) Zgodnie z tym [post] (http://stackoverflow.com/a/11516590/3967806) jest to zły pomysł. –

Odpowiedz

24

Wpisz kod samodzielnie. Wtedy najlepiej pasuje do twojego problemu!

Płytka kotła: Nigdy nie zakładaj, że kod pobrany z sieci jest poprawny lub optymalny ... upewnij się, że w pełni go rozumiesz przed użyciem. Dlatego

%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) 

enter image description here

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] 

Twoje klastry są

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] 

i wizualnie, zrobiliśmy to dzielone: ​​

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') 

enter image description here

Cięcie przy czerwonych znacznikach. Zielone markery są naszymi najlepszymi szacunkami dla centrów klastra.

+0

Byłbym niezdecydowany, by nazwać tę metodę lepiej niż k-znaczy. Obejmuje to wybór arbitralnej szerokości pasma, a następnie obliczenie szacunkowych wartości 50 gęstości. Biorąc to pod uwagę, nie wiem, czy istnieje lepszy sposób na zrobienie tego z oceną gęstości jądra. –

+4

Nie musisz wiedzieć k. Otrzymujesz nie tylko lepsze centra (mniej odstające od wartości odstających), ale także * dźwięki * punkty podziału (nie tylko w połowie drogi). Istnieje mnóstwo literatury na temat przepustowości, takich jak zasada Silvermana. Również. kogo obchodzą obliczenia 50 gęstości? Możesz wstępnie skompilować jądro i zrobić to w szybkim splotu. –

+0

Dodam również, że jest to szczególnie szybka, nieliniowa metoda skalowania do grupowania 1D. – Matthew