聚类算法K-Means

聚类算法K-Means
1 概述
1.1 无监督学习与聚类算法
在过去的五周之内,我们学习了决策树,随机森林,PCA和逻辑回归,他们虽然有着不同的功能,但却都属于“有监 督学习”的一部分,即是说,模型在训练的时候,即需要特征矩阵X,也需要真实标签y。机器学习当中,还有相当 一部分算法属于“无监督学习”,无监督的算法在训练的时候只需要特征矩阵X,不需要标签。而聚类算法,就是无监督学习的代表算法。
聚类算法又叫做“无监督分类”,其目的是将数据划分成有意义或有用的组(或簇)。这种划分可以基于我们的业务 需求或建模需求来完成,也可以单纯地帮助我们探索数据的自然结构和分布。比如在商业中,如果我们手头有大量的当前和潜在客户的信息,我们可以使用聚类将客户划分为若干组,以便进一步分析和开展营销活动,最有名的客户价值判断模型RFM,就常常和聚类分析共同使用。再比如,聚类可以用于降维和矢量量化(vector quantization),可以将高维特征压缩到一列当中,常常用于图像,声音,视频等非结构化数据,可以大幅度压缩 数据量。
在这里插入图片描述
1.2 sklearn中的聚类算法
聚类算法在sklearn中有两种表现形式,一种是类(和我们目前为止学过的分类算法以及数据预处理方法们都一 样),需要实例化,训练并使用接口和属性来调用结果。另一种是函数(function),只需要输入特征矩阵和超参 数,即可返回聚类的结果和各种指标。
在这里插入图片描述
2 KMeans
2.1 KMeans是如何工作的
在这里插入图片描述
在KMeans算法中,簇的个数K是一个超参数,需要我们人为输入来确定。KMeans的核心任务就是根据我们设定好的K,找出K个最优的质心,并将离这些质心最近的数据分别分配到这些质心代表的簇中去。具体过程可以总结如下:
在这里插入图片描述
那什么情况下,质心的位置会不再变化呢?
当我们找到一个质心,在每次迭代中被分配到这个质心上的样本都是一致的,即每次新生成的簇都是一致的,所有的样本点都不会再从一个簇转移到另一个簇,质心就不会变化了。
聚类就完成了,我们可以明显看出,KMeans按照数据的分布,接下来我们就可以按照我们的业务需求或者算法需求,对这四类数据进行不同的处理。

3 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’)

3.1 重要参数n_clusters
n_clusters是KMeans中的k,表示着我们告诉模型我们要分几类。这是KMeans当中唯一一个必填的参数,默认为8 类,但通常我们的聚类结果会是一个小于8的结果。

3.1.2 聚类算法的模型评估指标
不同于分类模型和回归,聚类算法的模型评估不是一件简单的事。在分类中,有直接结果(标签)的输出,并且分 类的结果有正误之分,所以我们使用预测的准确度,混淆矩阵,ROC曲线等等指标来进行评估,但无论如何评估, 都是在”模型找到正确答案“的能力。而回归中,由于要拟合数据,我们有SSE均方误差,有损失函数来衡量模型的 拟合程度。但这些衡量指标都不能够使用于聚类。
面试高危问题:如何衡量聚类算法的效果?
聚类模型的结果不是某种标签输出,并且聚类的结果是不确定的,其优劣由业务需求或者算法需求来决定,并且没有永远的正确答案。那我们如何衡量聚类的效果呢?

记得我们说过,KMeans的目标是确保“簇内差异小,簇外差异大”,我们就可以通过衡量簇内差异来衡量聚类的效 果。我们刚才说过,Inertia是用距离来衡量簇内差异的指标,因此,我们是否可以使用Inertia来作为聚类的衡量指 标呢?Inertia越小模型越好嘛。
可以,但是这个指标的缺点和极限太大。
在这里插入图片描述

from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

X,y=make_blobs(n_samples=500,centers=4,n_features=2,random_state=1)
cluster=KMeans(n_clusters=3,random_state=0).fit(X)
y_pred=cluster.labels_
pre=cluster.fit_predict(X)

centroid=cluster.cluster_centers_
print('centroid',centroid)
print(centroid.shape)
inertia=cluster.inertia_
print('interia0:',inertia)

color=['red','blue','green','purple']
fig,ax1=plt.subplots(1)
#为y中的0,1,2,3上不同的颜色
for i in range(4):
    ax1.scatter(X[y_pred==i,0],X[y_pred==i,1],
                marker='o',
                s=8,#控制点的大小
                color=color[i],
    )
ax1.scatter(centroid[:,0],centroid[:,1],
            marker='x',
            s=15,
            color='black')
plt.show()


cluster=KMeans(n_clusters=4,random_state=0).fit(X)
inertia1=cluster.inertia_
print('interia2:',inertia1)
centroid [[-7.09306648 -8.10994454]
 [-1.54234022  4.43517599]
 [-8.0862351  -3.5179868 ]]
(3, 2)
interia0: 1903.4503741659223
interia2: 908.3855684760613

那我们可以使用什么指标呢?来使用轮廓系数。

在99%的情况下,我们是对没有真实标签的数据进行探索,也就是对不知道真正答案的数据进行聚类。这样的聚 类,是完全依赖于评价簇内的稠密程度(簇内差异小)和簇间的离散程度(簇外差异大)来评估聚类的效果。其中 轮廓系数是最常用的聚类算法的评价指标。它是对每个样本来定义的,它能够同时衡量:
1)样本与其自身所在的簇中的其他样本的相似度a,等于样本与同一簇中所有其他点之间的平均距离
2)样本与其他簇中的样本的相似度b,等于样本与下一个最近的簇中得所有点之间的平均距离 根据聚类的要求”簇内差异小,簇外差异大“,我们希望b永远大于a,并且大得越多越好。 单个样本的轮廓系数计算为:
在这里插入图片描述
这个公式可以被解析为:
在这里插入图片描述
很容易理解轮廓系数范围是(-1,1),其中值越接近1表示样本与自己所在的簇中的样本很相似,并且与其他簇中的样本不相似,当样本点与簇外的样本更相似的时候,轮廓系数就为负。当轮廓系数为0时,则代表两个簇中的样本相 似度一致,两个簇本应该是一个簇。
如果一个簇中的大多数样本具有比较高的轮廓系数,则簇会有较高的总轮廓系数,则整个数据集的平均轮廓系数越 高,则聚类是合适的。如果许多样本点具有低轮廓系数甚至负值,则聚类是不合适的,聚类的超参数K可能设定得太大或者太小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值