我如何计算 python 中每个质心的密度?

How can i calculate density of every centroid in python?

我有 kmeans 聚类数据和 kmeans 的聚类质心。我想计算每个簇质心的密度并删除最高簇质心密度的簇。我做了我的研究,找到了这个公式。

N(c)是簇c的一组邻居簇质心,应该是5 我试图实现该算法但做不到。你能帮我实现吗?

到目前为止,这是我的代码:

df = make_blobs(n_samples=5000, n_features=15,centers=15, cluster_std=1,random_state=10)
X,y=df
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=10)
TrainData=X_train,y_train
n_clusters_sampling=10
 
kmeans2 = KMeans(n_clusters = n_clusters_sampling,random_state=10)
kmeans2.fit(X_train)
centroids = kmeans2.cluster_centers_

你可以用曼哈顿距离做到 公式为 d(p, q) = d(q,p) = Sum (|qi-pi|)

def ManhattanDistance(x, y):
    S = 0;
    for i in range(len(x)):
        S += abs(int(x[i])- int(y[i]))

    return S

和她你可以得到射程

def Classify(centroieds, item):
    minimum =10000;
    for i in range(len(centroieds)):

        # Find distance from item to mean
        dis = ManhattanDistance(item, centroieds[i]);

        if (dis < minimum):
            minimum = dis;
            index = i;

    return index;

你可以找到适合她的克拉斯特 我把所有的集群放在一个字典中

def FindClusters(centroieds):
    clusters = {} # Init clusters

    for i in range(200):
        item = l[i]

        # Classify item into a cluster
        index = Classify(means, item);

        # Add item to cluster
        if index in clusters.keys():
            clusters[index].append()
        else:
            clusters[index] = l[i]
            clusters[index].append(l[i])

   
    return(clusters)

这不是我的全部代码,它只是其中的一部分,希望对您有所帮助。

你的问题本质上是对质心形成的“新数据集”的“k-最近邻搜索”。您需要每个质心最接近的 5 个及其相关距离。幸运的是,sklearn 确实有 NearestNeighbors class 提供了这个功能:

...
centroids = kmeans2.cluster_centers_

from sklearn.neighbors import NearestNeighbors
nn = NearestNeighbors(n_neighbors=6) # 6 is not a typo. Explanation below.
nn.fit(centroids)
neigh_dist, neigh_ind = nn.kneighbors(centroids, return_distance=True)
densities = [5/np.sum(neigh_dist[i,:]) for i in range(centroids.shape[0])]
print(densities)

请注意,我们正在用我们正在执行查询的相同数据点(质心)拟合 nn 对象。 这就是 n_neighbors 为 6 的原因:对于每个质心,它本身将是距离为零的最近邻居。
.kneighbors() 方法,当 return_distance 设置为 True 时,(也)returns 形状为(nn_neighbors)的距离数组,其中 n 是查询点的数量 - 即质心。该数组的 i,j 单元格告诉您邻居 j 与质心 [=42] 的距离=]我。因此,我们根据您正在 posting.

的公式取每行的平均值来计算密度

编辑:答案的下一部分解决了 OP 关于删除最高密度集群的评论。

删除一个集群,比如说,c 本质上意味着将其数据点的集群标签重新分配给下一个最接近的质心。所以,现在我们有了一个新的 1-最近邻问题,我们可以再次使用我们创建的 NearestNeihbors 对象。

我们对“质心数据集”执行 2 最近邻搜索,以查找最初分配给 c 的点。
第一个邻居当然是 c,所以我们只保留第二个最近的邻居。
然后我们简单地用新索引更新这些数据点的原始分配table。

# run k-means and get an array of initial cluster assignments.
assignments = kmeans2.predict(X_train)

# find the index of cluster to be removed
c = np.argmax(densities)

# for each point originally assigned to c, find its closest centroid.
# Again we are using the trick of searching for one more neighbor since we know
# the closest centroid of those points will be c.
nearest_centroids = nn.kneighbors(X_train[assignments==c,:], n_neighbors=2, return_distance=False)

# get the new closest cenroid (that is, the second column of the array) and make it 1D
nearest_centroids = nearest_centroids[:,1].flatten()

# simply update the initial assignment table for the specific datapoints
assignments[assignments==c] = nearest_centroids

assignments 数组现在不包含 c 的值。请注意,这可能会在绘制或对结果进行其他 post 处理时留下一个“洞”,因为会有一个没有分配点的集群。如果你想避免这种情况,只需将高于 c:

的索引减去一个
assignments = np.array([i-1 if i>c else i for i in assignments]) 

如果您还想删除质心:

centroids = np.delete(centroids, c, axis=0) # remove row from numpy array by index