web-dev-qa-db-ja.com

カーネル密度推定をscikit学習の1Dクラスタリング手法としてどのように使用しますか?

単純な一変量データセットを事前設定された数のクラスターにクラスター化する必要があります。技術的には、データが1Dのみであるため、データのビニングまたはソートに近いですが、上司はそれをクラスタリングと呼んでいるので、その名前に固執します。私が使用しているシステムで使用されている現在の方法はK平均法ですが、それはやり過ぎのようです。

このタスクを実行するより良い方法はありますか?

他のいくつかの投稿への回答では、KDE(カーネル密度推定)について言及していますが、これは密度推定方法ですが、どのように機能しますか?

KDEが密度を返す方法はわかりますが、データをビンに分割するように指示するにはどうすればよいですか?

データに依存しないビンの数を固定するにはどうすればよいですか(これは私の要件の1つです)?

より具体的には、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
24
Alex Kinman

自分でコードを記述します。次に、問題に最もよく適合します!

定型文:ネットからダウンロードしたコードが正しいまたは最適であると想定しないでください...使用する前に、コードを完全に理解してください。

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

したがって、クラスターは

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

enter image description here

赤いマーカーで切ります。緑のマーカーは、クラスターの中心を推定するのに最適です。