web-dev-qa-db-fra.com

Scikit-learn: Comment exécuter KMeans sur un tableau unidimensionnel?

J'ai un tableau de 13,876 (13,876) valeurs comprises entre 0 et 1. Je voudrais appliquer sklearn.cluster.KMeans à ce seul vecteur pour trouver les différents clusters dans lesquels les valeurs sont regroupées. Cependant, il semble que KMeans fonctionne avec un tableau multidimensionnel et non avec des tableaux unidimensionnels. Je suppose qu'il y a une astuce pour le faire fonctionner mais je ne sais pas comment. J'ai vu que KMeans.fit () accepte "X: matrice de type tableau ou clairsemée, forme = (n_échantillons, n_fonctionnalités)" , mais il veut que le n_samples être plus grand qu'un

J'ai essayé de mettre mon tableau sur une matrice np.zeros () et d'exécuter KMeans, mais je mets ensuite toutes les valeurs non nulles sur la classe 1 et le reste sur la classe 0.

Quelqu'un peut-il aider à exécuter cet algorithme sur un tableau unidimensionnel? Merci beaucoup!

23
Irene

Vous disposez de nombreux exemples de 1 fonctionnalité, vous pouvez donc remodeler le tableau en (13,876, 1) à l'aide de numpy's remodeler :

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
37
ryanpattison

En savoir plus sur Jenks Natural Breaks . Fonction dans Python a trouvé le lien de l'article:

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

Utilisation et visualisation:

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

Résultat:

enter image description here

4
Frank