我想使用肘部法来检查最佳的k值。我没有使用scikit-learn库。我已经从头开始编写了k-means代码,现在我很难弄清楚如何在Python中编写肘部法。我是一个完全的初学者。
这是我的k-means代码:
def cluster_init(array, k): initial_assgnm = np.append(np.arange(k), np.random.randint(0, k, size=(len(array))))[:len(array)] np.random.shuffle(initial_assgnm) zero_arr = np.zeros((len(initial_assgnm), 1)) for indx, cluster_assgnm in enumerate(initial_assgnm): zero_arr[indx] = cluster_assgnm upd_array = np.append(array, zero_arr, axis=1) return upd_arraydef kmeans(array, k): cluster_array = cluster_init(array, k) while True: unique_clusters = np.unique(cluster_array[:, -1]) centroid_dictonary = {} for cluster in unique_clusters: centroid_dictonary[cluster] = np.mean(cluster_array[np.where(cluster_array[:, -1] == cluster)][:, :-1], axis=0) start_array = np.copy(cluster_array) for row in range(len(cluster_array)): cluster_array[row, -1] = unique_clusters[np.argmin( [np.linalg.norm(cluster_array[row, :-1] - centroid_dictonary.get(cluster)) for cluster in unique_clusters])] if np.array_equal(cluster_array, start_array): break return centroid_dictonary
这是我尝试过的肘部法代码:
cost = []K= range(1,239)for k in K : KM = kmeans(x,k) print(k) KM.fit(x) cost.append(KM.inertia_)
但我得到了以下错误
KM.fit(x)
AttributeError: ‘dict’ object has no attribute ‘fit’
回答:
如果你想从头开始计算肘部值,你需要计算当前聚类分配的惯性。为此,你可以计算粒子惯性的总和。数据点的粒子惯性是从其当前位置到最近中心的距离。如果你有一个为你计算这个的函数(在scikit-learn中这个函数对应于pairwise_distances_argmin_min
),你可以这样做
labels, mindist = pairwise_distances_argmin_min( X=X, Y=centers, metric='euclidean', metric_kwargs={'squared': True})inertia = mindist.sum()
如果你真的想编写这个函数,你需要遍历X中的每一行x,找到Y中所有y的dist(x,y)的最小值,这将是x的惯性。这种计算粒子惯性的简单方法是O(nk)的,所以你可以考虑使用库函数来代替。