在使用 kmeans 创建集群时,有没有办法输出每行的失真?
Is there a way to output the distortions for each row when creating clusters with kmeans?
这里有一些代码:
df_tr_std = stats.zscore(df_tr[clmns])
km = KMeans(n_clusters=3, init='k-means++',n_init=10,max_iter=300,tol=1e-04,random_state=0)
y_km = km.fit_predict(df_tr_std)
我试过引用 inertial_,但这是完全失真的。以下代码用于计算各个距离:
distance = euclidean_distances(km.cluster_centers_, df_tr_std)
但它将距离分成 3 个数组(或者我创建的集群数量)。有没有办法不用 labels/cluster 分开?
我想用一列距离扩展我的原始数据集,以便我可以识别最大距离。我也想要最近的距离,但我能够使用以下代码找到它:
closest, _ = pairwise_distances_argmin_min(km.cluster_centers_, df_tr_std)
你可以做的是使用聚类质心和标签来索引聚类质心,以获得每个示例表示的内容。然后,您可以分别计算每个示例的失真。回想一下 K-Means 聚类结果的失真或惯性只是示例与其对应的代表性质心之间的平方差之和。要计算单个失真值,您只需找到每个示例的代表性质心,然后找到分量的平方差之和。总失真是所有这些值的总和。
因此:
cluster_centers = km.cluster_centers_
centroids = cluster_centers[y_km]
distortion = ((df_tr_std - centroids)**2.0).sum(axis=1)
第一行代码访问您拟合的 K-means 模型的聚类中心。第二行代码使用从拟合结果输出的标签获取每个示例的代表性质心。在最后一行中,您可以通过减去输入的每一行或示例及其代表质心分量来计算失真,对每个元素进行平方,然后对每一行求和。
在一行中执行此操作而不需要临时变量可能会很方便:
distortion = ((df_tr_std - km.cluster_centers_[y_km])**2.0).sum(axis=1)
这现在为您提供了每个示例的计算失真。具体来说,distortion
是一个 N,
NumPy 数组,其中 N
是数据集中的示例数。每个元素对应于相应示例对整体失真的贡献。
为了验证,您可以检查 km.inertia_
,即总失真与最后一行中计算的失真数组的总和相匹配,因此请检查 distortion.sum()
和 km.inertia_
。
作为一个可重现的例子:
In [27]: import numpy as np
In [28]: from sklearn.cluster import KMeans
In [29]: df_tr_std = np.random.rand(1000,3)
In [30]: km = KMeans(n_clusters=3, init='k-means++',n_init=10,max_iter=300,tol=
...: 1e-04,random_state=0)
In [31]: y_km = km.fit_predict(df_tr_std)
In [32]: distortion = ((df_tr_std - km.cluster_centers_[y_km])**2.0).sum(axis=1)
In [33]: km.inertia_
Out[33]: 147.01626670004867
In [34]: distortion.sum()
Out[34]: 147.01626670004865
请注意,值的尾部存在一些细微差异,这是由于数值精度所致,但您可以放心,我们已经分别计算了每个示例的失真。
获得扭曲数组后,您可以在数据框中添加一个额外的列来表示这些扭曲,然后您可以根据需要找到哪一行给您带来了最大或最小的扭曲。
这里有一些代码:
df_tr_std = stats.zscore(df_tr[clmns])
km = KMeans(n_clusters=3, init='k-means++',n_init=10,max_iter=300,tol=1e-04,random_state=0)
y_km = km.fit_predict(df_tr_std)
我试过引用 inertial_,但这是完全失真的。以下代码用于计算各个距离:
distance = euclidean_distances(km.cluster_centers_, df_tr_std)
但它将距离分成 3 个数组(或者我创建的集群数量)。有没有办法不用 labels/cluster 分开?
我想用一列距离扩展我的原始数据集,以便我可以识别最大距离。我也想要最近的距离,但我能够使用以下代码找到它:
closest, _ = pairwise_distances_argmin_min(km.cluster_centers_, df_tr_std)
你可以做的是使用聚类质心和标签来索引聚类质心,以获得每个示例表示的内容。然后,您可以分别计算每个示例的失真。回想一下 K-Means 聚类结果的失真或惯性只是示例与其对应的代表性质心之间的平方差之和。要计算单个失真值,您只需找到每个示例的代表性质心,然后找到分量的平方差之和。总失真是所有这些值的总和。
因此:
cluster_centers = km.cluster_centers_
centroids = cluster_centers[y_km]
distortion = ((df_tr_std - centroids)**2.0).sum(axis=1)
第一行代码访问您拟合的 K-means 模型的聚类中心。第二行代码使用从拟合结果输出的标签获取每个示例的代表性质心。在最后一行中,您可以通过减去输入的每一行或示例及其代表质心分量来计算失真,对每个元素进行平方,然后对每一行求和。
在一行中执行此操作而不需要临时变量可能会很方便:
distortion = ((df_tr_std - km.cluster_centers_[y_km])**2.0).sum(axis=1)
这现在为您提供了每个示例的计算失真。具体来说,distortion
是一个 N,
NumPy 数组,其中 N
是数据集中的示例数。每个元素对应于相应示例对整体失真的贡献。
为了验证,您可以检查 km.inertia_
,即总失真与最后一行中计算的失真数组的总和相匹配,因此请检查 distortion.sum()
和 km.inertia_
。
作为一个可重现的例子:
In [27]: import numpy as np
In [28]: from sklearn.cluster import KMeans
In [29]: df_tr_std = np.random.rand(1000,3)
In [30]: km = KMeans(n_clusters=3, init='k-means++',n_init=10,max_iter=300,tol=
...: 1e-04,random_state=0)
In [31]: y_km = km.fit_predict(df_tr_std)
In [32]: distortion = ((df_tr_std - km.cluster_centers_[y_km])**2.0).sum(axis=1)
In [33]: km.inertia_
Out[33]: 147.01626670004867
In [34]: distortion.sum()
Out[34]: 147.01626670004865
请注意,值的尾部存在一些细微差异,这是由于数值精度所致,但您可以放心,我们已经分别计算了每个示例的失真。
获得扭曲数组后,您可以在数据框中添加一个额外的列来表示这些扭曲,然后您可以根据需要找到哪一行给您带来了最大或最小的扭曲。