Невозможно построить вычисленные значения центроида по существующему сюжету на основе данных

EDIT: Хорошо, если данные двухмерны следующим образом:

x = [1,1,1,2,2,2,3,3,3,4,4,4,5,5,5]
y = [8,7,5,4,3,7,8,3,2,1,9,11,16,18,19]

Затем, как вычислить k-средство (3 значения) и сделать график?


Невозможно ли выстроить расчетные значения центроида по существующему сюжету на основе данных здесь? Я хочу сделать подобный сюжет, как показано в следующей ссылке

http://glowingpython.blogspot.jp/2012/04/k-means-clustering-with-scipy.html

Однако я не мог понять. Любая помощь будет высоко оценена.

import numpy as np, matplotlib.pyplot as plt
from scipy.cluster.vq import kmeans, vq

data = np.array(np.random.rand(100))

plt.plot(data, 'ob')


centroids, variances= kmeans(data,3,10)
indices, distances= vq(data,centroids)

print (centroids)
[ 0.82847854  0.49085422  0.18256191]

plt.show()

Ответ 1

Небольшое редактирование, чтобы ответить на ваш вопрос о 2d:

Вы можете использовать оригинальный ответ ниже, просто возьмите

data = np.column_stack([x,y])

Если вы хотите построить центроиды, это будет таким же, как ниже в исходном ответе. Если вы хотите покрасить каждое значение выбранной группой, вы можете использовать kmeans2

from scipy.cluster.vq import kmeans2

centroids, ks = kmeans2(data, 3, 10)

Чтобы построить, выберите цвета k, затем используйте массив ks, возвращенный kmeans2, чтобы выбрать этот цвет из трех цветов:

colors = ['r', 'g', 'b']
plt.scatter(*data.T, c=np.choose(ks, colors))
plt.scatter(*centroids.T, c=colors, marker='v')

two d

оригинальный ответ:

Как указывает @David, ваш data является одномерным, поэтому центроид для каждого кластера также будет просто одномерным. Причина, по которой ваш сюжет выглядит 2d, заключается в том, что при запуске

plt.plot(data)

если data равно 1d, то то, что фактически выполняет функция, это plot:

plt.plot(range(len(data)), data)

Чтобы это было ясно, см. этот пример:

data = np.array([3,2,3,4,3])
centroids, variances= kmeans(data, 3, 10)
plt.plot(data)

32343

Тогда центроиды будут одномерными, поэтому они не имеют местоположения x в этом сюжете, поэтому вы можете начертить их как строки, например:

for c in centroids:
    plt.axhline(c)

lines

Если вы хотите найти центроиды пары x-y, где x = range(len(data)) и y = data, вы должны передать эти пары алгоритму кластеризации, например:

xydata = np.column_stack([range(len(data)), data])
centroids, variances= kmeans(xydata, 3, 10)

Но я сомневаюсь, что это то, чего вы хотите. Вероятно, вам нужны случайные значения x и y, поэтому попробуйте что-то вроде:

data = np.random.rand(100,2)
centroids, variances = kmeans(data, 3, 10)