根据菜菜的课程进行整理,方便记忆理解
代码位置如下:
sklearn.cluster.KMeans
class sklearn.cluster.KMeans (
n_clusters
=8, init=’k-means++’, n_init=10,max_iter
=300, tol=0.0001,precompute_distances=’auto’, verbose=0, random_state=None, copy_x=True, n_jobs=None, algorithm=’auto’)
n_clusters
n_clusters是KMeans中的k,表示着我们告诉模型我们要分几类。这是KMeans当中唯一一个必填的参数,默认为8类,但通常我们的聚类结果会是一个小于8的结果。通常,在开始聚类之前,我们并不知道n_clusters究竟是多少,因此我们要对它进行探索。
当我们拿到一个数据集,如果可能的话,我们希望能够通过绘图先观察一下这个数据集的数据分布,以此来为我们聚类时输入的n_clusters做一个参考。 首先,我们来自己创建一个数据集。这样的数据集是我们自己创建,所以是有标签的。
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
# 我们使用make_blobs制作随机点
x,y = make_blobs(n_samples=500,n_features=2,centers=4,random_state=1)
# 绘图完成
fig,axis = plt.subplots(1)
axis.scatter(x[:,0],x[:,1],marker="o",s=8)
plt.show()
# 我们对于每一类的数据完成上色
fig,axis = plt.subplots(1)
color = ["red","blue","black","yellow"]
for i in range(4):
axis.scatter(x[y==i,0],x[y==i,1],marker="o",s=8)
plt.show()
基于这个分布,我们来使用Kmeans进行聚类
# 使用kmeans完成聚类
from sklearn.cluster import KMeans
km = KMeans(n_clusters=3,random_state=0).fit(x)
# labels_这个属性我们可以看到我们聚类下,数据的类别
y_pred = km.labels_
y_pred
"""
array([1, 1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 2, 0, 0, 1, 0, 2, 0, 0, 1,
0, 2, 0, 2, 1, 0, 2, 0, 0, 0, 1, 0, 0, 1, 2, 0, 2, 1, 2, 1, 0, 1,
0, 1, 1, 0, 1, 1, 2, 2, 0, 0, 2, 0, 0, 2, 2, 1, 1, 2, 1, 1, 1, 0,
0, 1, 0, 0, 2, 0, 2, 1, 2, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 2,
1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 0, 2, 2, 1, 2, 0, 2, 0, 1, 0, 2,
2, 0, 2, 2, 1, 2, 1, 0, 0, 1, 0, 2, 1, 1, 2, 1, 1, 1, 1, 2, 0, 2,
0, 2, 2, 2, 0, 1, 0, 0, 1, 1, 1, 1, 0, 2, 1, 0, 0, 2, 2, 1, 0, 0,
2, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 2, 0, 1, 2, 1, 0, 0, 2,
0, 2, 2, 2, 1, 1, 0, 0, 0, 2, 0, 1, 0, 2, 1, 0, 2, 0, 0, 2, 1, 0,
0, 2, 2, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2,
0, 1, 0, 2, 0, 1, 2, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 1, 1, 0,
0, 1, 2, 2, 0, 1, 0, 1, 0, 0, 1, 2, 0, 2, 2, 0, 2, 0, 0, 2, 1, 2,
1, 1, 0, 0, 2, 1, 0, 2, 1, 0, 1, 2, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0,
0, 1, 0, 0, 0, 1, 2, 2, 1, 2, 2, 2, 0, 1, 1, 2, 1, 2, 1, 1, 0, 2,
2, 2, 2, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 2, 1,
0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1,
0, 1, 0, 0, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 1, 0, 2, 0, 0, 0, 2,
0, 0, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 2, 2, 2, 2, 1, 2, 1,
0, 1, 2, 0, 1, 0, 1, 0, 0, 0, 2, 0, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0,
0, 0, 1, 0, 1, 0, 1, 1, 1, 2, 0, 1, 2, 1, 0, 1, 0, 0, 1, 2, 0, 0,
0, 1, 1, 0, 0, 0, 0, 0, 2, 1, 0, 1, 2, 0, 0, 0, 2, 0, 0, 2, 0, 0,
0, 0, 0, 0, 2, 1, 0, 1, 0, 1, 0, 2, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2,
0, 0, 0, 2, 1, 0, 0, 2, 0, 0, 0, 0, 1, 2, 2, 0])
"""
# 我们也可以直接使用 fit_predict的方式对x直接训练得到预测的标签
pre = km.fit_predict(x)
pre == y_pred
# 这是一种思想:当我们的数据量非常大的时候,我们可以使用数据中的一小部分进行训练,然后预测所有的值的类别,可以大大的缩减时间
cluster = KMeans(n_clusters=3,random_state=0).fit(x[:200])
pred = cluster.predict(x)
pred
"""
array([0, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 0,
2, 1, 2, 1, 0, 2, 1, 2, 2, 2, 0, 2, 2, 0, 1, 2, 1, 0, 1, 0, 2, 0,
2, 0, 2, 2, 0, 0, 1, 1, 2, 2, 1, 2, 2, 1, 1, 0, 0, 1, 0, 0, 0, 2,
2, 0, 2, 2, 1, 2, 1, 0, 1, 0, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 1, 1,
0, 1, 1, 1, 0, 1, 2, 2, 0, 0, 0, 2, 1, 1, 2, 1, 2, 1, 2, 0, 2, 1,
1, 2, 1, 1, 0, 1, 0, 2, 2, 0, 2, 1, 0, 0, 1, 0, 0, 0, 0, 1, 2, 1,
2, 1, 1, 1, 2, 0, 2, 2, 0, 0, 0, 0, 2, 1, 2, 2, 2, 1, 1, 0, 2, 2,
1, 2, 2, 0, 2, 2, 0, 2, 0, 2, 2, 2, 0, 2, 1, 2, 0, 1, 0, 2, 2, 1,
2, 1, 1, 1, 0, 0, 2, 2, 2, 1, 2, 0, 2, 1, 0, 2, 1, 2, 2, 1, 2, 2,
2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 1, 1,
2, 0, 2, 1, 2, 0, 1, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 0, 2, 2,
2, 0, 1, 1, 2, 0, 2, 0, 2, 2, 0, 1, 2, 1, 1, 2, 1, 2, 2, 1, 0, 1,
0, 0, 2, 2, 1, 0, 2, 1, 0, 2, 0, 1, 2, 2, 2, 0, 0, 2, 0, 2, 0, 2,
2, 0, 2, 2, 2, 0, 1, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1, 0, 0, 2, 1,
1, 1, 1, 2, 0, 2, 1, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 2, 2, 1, 0,
2, 2, 0, 0, 2, 0, 2, 2, 2, 2, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2, 1, 0,
2, 0, 2, 2, 1, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2, 0, 2, 1, 2, 2, 2, 1,
2, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 0, 1, 0,
2, 0, 1, 2, 0, 2, 0, 2, 2, 2, 1, 2, 1, 2, 2, 2, 1, 2, 2, 0, 1, 2,
2, 2, 2, 2, 0, 2, 0, 2, 0, 1, 2, 0, 1, 0, 2, 0, 2, 2, 0, 1, 2, 2,
2, 0, 2, 2, 2, 2, 2, 2, 1, 0, 2, 0, 1, 2, 2, 2, 1, 2, 2, 1, 2, 2,
2, 2, 2, 2, 1, 0, 2, 0, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 1,
2, 2, 2, 1, 0, 2, 2, 1, 2, 2, 2, 2, 0, 1, 1, 2])
"""
- 查看聚类中心
# 属性cluster_centers_ 可以查看聚类的中心
centroid = cluster.cluster_centers_
centroid
"""
array([[ 2.3421645 , 0.6245231 ],
[-1.08228857, 7.74767297],
[-0.25546165, 3.39432391]])
"""
- 查看簇内距离和
# 我们可以通过inertia_来查看簇内的距离和
inertia = cluster.inertia_
inertia
# 561.2329475766046
- 可视化聚类效果
color = ["red","pink","orange","gray"]
fig, ax1 = plt.subplots(1)
for i in range(3):
ax1.scatter(x[y_pred==i, 0], x[y_pred==i, 1],marker='o',s=8,c=color[i])
ax1.scatter(centroid[:,0],centroid[:,1],marker="x",s=15,c="black")
plt.show()
- 分别尝试使用4,5,6作为聚类中心个数
n_clusters = 4
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(x)
inertia_ = cluster_.inertia_
inertia_
# 893.2890226111844
n_clusters = 5
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(x)
inertia_ = cluster_.inertia_
inertia_
# 780.9490175725243
# 我们可以发现我们的聚类中心越多,我们的inertia_的就会越低,但是还是需要以要求的为主
n_clusters = 6
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(x)
inertia_ = cluster_.inertia_
inertia_
# 693.2931571532183
聚类算法的模型评估指标
- 分类
- 直接结果(标签)的输出,并且分类的结果有正误之分,
- 预测的准确度
- 混淆矩阵
- ROC曲线
- 无论如何评估,都是在”模型找到正确答案“的能力。
- 直接结果(标签)的输出,并且分类的结果有正误之分,
- 回归
- 要拟合数据
- SSE均方误差
- 损失函数
- 要拟合数据
但这些衡量指标都不能够使用于聚类
使用Inertia来作为聚类的衡量指标的问题
- 首先,它不是有界的。我们只知道,Inertia是越小越好,是0最好,但我们不知道,一个较小的Inertia究竟有没有达到模型的极限,能否继续提高。
- 第二,它的计算太容易受到特征数目的影响,数据维度很大的时候,Inertia的计算量会陷入维度诅咒之中,计算量会爆炸,不适合用来一次次评估模型。
- 第三,它会受到超参数K的影响,在我们之前的常识中其实我们已经发现,随着K越大,Inertia注定会越来越小,但这并不代表模型的效果越来越好了
- 第四,Inertia对数据的分布有假设,它假设数据满足凸分布(即数据在二维平面图像上看起来是一个凸函数的样子),并且它假设数据是各向同性的(isotropic),即是说数据的属性在不同方向上代表着相同的含义。但是现实中的数据往往不是这样。所以使用Inertia作为评估指标,会让聚类算法在一些细长簇,环形簇,或者不规则形状的流形时表现不佳:
使用指标
当真实标签已知的时候
虽然我们在聚类中不输入真实标签,但这不代表我们拥有的数据中一定不具有真实标签,或者一定没有任何参考信息。当然,在现实中,拥有真实标签的情况非常少见(几乎是不可能的)。如果拥有真实标签,我们更倾向于使用分类算法。但不排除我们依然可能使用聚类算法的可能性。如果我们有样本真实聚类情况的数据,我们可以对于聚类算法的结果和真实结果来衡量聚类的效果。常用的有以下三种方法:
模型评估指标 | 说明 |
---|---|
互信息分 普通互信息分 metrics.adjusted_mutual_info_score (y_pred, y_true) 调整的互信息分 metrics.mutual_info_score (y_pred, y_true) 标准化互信息分 metrics.normalized_mutual_info_score (y_pred, y_true) | 取值范围在(0,1)之中 越接近1,聚类效果越好 在随机均匀聚类下产生0分 |
V-measure:基于条件上分析的一系列直观度量 同质性:是否每个簇仅包含单个类的样本 metrics.homogeneity_score(y_true, y_pred) 完整性:是否给定类的所有样本都被分配给同一个簇中 metrics.completeness_score(y_true, y_pred) 同质性和完整性的调和平均,叫做V-measure metrics.v_measure_score(labels_true, labels_pred) 三者可以被一次性计算出来: metrics.homogeneity_completeness_v_measure(labels_true, labels_pred) | 取值范围在(0,1)之中 越接近1,聚类效果越好 由于分为同质性和完整性两种度量,可以更仔细地研究,模型到底哪个任务 做得不够好 对样本分布没有假设,在任何分布上都可以有不错的表现 在随机均匀聚类下不会产生0分 |
调整兰德系数 metrics.adjusted_rand_score(y_true, y_pred) | 取值在(-1,1)之间,负值象征着簇内的点差异巨大,甚至相互独立,正类的 兰德系数比较优秀,越接近1越好 对样本分布没有假设,在任何分布上都可以有不错的表现,尤其是在具 有"折叠"形状的数据上表现优秀 在随机均匀聚类下产生0分 |
当真实标签未知的时候:
- 轮廓系数 metrics.silhouette_score
- 样本与其自身所在的簇中的其他样本的相似度a,等于样本与同一簇中所有其他点之间的平均距离
- 样本与其他簇中的样本的相似度b,等于样本与下一个最近的簇中的所有点之间的平均距离
- 聚类的要求”簇内差异小,簇外差异大“,我们希望b永远大于a,并且大得越多越好
- 这个公式可以被解析为:
- 理解
- 轮廓系数范围是(-1,1),其中值越接近1表示样本与自己所在的簇中的样本很相似,并且与其他簇中的样本不相似,当样本点与簇外的样本更相似的时候,轮廓系数就为负。当轮廓系数为0时,则代表两个簇中的样本相似度一致,两个簇本应该是一个簇。可以总结为轮廓系数越接近于1越好,负数则表示聚类效果非常差。
- metrics.silhouette_score
- 它返回的是一个数据集中,所有样本的轮廓系数的均值
- metrics.silhouette_sample
- 参数与轮廓系数一致,但返回的是数据集中每个样本自己的轮廓系数
- 优点
- 它在有限空间中取值,使得我们对模型的聚类效果有一个“参考”。
- 轮廓系数对数据的分布没有假设,因此在很多数据集上都表现良好。
- 但它在每个簇的分割比较清洗时表现最好。
- 缺陷
- 它在凸型的类上表现会虚高,比如基于密度进行的聚类,或通过DBSCAN获得的聚类结果,如果使用轮廓系数来衡量,则会表现出比真实聚类效果更高的分数
from sklearn.metrics import silhouette_score
from sklearn.metrics import silhouette_samples
silhouette_score(x,y_pred)
# 0.46541359707472485
silhouette_score(x,cluster_.labels_)
# 0.4066673149238741
silhouette_samples(x,y_pred)
"""
array([ 0.65715038, 0.54746502, 0.3658444 , 0.23386185, -0.00090688,
0.4038489 , 0.22254628, 0.43409563, 0.23373316, 0.73589693,
0.52325438, 0.64252292, 0.05029916, 0.72684332, 0.20830541,
0.08017815, 0.65103435, 0.44883743, 0.66853621, 0.39665298,
0.28152248, 0.65631181, 0.34321719, 0.70281554, 0.38312371,
0.59221403, 0.604633 , 0.54922901, 0.58366506, 0.3618993 ,
0.37589463, 0.36177191, 0.64394625, 0.32092452, 0.5608424 ,
0.5263444 , 0.69312512, 0.30230297, 0.56897043, 0.68037603,
0.63952665, 0.33182144, 0.08847158, 0.62724681, 0.38027281,
0.66963618, 0.22435611, 0.2456607 , 0.58399648, 0.67203834,
0.73775116, 0.7257686 , 0.07330999, 0.19801363, 0.10687663,
0.45479496, 0.34360882, 0.69075127, 0.39807626, 0.6643337 ])
"""
- Calinski-Harabaz Index 卡林斯基-哈拉巴斯指数 CHI,也被称为方差比标准
- Calinski-Harabaz指数越高越好
- 其中N为数据集中的样本量,k为簇的个数(即类别的个数), 是组间离散矩阵,即不同簇之间的协方差矩阵,是簇内离散矩阵,即一个簇内数据的协方差矩阵,而tr表示矩阵的迹。在线性代数中,一个n×n矩阵A的主对角线(从左上方至右下方的对角线)上各个元素的总和被称为矩阵A的迹(或迹数),一般记作。数据之间的离散程度越高,协方差矩阵的迹就会越大。组内离散程度低,协方差的迹就会越小, 也就越小,同时,组间离散程度大,协方差的的迹也会越大, 就越大,这正是我们希望的,因此Calinski-harabaz指数越高越好
- 优点
- 虽然calinski-Harabaz指数没有界,在凸型的数据上的聚类也会表现虚高。但是比起轮廓系数,它有一个巨大的优点,就是计算非常快速
from sklearn.metrics import calinski_harabaz_score
calinski_harabaz_score(x, y_pred)
# 672.6940617157574
# 时间对比
# calinski-harabaz的计算速度比轮廓系数更快
from time import time
t0 = time()
calinski_harabaz_score(x, y_pred)
time() - t0
# 0.0
t0 = time()
silhouette_score(x,y_pred)
time() - t0
# 0.004986763000488281
- 其他
标签未知时的评估指标 戴维斯-布尔丁指数
sklearn.metrics.davies_bouldin_score (X, y_pred)权变矩阵
sklearn.metrics.cluster.contingency_matrix (X, y_pred)
案例:基于轮廓系数来选择n_clusters
绘制轮廓系数分布图和聚类后的数据分布图来选择我们的最佳n_clusters
### 基于轮廓系数来选择n_clusters
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples,silhouette_score
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
n_clusters = 4
fig,(ax1,ax2) = plt.subplots(1,2)
fig.set_size_inches(18,7)
# 在这个地方我们使用xlim设置了x,y的范围
ax1.set_xlim([-0.1,1])
# 在这我们的y的范围是simple的数目加上类别加上1 * 10,这个是为了不同类见显示间隔
ax2.set_ylim([0,x.shape[0] + (n_clusters + 1) * 10])
clusterer = KMeans(n_clusters=n_clusters,random_state=0).fit(x)
cluster_labels = clusterer.labels_
silhouette_avg = silhouette_score(x,cluster_labels)
print("For n_clusters =",n_clusters,"The average silhouette_score is :",silhouette_avg)
sample_silhouette_values = silhouette_samples(x, cluster_labels)
y_lower = 10
for i in range(n_clusters):
# 我们将聚成一类的数据取出来
ith_cluster_silhouette_values = sample_silhouette_values[cluster_labels == i]
# 排序方便观看结果
ith_cluster_silhouette_values.sort()
# 取出此类中的数据的个数,主要为了计算y的位置
size_cluster_i = ith_cluster_silhouette_values.shape[0]
y_upper = y_lower + size_cluster_i
# 这个就是输入一个小数,可以返回一个颜色
color = cm.nipy_spectral(float(i)/n_clusters)
# 填充颜色
ax1.fill_betweenx(np.arange(y_lower, y_upper),ith_cluster_silhouette_values,facecolor=color,alpha=0.7)
ax1.text(-0.05, y_lower + 0.5 * size_cluster_i, str(i))
y_lower = y_upper + 10
ax1.set_title("The silhouette plot for the various clusters.")
ax1.set_xlabel("The silhouette coefficient values")
ax1.set_ylabel("Cluster label")
ax1.axvline(x=silhouette_avg, color="red", linestyle="--")
# 在y轴去掉刻度,在x轴增加刻度
ax1.set_yticks([])
ax1.set_xticks([-0.1, 0, 0.2, 0.4, 0.6, 0.8, 1])
colors = cm.nipy_spectral(cluster_labels.astype(float) / n_clusters)
# 这个地方我们发现都堆在一起了 是因为 我们的y坐标的范围太大了,导致我们的数据变成了直线的点的形式
# 改变y的取值范围即可
ax2.scatter(x[:, 0], x[:, 1],marker='o',s=8,c=colors)
centers = clusterer.cluster_centers_
# Draw white circles at cluster centers
ax2.scatter(centers[:, 0], centers[:, 1], marker='x',c="red", alpha=1, s=200)
ax2.set_title("The visualization of the clustered data.")
ax2.set_xlabel("Feature space for the 1st feature")
ax2.set_ylabel("Feature space for the 2nd feature")
plt.suptitle(("Silhouette analysis for KMeans clustering on sample data ""with n_clusters = %d" % n_clusters),fontsize=14, fontweight='bold')
plt.show()
init & random_state & n_init
是否能够收敛到真正的最小值很大程度上取决于质心的初始化
- init就是用来帮助我们决定初始化方式的参数。
- 可输入"k-means++","random"或者一个n维数组
- 默认"k-means++"。输入"kmeans++":一种为K均值聚类选择初始聚类中心的聪明的办法,以加速收敛
- 输入了n维数组,数组的形状应该是(n_clusters,n_features)并给出初始质心
- random_state参数来控制每次生成的初始质心都在相同位置
- n_init来选择,每个随机数种子下运行的次数,默认10次(并不常用)
plus = KMeans(n_clusters = 10).fit(x)
# 我们可以使用n_iter_来查看实际的迭代次数
plus.n_iter_
# 22
random = KMeans(n_clusters = 10,init="random",random_state=420).fit(x)
random.n_iter_
# 9
max_iter & tol
- max_iter,最大迭代次数
- 我们使用早停可以让我们的模型可能更好
- tol,两次迭代间Inertia下降的量,默认1e-4,如果两次迭代之间Inertia下降的值小于tol所设定的值,迭代就会停下
random = KMeans(n_clusters = 10,init="random",max_iter=10,random_state=420).fit(x)
y_pred_max10 = random.labels_
silhouette_score(x,y_pred_max10)
# 0.3429818620942456
random = KMeans(n_clusters = 10,init="random",max_iter=20,random_state=420).fit(x)
y_pred_max20 = random.labels_
silhouette_score(x,y_pred_max20)
# 0.3429818620942456
重要属性与重要接口
-
重要属性
属性 含义 cluster_centers_ 收敛导质心,如果算法在完全收敛之前就停下了(受到参数max_iter和tol的控制),所返回的内容与labels_属性中反应出来的聚类的结果不一致 labels_ 每个样本点对应的标签 intertia_ 每个样本到距离他们最近的簇心的均方距离,又叫做"簇内平方和" n_iter_ 实际的迭代次数 -
接口
接口 输入 功能&返回 fit 训练特征矩阵x,[训练用标签,sample_weight] 拟合模型,计算K均值的聚类结果 fit_predict 训练特征矩阵x,[训练用标签,sample_weight] 返回每个样本所对应的簇的索引
计算质心并且为每个样本预测所在的簇的索引功能相当于fit_transform 训练特征矩阵x,[训练用标签,sample_weight] 返回新空间中的特征矩阵
进行聚类并且将特征矩阵x转换到彻巨离空间当中,功能相当于先fit再transformget_params 不需要任何输入 获取该类的参数 predict 训练特征矩阵x,[sample_weight] 预测每个测试集x中的样本的所在簇,并返回每个样本所对应的簇的索引
在矢量呈化的相关文献中,cluster_centers_被称为代码簿,predict返回的每个值是代码簿中最接近的代码的索引score 训练特征矩阵x,[训练用标签,sample_weight] 返回聚类后的Inertia,即簇内平方和的负数
簇内平方和是Kmeans常用的模型评价指标簇内平方和越小越好,最佳值为0set_params 需要新设定的参数 为建立好的类重设参数 transform 任意特征矩阵X 将x转换到簇距离空间中
在新空间中,每个维度(即每个坐标轴)是样本点到集群中心的距离。请注意:即使X是稀疏的,变换返回的数组通常也是密集的。
函数cluster.k_means
sklearn.cluster.k_means (X,
n_clusters
, sample_weight=None,init
=’k-means++’, precompute_distances=’auto’,n_init
=10,max_iter
=300, verbose=False,tol
=0.0001,random_state
=None, copy_x=True, n_jobs=None,algorithm=’auto’, return_n_iter=False)
k_means函数可以一次性直接返回[质心,labels,inertial的距离,和最佳的迭代次数]
from sklearn.datasets import make_blobs
x,y = make_blobs(n_samples=500,n_features=2,centers=4,random_state=1)
from sklearn.cluster import k_means
k_means(x,4,return_n_iter=True)
"""
(array([[-1.24428679, 7.86364722],
[ 0.91618785, 4.35308658],
[-1.73282159, 2.79556356],
[ 1.98473613, 0.77127554]]),
array([3, 3, 1, 1, 1, 2, 1, 1, 1, 0, 2, 3, 2, 0, 1, 1, 3, 1, 0, 1, 1, 3,
2, 0, 1, 0, 3, 2, 0, 2, 2, 2, 3, 2, 2, 3, 0, 1, 0, 3, 0, 3, 1, 3,
2, 3, 1, 1, 3, 3, 0, 0, 2, 1, 1, 1, 2, 0, 0, 3, 3, 0, 3, 3, 3, 2,
1, 3, 1, 2, 0, 1, 0, 3, 0, 3, 2, 2, 1, 1, 0, 1, 0, 1, 1, 2, 0, 0,
3, 0, 0, 0, 3, 0, 1, 1, 3, 3, 3, 1, 0, 0, 3, 0, 1, 1, 2, 3, 1, 0,
0, 2, 0, 0, 3, 0, 3, 1, 2, 3, 2, 0, 3, 3, 0, 3, 3, 3, 3, 0, 1, 0,
2, 0, 0, 0, 1, 3, 1, 2, 3, 3, 3, 3, 2, 0, 1, 1, 2, 0, 1, 3, 1, 1,
1, 2, 2, 3, 1, 1, 3, 1, 3, 3, 2, 2, 3, 1, 0, 2, 3, 0, 3, 2, 2, 0,
1, 0, 0, 0, 3, 3, 1, 1, 2, 0, 2, 3, 2, 0, 3, 2, 0, 2, 2, 0, 1, 2,
1, 0, 0, 1, 2, 2, 1, 1, 2, 1, 2, 3, 2, 3, 2, 3, 1, 3, 2, 0, 0, 0,
1, 3, 2, 0, 2, 3, 0, 1, 0, 2, 2, 2, 2, 2, 1, 1, 1, 2, 0, 3, 1, 2,
2, 3, 0, 0, 1, 3, 1, 3, 1, 2, 3, 0, 1, 0, 0, 2, 0, 2, 1, 0, 3, 0,
3, 1, 1, 1, 0, 3, 1, 0, 3, 1, 3, 0, 2, 2, 1, 3, 3, 1, 3, 2, 3, 2,
2, 3, 1, 1, 1, 3, 0, 0, 3, 0, 0, 0, 1, 3, 3, 0, 1, 0, 3, 3, 2, 0,
0, 1, 0, 2, 3, 1, 0, 2, 0, 2, 2, 1, 1, 1, 2, 2, 0, 3, 1, 2, 0, 3,
1, 1, 3, 3, 2, 3, 2, 2, 1, 2, 0, 3, 3, 3, 3, 0, 3, 3, 3, 3, 1, 3,
1, 3, 1, 1, 0, 1, 1, 0, 0, 2, 1, 3, 3, 2, 2, 3, 1, 0, 1, 1, 1, 0,
1, 2, 1, 0, 0, 1, 0, 0, 2, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 3, 0, 3,
1, 3, 0, 1, 3, 1, 3, 1, 2, 2, 0, 2, 0, 2, 3, 3, 0, 2, 1, 3, 0, 2,
2, 1, 1, 1, 3, 2, 3, 1, 3, 0, 2, 3, 0, 3, 1, 3, 1, 2, 3, 0, 1, 1,
2, 3, 3, 1, 1, 2, 1, 2, 0, 3, 2, 3, 0, 2, 2, 2, 0, 2, 1, 0, 2, 2,
2, 2, 2, 1, 0, 3, 2, 3, 1, 2, 2, 0, 1, 0, 2, 0, 1, 1, 1, 2, 2, 0,
2, 2, 2, 0, 3, 2, 2, 0, 2, 2, 2, 1, 3, 0, 0, 1]),
893.2890226111844,
8)
"""