建议先阅读我之前的博客,掌握一定的机器学习前置知识后再阅读本文,链接如下:
带你从入门到精通——机器学习(一. 机器学习概述)-CSDN博客
带你从入门到精通——机器学习(二. KNN算法)-CSDN博客
带你从入门到精通——机器学习(三. 线性回归)-CSDN博客
带你从入门到精通——机器学习(四. 逻辑回归)-CSDN博客
带你从入门到精通——机器学习(六. 集成学习)-CSDN博客
带你从入门到精通——机器学习(七. 特征降维)-CSDN博客
带你从入门到精通——机器学习(八. 朴素贝叶斯算法)-CSDN博客
目录
九. 聚类算法
9.1 聚类算法的概念
聚类算法是一种无监督学习算法,其目的是在没有先验知识的情况下,自动发现数据集中的内在结构和模式,然后根据样本之间的相似性,将样本划分到不同的类别中,而不同的相似度计算方法(聚类准则),也会得到不同的聚类结果,常用的相似度计算方法有欧式距离法、余弦相似度法等等。
9.2 聚类算法的分类
聚类算法根据聚类颗粒度可以分为以下两类:
粗粒度聚类:这种聚类方法生成的簇较大,包含较多的数据点,适用于需要快速识别大类别的场景,但可能会丢失一些细粒度的信息。
细粒度聚类:这种聚类方法生成的簇较小,包含较少的数据点,适用于需要详细区分数据子类别的场景,但可能会产生过多的簇,增加计算复杂度。
两种聚类方式具体表现形式如下图:
根据实现方法分类:
Kmeans:按照质心分类(质心数即为聚类的簇数),下文会详细介绍K-means,K-means也是一种比较通用、普遍的聚类算法。
层次聚类:分为凝聚层次聚类(Agglomerative Hierarchical Clustering)和分裂层次聚类(Divisive Hierarchical Clustering)两种方法。在凝聚层次聚类中,初始会将每个数据点被视为一个单独的簇,然后逐步将最相似的簇合并,直到所有数据点合并成一个簇或达到预定的簇数;在分裂层次聚类中,初始会将所有数据点被视为一个簇,然后逐步将簇分裂成更小的簇,直到每个数据点成为一个单独的簇或达到预定的簇数。
高斯混合模型聚类(Gaussian Mixture Model,GMM):高斯混合模型是由多个高斯分布混合而成的模型,其数学表达式如下:
高斯混合模型聚类是假设数据的分布是由多个高斯分布的混合而成,并使用期望最大化(Expectation Maximization,EM)算法计算每个点的后验概率,即每个数据点属于每个高斯分布的概率,通常最后会选择后验概率最大的高斯分布作为该数据点的簇标签。
9.2 KMeans算法
KMeans算法的实现流程如下:
1. 事先确定常数K ,常数K意味着最终的聚类类别数(也是质心的个数)。
2. 随机选择K个样本点作为初始聚类中心。
3. 计算每个样本到K个中心的距离,选择距离最近的聚类中心点作为该样本的簇标签。
4. 根据每个簇中的样本点,重新计算出新的聚类中心点(通常是求簇中样本点的平均值),如果计算得出的新中心点与原中心点一样则停止聚类,否则重新进行第3步的过程,直到聚类中心不再变化(即质心不再移动)或达到最大迭代次数。
9.3 聚类的评估指标
9.3.1 误差平方和
误差平方和(The sum of squares due to error,SSE)是衡量聚类效果的一个常用指标,主要考虑了簇内的内聚程度,其数学表达式如下:
其中Ci表示各个簇,k表示聚类中心的个数(簇数),p表示某个簇内的样本,mi表示各个簇的质心点(聚类中心点),SSE计算了每个样本点到质心的欧式距离的平方和,并累加起来,SSE越小,表示数据点越接近它们的中心,聚类效果越好。
9.3.2 肘方法
使用肘方法(Elbow method)可以帮助我们寻找KMeans的最佳K值,具体流程如下:
1. 对于n个点的数据集,取不同的K值(K值的取值范围为1到n)使用KMeans算法进行聚类,并依次计算不同K值下的SSE。
2. 以各个SSE为y轴,对应的K值为x轴绘制一个折线图,随着K值的增大,SSE是会逐渐变小的,而SSE在变化过程中会出现一个拐点,即下降率突然变缓的点,此时对应的K值即可认为是最佳的K值。
示意图如下:
9.3.3 轮廓系数
轮廓系数(Silhouette Coefficient,SC)考虑了簇内的内聚程度(Cohesion)以及簇外的分离程度(Separation)。
SC的值越大,表示聚类效果越好,其计算过程如下
1. 对计算一个样本i到同簇内其他样本的平均距离ai,该值越小,说明簇内的相似程度越大,簇内的内聚程度越大,常用的距离度量方法有欧氏距离、曼哈顿距离等。
2. 计算一个样本i到所以其他簇j内的所有样本的平均距离bij,该值越大,说明该样本越不属于其他簇j,簇外的分离程度越大,最后取bij的最小值作为bi。
3. 根据下面公式计算单个样本i的轮廓系数
4. 计算所有样本的平均轮廓系数,注意:轮廓系数的范围为[-1, 1]。
计算SC的图示如下:
9.3.4 Calinski-Harabasz指数
Calinski-Harabasz指数(Calinski-Harabasz Index),简称CH指数,CH指数考虑了簇内的内聚程度以及簇外的离散程度的同时、还考虑了质心的个数(即簇的个数、聚类的类别个数),使用CH指数评估聚类效果能够到达用尽量少的类别聚类尽量多的样本,同时获得较好的聚类效果。
CH指数的值越大,表示聚类效果越好,其计算方式如下:
上式中m表示样本数量,k表示质心个数。
SSW表示组内平方和(Sum of Squares Within Treatment),相当于SSE,表示了簇内距离,该值越小越好,计算公式如下:
其中xi表示某个样本,Cpi表示样本i所属的质心,SSW值计算了每个样本点到质心的欧式距离的平方和。
SSB表示组间平方和(Sum of Squares Between Groups),表示了簇间距离,该值越大越好,计算公式如下:
其中Cj表示质心,表示数据集的中心点,nj表示属于Cj的样本个数,SSB值计算了各个质心到数据集中心的欧式距离的平方乘以该簇内的样本个数,并累加起来。
由于CH指数的计算公式前有一个系数,在m一定的情况下,k越小,该系数越大,最终的CH指数也就越大,所以聚类的簇数越少越好。
9.4 KMeans算法聚类实例
使用KMeans算法进行聚类的具体实现代码如下:
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
from sklearn.metrics import calinski_harabasz_score, silhouette_score
# 生成1000个二维数据,指定了5个中心点,每个中心点有100个样本,并指定了每个中心点的方差
# x是二维数据,_是标签(聚类算法为无监督学习不使用标签),都为数组类型
x, _ = make_blobs(n_samples=1000, n_features=2,
centers=[[0, 0], [-1, -1], [2, 2], [3, 3], [4, 4]],
cluster_std=[0.2, 0.5, 0.1, 0.3, 0.1],
random_state=66)
# 使用肘方法确定最佳聚类中心个数
sse_list, sc_list, ch_list = [], [], []
for k in range(2, 10):
# 创建KMeans模型
k_means = KMeans(n_clusters=k)
# 训练并进行聚类预测
y_pred = k_means.fit_predict(x) # y_pred为每个样本的聚类类别,类型为数组
print(y_pred, type(y_pred))
sse_list.append(k_means.inertia_) # inertia_属性即为误差平方和(SSE),也就是每个样本点到质心的距离的平方和
sc_list.append(silhouette_score(x, y_pred))
ch_list.append(calinski_harabasz_score(x, y_pred))
# 绘制SSE,SC,CH指数与k值的折线图
# 创建一个大小为20x30的图形对象
fig = plt.figure(figsize=(20, 30))
# 添加第一个子图,用于展示SSE(误差平方和)随k值变化的情况
ax1 = fig.add_subplot(3, 1, 1)
# 绘制SSE变化曲线,x轴为k值范围(2到10),y轴为SSE值列表
ax1.plot(range(2, 10), sse_list)
# 设置子图标题为'SSE'
ax1.set_title('SSE')
# 设置x轴标签为'k'
ax1.set_xlabel = 'k'
# 添加第二个子图,用于展示轮廓系数随k值变化的情况
ax2 = fig.add_subplot(3, 1, 2)
# 绘制轮廓系数变化曲线,x轴为k值范围(2到10),y轴为轮廓系数列表
ax2.plot(range(2, 10), sc_list)
# 设置子图标题为'Silhouette Coefficient'
ax2.set_title('Silhouette Coefficient')
# 设置x轴标签为'k'
ax2.set_xlabel = 'k'
# 添加第三个子图,用于展示Calinski Harabasz指数随k值变化的情况
ax3 = fig.add_subplot(3, 1, 3)
# 绘制Calinski Harabasz指数变化曲线,x轴为k值范围(2到10),y轴为CH指数列表
ax3.plot(range(2, 10), ch_list)
# 设置子图标题为'Calinski Harabasz Index'
ax3.set_title('Calinski Harabasz Index')
# 设置x轴标签为'k'
ax3.set_xlabel = 'k'
# 显示整个图形
plt.show()
# 使用肘方法确定了最佳的K值为5,创建KMeans模型,指定聚类中心个数为5
k_means = KMeans(n_clusters=5)
# 模型训练
k_means.fit(x)
# 模型聚类预测
y_pred = k_means.predict(x)
# 绘制聚类结果
# x[:, 0] 和 x[:, 1] 分别表示数据点的横坐标和纵坐标
# 参数c=y_pred,表示根据 y_pred 的值为每个点分配颜色。
plt.scatter(x[:, 0], x[:, 1], c=y_pred)
plt.show()
# 输出CH指数
print(calinski_harabasz_score(x, y_pred))
标签:入门,样本,KMeans,算法,聚类,SSE,质心
From: https://blog.csdn.net/2401_86480334/article/details/144932894