聚类算法K-Means - 参数(二)

972 阅读17分钟

根据菜菜的课程进行整理,方便记忆理解

代码位置如下:

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()

image.png

# 我们对于每一类的数据完成上色
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()

image.png

基于这个分布,我们来使用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()

image.png

  • 分别尝试使用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作为评估指标,会让聚类算法在一些细长簇,环形簇,或者不规则形状的流形时表现不佳:

image.png

使用指标
当真实标签已知的时候

虽然我们在聚类中不输入真实标签,但这不代表我们拥有的数据中一定不具有真实标签,或者一定没有任何参考信息。当然,在现实中,拥有真实标签的情况非常少见(几乎是不可能的)。如果拥有真实标签,我们更倾向于使用分类算法。但不排除我们依然可能使用聚类算法的可能性。如果我们有样本真实聚类情况的数据,我们可以对于聚类算法的结果和真实结果来衡量聚类的效果。常用的有以下三种方法:

模型评估指标说明
互信息分
普通互信息分
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,并且大得越多越好 image.png
    • 这个公式可以被解析为: image.png
    • 理解
    • 轮廓系数范围是(-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指数越高越好 image.png
    • 其中N为数据集中的样本量,k为簇的个数(即类别的个数),BkB_k 是组间离散矩阵,即不同簇之间的协方差矩阵,WkW_k是簇内离散矩阵,即一个簇内数据的协方差矩阵,而tr表示矩阵的迹。在线性代数中,一个n×n矩阵A的主对角线(从左上方至右下方的对角线)上各个元素的总和被称为矩阵A的迹(或迹数),一般记作tr(A)tr(A)数据之间的离散程度越高,协方差矩阵的迹就会越大。组内离散程度低,协方差的迹就会越小, Tr(Wk)Tr(W_k)也就越小,同时,组间离散程度大,协方差的的迹也会越大, Tr(Br)Tr(Br)就越大,这正是我们希望的,因此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()

image.png

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再transform
    get_params不需要任何输入获取该类的参数
    predict训练特征矩阵x,[sample_weight]预测每个测试集x中的样本的所在簇,并返回每个样本所对应的簇的索引
    在矢量呈化的相关文献中,cluster_centers_被称为代码簿,predict返回的每个值是代码簿中最接近的代码的索引
    score训练特征矩阵x,[训练用标签,sample_weight]返回聚类后的Inertia,即簇内平方和的负数
    簇内平方和是Kmeans常用的模型评价指标簇内平方和越小越好,最佳值为0
    set_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)
"""