2015-02-09 19 views
10

0 ile 1 arasında 13.876 (13,876) değerden oluşan bir dizim var. sklearn.cluster.KMeans değerini yalnızca bu vektöre uygulamak ve değerlerin gruplandığı farklı kümeleri bulmak istiyorum. Bununla birlikte, KMW'ler tek boyutlu olanlarla değil, çok boyutlu bir diziyle çalışmaktadır. Sanırım işe yaratacak bir numara var ama nasıl olduğunu bilmiyorum. Ben KMeans.fit()kabul ettiğini gördük "X: dizi benzeri veya seyrek matris, şekil = (N_SAMPLES, n_features)" ama ben np.zeros benim dizi koyarak çalıştı büyük birdenScikit-learn: Tek boyutlu bir dizide KMeans nasıl çalıştırılır?

olmak n_samples istiyor() matrisini çalıştırın ve KMeans'i çalıştırın, ancak daha sonra sınıfa sıfır olmayan değerleri sınıf 1'e ve geri kalanını da sınıf 0'a koyuyorsunuz.

Bu algoritmayı tek boyutlu bir dizide çalıştırmaya yardımcı olan var mı? Çok teşekkürler!

cevap

18

Sen 1 özelliğin birçok örnekleri var, bu yüzden (1 13,876) numpy en reshape kullanarak diziyi biçimlendirebiliyor:

from sklearn.cluster import KMeans 
import numpy as np 
x = np.random.random(13876) 

km = KMeans() 
km.fit(x.reshape(-1,1)) # -1 will be calculated to be 13876 here 
+0

, bu detay beni bir saat boyunca sıkışmış var! – iamgin

+0

Bu tür şekildeki verilerde MiniBatchKmeans kullanılıyorsa, çok farklı sonuçlar elde edilir. Bu beklenen davranış mı? – marscher

+0

bu, rastgele durumla ilgilidir. Biri düzeltirse, aynı sonuçları alır. – marscher

3

yaklaşık Jenks Natural Breaks okuyun.

def get_jenks_breaks(data_list, number_class): 
    data_list.sort() 
    mat1 = [] 
    for i in range(len(data_list) + 1): 
     temp = [] 
     for j in range(number_class + 1): 
      temp.append(0) 
     mat1.append(temp) 
    mat2 = [] 
    for i in range(len(data_list) + 1): 
     temp = [] 
     for j in range(number_class + 1): 
      temp.append(0) 
     mat2.append(temp) 
    for i in range(1, number_class + 1): 
     mat1[1][i] = 1 
     mat2[1][i] = 0 
     for j in range(2, len(data_list) + 1): 
      mat2[j][i] = float('inf') 
    v = 0.0 
    for l in range(2, len(data_list) + 1): 
     s1 = 0.0 
     s2 = 0.0 
     w = 0.0 
     for m in range(1, l + 1): 
      i3 = l - m + 1 
      val = float(data_list[i3 - 1]) 
      s2 += val * val 
      s1 += val 
      w += 1 
      v = s2 - (s1 * s1)/w 
      i4 = i3 - 1 
      if i4 != 0: 
       for j in range(2, number_class + 1): 
        if mat2[l][j] >= (v + mat2[i4][j - 1]): 
         mat1[l][j] = i3 
         mat2[l][j] = v + mat2[i4][j - 1] 
     mat1[l][1] = 1 
     mat2[l][1] = v 
    k = len(data_list) 
    kclass = [] 
    for i in range(number_class + 1): 
     kclass.append(min(data_list)) 
    kclass[number_class] = float(data_list[len(data_list) - 1]) 
    count_num = number_class 
    while count_num >= 2: # print "rank = " + str(mat1[k][count_num]) 
     idx = int((mat1[k][count_num]) - 2) 
     # print "val = " + str(data_list[idx]) 
     kclass[count_num - 1] = data_list[idx] 
     k = int((mat1[k][count_num] - 1)) 
     count_num -= 1 
    return kclass 

Kullanımı ve görselleştirme: Python Fonksiyon makalesinden bağlantı buldu

import numpy as np 
import matplotlib.pyplot as plt 

def get_jenks_breaks(...):... 

x = np.random.random(30) 
breaks = get_jenks_breaks(x, 5) 

for line in breaks: 
    plt.plot([line for _ in range(len(x))], 'k--') 

plt.plot(x) 
plt.grid(True) 
plt.show() 

Sonuç: Bir cazibe gibi çalıştı enter image description here