【问题标题】:k-means not clustering correct in pythonk-means在python中聚类不正确
【发布时间】:2017-11-10 16:34:54
【问题描述】:

我正在尝试使用 k-means 对数据集进行聚类。当我只用一次迭代运行我的算法时,它应该返回随机簇,但是当我尝试多次迭代时,它只返回 0。我使用的矩阵是一个 50k x 140 的二进制矩阵。每行代表一个用户,每列代表一个项目。

 def clusterizator(matriz, nDeClusters, it=10): # matrix, number of clusters, number of iterations

    nOfLines = matriz.shape[0] # number of lines (users)
    nOfColumns = matriz.shape[1] # number of columns (items)
    clusterCurrently = np.zeros((nOfLines, 1)) # currently cluster assigned to each user
    listOfCurrentlyAssigneds = [] # list with numberOfClusters size, each element is a list of currently elements assigned to this cluster
    clusterCentroid = [] # centroid of each cluster

    clusterCentroid = np.random.randint(2, size=(nDeClusters, nOfColumns)) # starts with randoms centroids

    for repeat in xrange(it): # number of iterations
        listOfCurrentlyAssigneds = [[] for i in xrange(nDeClusters)] # create empty lists for each cluster

        for i in xrange(nOfLines): # for each user
            closestCentroid = clusterMaisProximo(matriz[i], clusterCentroid) # calculates the closest centroid
            clusterCurrently[i] = closestCentroid                            # assign the user to closest centroid
            listOfCurrentlyAssigneds[closestCentroid].append(matriz[i])      # put user on that centroid list

        for i in xrange(nDeClusters): # for each cluster
            if listOfCurrentlyAssigneds[i] != []: # if the list is not empty
                clusterCentroid[i] = centeroidnp(listOfCurrentlyAssigneds[i])   # calculates the new centroid




    return clusterCurrently    # return 1-column matrix with user x cluster

def distanciaEucl(elemento1, elemento2):
    return np.linalg.norm(elemento2-elemento1)  #calculates the distance between to items (or one user and one cluster)



def clusterMaisProximo(elemento, listaDeClusters):  # receive one user and the cluster's centroids list, return the closest one
    closest = 0
    closestDist = distanciaEucl(elemento, listaDeClusters[0]) # starts with the cluster[0]

    for i in xrange(len(listaDeClusters)-1): # for each cluster
        dist = distanciaEucl(elemento, listaDeClusters[i+1]) # get the distance to currently cluster's centroid
        if dist < closestDist: # if it is closer to the element
            closest = i+1 # update new closest element
            closestDist = dist # update new closest distance

    return closest   # return closest

# from https://stackoverflow.com/questions/23020659/fastest-way-to-calculate-the-centroid-of-a-set-of-coordinate-tuples-in-python-wi
# by Retozi (adapted)
def centeroidnp(lista):   # get a list of elements (number of elements x items)
    shape = list(lista[0].shape)
    shape[:0] = [len(lista)]
    arr = np.concatenate(lista).reshape(shape)   # get an array from the list
    length = arr.shape[0]
    somas = np.zeros(arr.shape[1])
    for i in xrange(arr.shape[1]): # for each item (dimension)
        somas[i] = (np.sum(arr[:, i]))/length   # sum all elements and divide by number of elements
    return somas  # return array that will be the new centroid position

我评论了所有内容以试图弄清楚每一行在做什么,有些 cmets 很愚蠢,因为起初我的变量是用葡萄牙语写的,然后我翻译了以使其更清楚。

我是这样运行的:

clust = clusterizator(train, 10, 2)

示例矩阵:

train = [[0, 1, 1, 0], [1, 0, 0, 0], [0, 1, 1, 1], [1, 0, 0, 1], [1, 0, 0, 0]]

【问题讨论】:

  • 没有“kNN 聚类”。您可能正在尝试实现 k-means。 (也有kNN分类)

标签: python cluster-analysis k-means


【解决方案1】:

我猜你有一个整数除法问题。

看看你的新质心。他们可能都是零? 这是因为在编程中(Python 3 除外)1/2=0 因为整数数学。

该算法称为 k-means,而不是 kNN。它不使用每个点的 k 个最近邻居,而是使用 1 个最近的质心。

【讨论】:

  • 对不起,我把名字弄混了。我将其更改为somas[i] = (np.sum(arr[:, i]))/float(length),但结果仍然为零。质心不为零,但由于某种原因,它们都得到了相同的值。
猜你喜欢
  • 2016-02-01
  • 2016-08-14
  • 2015-04-11
  • 2011-04-11
  • 2019-03-16
  • 2017-01-01
  • 2011-08-13
  • 2013-08-08
  • 2013-02-14
相关资源
最近更新 更多