2015-02-09 4 views
10

मेरे पास 0 और 1 के बीच 13.876 (13,876) मानों की एक सरणी है। मैं sklearn.cluster.KMeans को केवल वेक्टर में लागू करना चाहता हूं ताकि वे अलग-अलग समूहों को ढूंढ सकें जिनमें मूल्य समूहबद्ध हैं। हालांकि, ऐसा लगता है कि केमैन एक बहुआयामी सरणी के साथ काम करता है, न कि एक-आयामी वाले। मुझे लगता है कि यह काम करने के लिए एक चाल है लेकिन मुझे नहीं पता कि कैसे। मैंने देखा कि KMeans.fit()स्वीकार करता है "एक्स: सरणी की तरह या विरल मैट्रिक्स, आकार = (N_SAMPLES, n_features)", लेकिन यह n_samples चाहता है बड़ा एक सेScikit-learn: KMeans को एक-आयामी सरणी पर कैसे चलाएं?

होने के लिए मैं एक np.zeros पर मेरे सरणी डालने की कोशिश की() मैट्रिक्स और KMeans चलाएं, लेकिन फिर कक्षा 1 पर सभी गैर-शून्य मान डाल रहे हैं और शेष 0 वर्ग 0

क्या कोई भी इस एल्गोरिदम को एक-आयामी सरणी पर चलाने में मदद कर सकता है? बहुत बहुत धन्यवाद!

उत्तर

18

आप 1 सुविधा के कई नमूने हैं, इसलिए आपको (13,876, 1) के लिए सरणी नयी आकृति प्रदान का उपयोग कर numpy के reshape कर सकते हैं:

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

यह एक आकर्षण की तरह काम किया, इस विस्तार मुझे एक घंटे के लिए अटक गया है! – iamgin

+0

यदि कोई इस प्रकार के आकार के डेटा पर मिनीबैचकिमेन का उपयोग करता है, तो कोई बहुत अलग परिणाम प्राप्त करता है। क्या यह अपेक्षित व्यवहार है ?? – marscher

+0

यह यादृच्छिक स्थिति से संबंधित है। अगर कोई इसे ठीक करता है, तो एक ही परिणाम प्राप्त करता है। – marscher

3

पढ़ें Jenks Natural Breaks के बारे में।

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 

उपयोग और दृश्य: अजगर में समारोह लेख से लिंक मिल गया

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

परिणाम: enter image description here

संबंधित मुद्दे