K означает в Python с нуля - PullRequest
       19

K означает в Python с нуля

0 голосов
/ 23 февраля 2019

У меня есть код Python для алгоритма k-средних.Мне трудно понять, что он делает.Строки типа C = X[numpy.random.choice(X.shape[0], k, replace=False), :] меня очень смущают.

Может кто-нибудь объяснить, что на самом деле делает этот код?Спасибо

def k_means(data, k, num_of_features):
    # Make a matrix out of the data
    X = data.as_matrix()
    # Get k random points from the data
    C =  X[numpy.random.choice(X.shape[0], k, replace=False), :]
    # Remove the last col
    C = [C[j][:-1] for j in range(len(C))]
    # Turn it into a numpy array
    C = numpy.asarray(C)
    # To store the value of centroids when it updates
    C_old = numpy.zeros(C.shape)
    # Make an array that will assign clusters to each point
    clusters = numpy.zeros(len(X))
    # Error func. - Distance between new centroids and old centroids
    error = dist(C, C_old, None)
    # Loop will run till the error becomes zero of 5 tries
    tries = 0
    while error != 0 and tries < 1:
        # Assigning each value to its closest cluster
        for i in range(len(X)):
            # Get closest cluster in terms of distance
            clusters[i] = dist1(X[i][:-1], C)
        # Storing the old centroid values
        C_old = deepcopy(C)
        # Finding the new centroids by taking the average value
        for i in range(k):
            # Get all of the points that match the cluster you are on
            points = [X[j][:-1] for j in range(len(X)) if clusters[j] == i]
            # If there were no points assigned to cluster, put at origin
            if not points:
                C[i][:] = numpy.zeros(C[i].shape)
            else:
                # Get the average of all the points and put that centroid there
                C[i] = numpy.mean(points, axis=0)
        # Erro is the distance between where the centroids use to be and where they are now
        error = dist(C, C_old, None)
        # Increase tries
        tries += 1
    return sil_coefficient(X,clusters,k)

1 Ответ

0 голосов
/ 23 февраля 2019

(расширенный ответ, отформатирую позже) X - это данные в виде матрицы.Используя нотацию [], мы берем срезы или выбираем отдельный элемент из матрицы.Возможно, вы захотите рассмотреть индексирование массива.https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html numpy.random.choice выбирает k элементов случайным образом из размера первого измерения матрицы данных без замены.Обратите внимание, что при индексации, используя синтаксис [], мы видим, что у нас есть две записи.Numpy.random.choice и ":".«:» указывает, что мы берем все по этой оси.

Таким образом, X [numpy.random.choice (X.shape [0], k, replace = False),:] означает, что мы выбираем элементвдоль первой оси и возьмите каждый элемент вдоль второй, которая разделяет этот первый индекс.По сути, мы выбираем случайную строку матрицы.

(комментарии достаточно хорошо объясняют этот код, я бы посоветовал вам прочесть в индексном списке список понятий для дальнейшего разъяснения).

C[C [j] [: - 1] для j в диапазоне (len (c))] Часть после «C [» использует понимание списка, чтобы выбрать части матрицы C.

C [j] представляет строки матрицы C. Мы используем [: -1], чтобы взять до, но не включая последний элемент строки.Мы делаем это для каждой строки в матрице C. Это удаляет последний столбец матрицы.

C = numpy.asarray (C).Это преобразует матрицу в массив NumPy, чтобы мы могли делать с ним специальные функции NUMPY.

C_old = numpy.zeros (C.shape).Это создает нулевую матрицу для последующего заполнения, которая имеет тот же размер, что и C. Мы инициализируем этот массив для последующего заполнения.

clusters = numpy.zeros (len (x)).Это создает нулевой вектор, размер которого равен числу строк в матрице X. Этот вектор будет заполнен позже.Мы инициализируем этот массив для последующего заполнения.

error = dist (C, C_old, None).Возьмите расстояние между двумя матрицами.Я считаю, что эта функция должна быть определена в другом месте в вашем скрипте.

попытки = 0. Установите счетчик шин на 0.

, пока ... делайте этот блок, пока выполняется это условие.

для i в [0 ...(количество строк в X - 1)]:

кластеров [i] = dist1 (X [i] [: - 1], C);Поместите, к какому кластеру i-я строка X ближе всего расположена в i-й позиции кластеров.

C_old = deepcopy (C) - Создайте копию C, которая является новой.Не просто перемещайте указатели.

для каждого (0 ... число означает - 1):

точек = [X [j] [: - 1] для j в диапазоне (len(X)) если кластеры [j] == i].Это понимание списка.Создайте список строк X со всеми, кроме последней записи, но включайте только строки, если они принадлежат j-му кластеру.

, если не точки.Если ничто не принадлежит кластеру.

C [i] [:] = numpy.zeros (C [i] .shape).Создайте вектор нулей, который будет заполнен позже, и используйте этот вектор в качестве i-й строки матрицы кластеров, C.

else:

C [i] = np.mean (points, ось = 0).Назначьте i-ую строку матрицы кластеров C средней точкой в ​​кластере.Суммируем по строкам (ось = 0).Это мы обновляем наши кластеры.

...