自制KMeans聚类算法运行结果不一致的问题求助
自制KMeans聚类算法运行结果不一致的问题求助
我正在尝试实现一个简化版的KMeans聚类算法,但有时候运行结果会出现异常,不是每次都能得到合理的聚类效果,这是怎么回事呢?
以下是我的KMeans实现代码:
import numpy as np import random import matplotlib.pyplot as plt class KMeans: def __init__( self, n_clusters, max_iter ): self.n_clusters = n_clusters self.max_iter = max_iter def _get_distance(self, x, cluster_location): """calculate the euclidean distance from each points to the clusters center """ return np.linalg.norm(x[:,np.newaxis,:]-cluster_location, axis = 2) def fit(self, x:np.ndarray) -> None: """Steps for k-means clustering 1. initiate cluster location 2. calculate distance from each points to cluster point 3. assign each points to a cluster 4. update the cluster location using the mean of the associated points 5. repeat 2-4 until convergence or max_iter reached Args: x (_type_): _description_ Returns: _type_: _description_ """ self.x = x data_dim = x.shape[1] # 1. initiate cluster location cluster_locations = np.random.uniform(x.min(), x.max(), size=(self.n_clusters,data_dim)) # print("initial:\n",cluster_locations) for _ in range(self.max_iter): # 2. calculate distance from each points to cluster point distances = self._get_distance(x, cluster_locations) # 3. assign each points to a cluster clusters = np.argmin(distances, axis=1) # 4. update the cluster location using the mean of the associated points for cluster in range(self.n_clusters): # Check if cluster has any points cluster_mask = clusters == cluster if np.any(cluster_mask): cluster_locations[cluster] = np.mean(x[cluster_mask], axis=0) else: # If cluster is empty, reinitialize with a random point cluster_locations[cluster] = x[np.random.randint(x.shape[0])] self.cluster_locations = cluster_locations self.clusters = clusters return None def visualize(self, data, clusters): _, ax = plt.subplots(1,1,figsize=(5,5)) cluster_color = [(random.random(),random.random(),random.random()) for _ in range(self.n_clusters)] for cluster in range(self.n_clusters): to_plot = data[np.where(clusters == cluster)[0]] ax.scatter(to_plot[:,0], to_plot[:,1], color=cluster_color[cluster]) ax.scatter(self.cluster_locations[:,0], self.cluster_locations[:,1], marker="x", color='r', s=30) plt.show()
我是这样使用这个类的:
from sklearn.datasets import make_blobs random_state = 42 n_samples = 100 x, _ = make_blobs(n_samples=n_samples, random_state=random_state) my_kmeans = KMeans(3, 50) my_kmeans.fit(x) my_kmeans.visualize(x, my_kmeans.clusters)
大部分时候,运行结果是合理的:
合理输出示例:三个样本簇被正确区分,红色叉号标记的质心位置准确处于每个簇的中心区域。
但每隔几次运行,就会得到异常的结果:
异常输出示例:其中一个质心位置明显偏离对应簇,导致部分样本被错误划分,聚类效果完全不符合预期。
我是不是在实现过程中漏掉了什么关键细节?
备注:内容来源于stack exchange,提问作者Amri Rasyidi
相关产品推荐
相关产品推荐

