K-Means 算法质心未放置在簇中

K-Means algorithm Centroids are not placed in the clusters

我有问题。我想聚类我的数据集。不幸的是,我的质心不在集群内,而是在集群外。我已经读过 Python k-mean, centroids are placed outside of the clusters关于这个。

但是,我不知道是什么原因。我怎样才能正确聚类?

您可以在 https://gist.githubusercontent.com/Coderanker3/24c948d2ff0b7f71e51b3774c2cc7b22/raw/253ba0660720de3a9cf7dee2a2d25a37f61095ca/Dataset

找到数据集
import pandas as pd
from sklearn.cluster import KMeans
from scipy.cluster import hierarchy
import seaborn as sns
from sklearn import metrics
from sklearn.metrics import silhouette_samples
import matplotlib as mpl
import matplotlib.pyplot as plt

df = pd.read_csv(r'https://gist.githubusercontent.com/Coderanker3/24c948d2ff0b7f71e51b3774c2cc7b22/raw/253ba0660720de3a9cf7dee2a2d25a37f61095ca/Dataset')
df.shape

features_clustering = ['review_scores_accuracy',
 'distance_to_center',
 'bedrooms',
 'review_scores_location',
 'review_scores_value',
 'number_of_reviews',
 'beds',
 'review_scores_communication',
 'accommodates',
 'review_scores_checkin',
 'amenities_count',
 'review_scores_rating',
 'reviews_per_month',
 'corrected_price']

df_cluster = df[features_clustering].copy()
X = df_cluster.copy()

model = KMeans(n_clusters=4, random_state=53, n_init=10, max_iter=1000, tol=0.0001)
clusters = model.fit_predict(X)
df_cluster["cluster"] = clusters

fig = plt.figure(figsize=(8, 8))
sns.scatterplot(data=df_cluster, x="amenities_count", y="corrected_price", hue="cluster", palette='Set2_r')
sns.scatterplot(x=model.cluster_centers_[:,0], y=model.cluster_centers_[:,1], color='blue',marker='*',
                            label='centroid', s=250)
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
#plt.ylim(ymin=0)
plt.xlim(xmin=-0.1)
plt.show()

model.cluster_centers_

inertia = model.inertia_
sil = metrics.silhouette_score(X,model.labels_)

print(f'inertia {inertia:.3f}')
print(f'silhouette {sil:.3f}')

[OUT]

inertia 4490.076
silhouette 0.156

您的主要问题的答案:聚类中心在您的聚类之外。

1:您正在对 features_clustering 列表中显示的 14 个特征进行聚类。

2 :您正在二维 space 上查看集群,任意选择数据 amenities_countcorrected_price 以及集群中心的两个坐标 x=model.cluster_centers_[:,0], y=model.cluster_centers_[:,1] 不对应相同的特征。

由于这些原因,您将得到奇怪的结果;他们真的没有任何意义。

底线是您无法查看二维上的 14 维聚类。

为了更清楚地显示点 2,将簇线的绘图更改为

sns.scatterplot(x=model.cluster_centers_[:,10], y=model.cluster_centers_[:,13], color='blue',marker='*', label='centroid', s=250)

根据与数据相同的特征绘制聚类中心。


关于聚类中心在聚类数据之外的 SO 答案的 link 是关于在聚类之前将数据缩放到 0 和 1 之间,然后在绘图时不缩放聚类中心与真实数据。这与您此处的问题不同。

您正在制作多维聚类并且希望它们适合二维地图,它本身是行不通的。让我解释一下,一个变量是一个维度:x1,x2,x3,...,xn 如果你找到簇,它会给你结果 y1,y2,y3,...,yn。如果您在 2D 中映射结果,(我以您为例) x1 是“amenities_count”,x5 是“corrected_price”。

它将创建仅包含这两个变量的 2D 地图,并且绘图仪肯定会看到您使用 2D 地图,只会从簇中提取前两个变量 y1 和 y2 进行绘图。请注意,xi 与 y1 没有直接关系。

您必须:1) 进行转换以找到其对应的 x、y 或 2) 降低您用于生成包含所有变量信息的 2D 地图的数据的维数。

对于第一种情况,我不是很确定,因为我没有做过(Remapping the data)。 但是在降维上,我推荐大家使用https://en.wikipedia.org/wiki/T-distributed_stochastic_neighbor_embedding或者经典的PCA

道德:如果你想看到一个二维集群,确保你只有 2 个变量。