层次聚类 簇数_聚类(一):K-means、层次、DBSCAN、均值漂移、K-Means 与 KNN

本文深入探讨了几种常见的聚类算法,包括K-means的基本原理、K值的确定方法(如肘部法则)、成本函数(SSE)及其应用。此外,还介绍了层次聚类的简单过程,DBSCAN基于密度的聚类算法特点,以及均值漂移聚类的工作机制。文章通过代码示例展示了K-means的实现过程,并对比了K-means与KNN的区别,同时总结了K-means的优点和缺点。
摘要由CSDN通过智能技术生成

文章目录

一、K-means简介

1.1 K-means简介

1.1.1 K值的确定

1.1.2 K-means 成本函数(利用SSE选择k)

1.2 层次聚类

1.3 DBSCAN - 基于密度的聚类算法

1.3.1 简介

1.3.2 具体步骤

1.4 均值漂移聚类

1.4.1 简介

1.4.2 步骤

二、代码

2.1 原理推导

2.2 make_blobs

三、总结

3.1 K-Means 与 KNN

3.2 K-Means的主要优点有

3.3 K-Means的主要缺点有

424d3eb13cc0c971ff8e7779777f593b.png

一、K-means简介

1.1 K-means简介

K-means是无监督的聚类算法。其主要思想是选择K个点作为初始聚类中心, 将每个对象分配到最近的中心形成K个簇,重新计算每个簇的中心,重复以上迭代步骤,直到簇不再变化或达到指定迭代次数为止。,让簇内的点尽量紧密的连接在一起,而让簇间的距离尽量的大。

K-means每次计算质心,第一次是随机产生质心,第二次开始,是根据第一次分类后,每类的平均值作为质心,所以叫K-means聚类。

K-means如果簇中存在异常点,将导致均值偏差比较严重。例如:

一个簇中有2、4、6、8、100五个数据,那么新的质点为24,显然这个质点离绝大多数点都比较远;在当前情况下,使用中位数6可能比使用均值的想法更好,使用中位数的聚类方式叫做K- Mediods聚类(K中值聚类)。

1.1.1 K值的确定

在实际的应用中,主要两种方法进行K值的确定:

经验法:在实际的工作中,可以结合业务的场景和需求,来决定分几类以确定K值。

肘部法则:在使用聚类算法时,如果没有指定聚类的数量,即K值,则可以通过肘部法则来进行对K值得确定。肘部法则是通过成本函数来刻画的,其是通过将不同K值的成本函数刻画出来,随着K值的增大,平均畸变程度会不断减小且每个类包含的样本数会减少,于是样本离其重心会更近。但是,随着值继续增大,平均畸变程度的改善效果会不断减低。因此找出在K值增大的过程中,畸变程度下降幅度最大的位置所对应的K较为合理。

1.1.2 K-means 成本函数(利用SSE选择k)

k-means是以最小化样本与质点平方误差作为目标函数,将每个簇的质点与簇内样本点的平方距离误差和称为畸变程度(distortions),那么,对于一个簇,它的畸变程度越低,代表簇内成员越紧密,畸变程度越高,代表簇内结构越松散。 畸变程度会随着类别的增加而降低,但对于有一定区分度的数据,在达到某个临界点时畸变程度会得到极大改善,之后缓慢下降,这个临界点就可以考虑为聚类性能较好的点。

指定一个i值,即可能的最大类簇数。然后将类簇数从1开始递增,一直到i,计算出i个簇内误方差(SSE)。根据数据的潜在模式,当设定的类簇数不断逼近真实类簇数时,SSE呈现快速下降态势,而当设定类簇数超过真实类簇数时,SSE也会继续下降,当下降会迅速趋于缓慢。通过画出K-SSE曲线,找出下降途中的拐点,即可较好的确定K值。

b14a1030e4263c444489d87850f2e351.png

从图中可以看出,k值从1到2时,平均畸变程度变化最大。超过2以后,平均畸变程度变化显著降低。因此最佳的k是2。

1.2 层次聚类

尽管k-means的原理很简单,然而层次聚类法的原理更简单。它的基本过程如下:

每一个样本点视为一个簇;

计算各个簇之间的距离,最近的两个簇聚合成一个新簇;

重复以上过程直至最后只有一簇。

层次聚类不指定具体的簇数,而只关注簇之间的远近,最终会形成一个树形图。

1.3 DBSCAN - 基于密度的聚类算法

1.3.1 简介

DBSCAN(Density-Based Spatial Clustering of Application with Noise) - 基于密度的聚类算法.

基于密度的聚类方法与其他方法的一个根本区别是:它不是基于各种各样的距离度量的,而是基于密度的。因此它能克服基于距离的算法只能发现“类圆形”的聚类的缺点。

DBSCAN的指导思想是:用一个点的∈邻域内的邻居点数衡量该点所在空间的密度,只要一个区域中的点的密度大过某个阈值,就把它加到与之相近的聚类中去

e79e21fe414f0c16c2ccc803cf191992.png

1.3.2 具体步骤

与均值漂移聚类类似,DBSCAN也是基于密度的聚类算法。

具体步骤:

首先确定半径r和minPoints. 从一个没有被访问过的任意数据点开始,以这个点为中心,r为半径的圆内包含的点的数量是否大于或等于minPoints,如果大于或等于minPoints则改点被标记为central point,反之则会被标记为noise point。

重复1的步骤,如果一个noise point存在于某个central point为半径的圆内,则这个点被标记为边缘点,反之仍为noise point。重复步骤1,知道所有的点都被访问过。

优点:不需要知道簇的数量

缺点:需要确定距离r和minPoints

1.4 均值漂移聚类

1.4.1 简介

均值漂移聚类是基于滑动窗口的算法,来找到数据点的密集区域。这是一个基于质心的算法,通过将中心点的候选点更新为滑动窗口内点的均值来完成,来定位每个组/类的中心点。然后对这些候选窗口进行相似窗口进行去除,最终形成中心点集及相应的分组。

1.4.2 步骤

具体步骤:

确定滑动窗口半径r,以随机选取的中心点C半径为r的圆形滑动窗口开始滑动。均值漂移类似一种爬山算法,在每一次迭代中向密度更高的区域移动,直到收敛。

每一次滑动到新的区域,计算滑动窗口内的均值来作为中心点,滑动窗口内的点的数量为窗口内的密度。在每一次移动中,窗口会想密度更高的区域移动。

移动窗口,计算窗口内的中心点以及窗口内的密度,知道没有方向在窗口内可以容纳更多的点,即一直移动到圆内密度不再增加为止。

步骤一到三会产生很多个滑动窗口,当多个滑动窗口重叠时,保留包含最多点的窗口,然后根据数据点所在的滑动窗口进行聚类。

二、代码

2.1 原理推导

from scipy.io import loadmatimport pandas as pdimport seaborn as sbimport matplotlib.pyplot as pltimport numpy as np'''''K-means是一个迭代的,无监督的聚类算法,将类似的实例组合成簇。 该算法通过猜测每个簇的初始聚类中心开始,然后重复将实例分配给最近的簇,并重新计算该簇的聚类中心。'''def find_closest_centroids(X, centroids): # 初始质心centroids m = X.shape[0] # m是样本数 k = centroids.shape[0] idx = np.zeros(m) for i in range(m): min_dist = 1000000 # 初始距离 样本与质心 for j in range(k): # k是聚类中心数 dist = np.sum((X[i, :] - centroids[j, :]) ** 2) print('dist', dist) # 300个样本,输出900个dist(计算每个样本到质心的距离) if dist < min_dist: min_dist = dist idx[i] = j return idxdata = loadmat('./data/ex7data2.mat')print('data.keys()', data.keys())# data.keys() dict_keys(['__header__', '__version__', '__globals__', 'X'])X = data['X']print('X.shape', X.shape) # X.shape (300, 2)initial_centroids = np.array([[3, 3], [6, 2], [8, 5]])idx = find_closest_centroids(X, initial_centroids)print('idx.shape', idx.shape) # idx.shape (300,),即预测的结果print('idx[0:3]', idx[0:3]) # idx[0:3] [0. 2. 1.]# 输出与文本中的预期值匹配(记住我们的数组是从0开始索引的,而不是从1开始索引的,#接下来,我们需要一个函数来计算簇的聚类中心。 聚类中心只是当前分配给簇的所有样本的平均值。data2 = pd.DataFrame(data.get('X'), columns=['X1', 'X2'])print('data2.head()',data2.head())sb.set(context='notebook', style='white')sb.lmplot('X1', 'X2', data=data2, fit_reg=False)#lmplot是用来绘制回归图的plt.show()
1cb713bc5aa284a7668fe0a8376e6b27.png
def compute_centroids(X, idx, k):#计算质心 m, n = X.shape centroids = np.zeros((k, n)) for i in range(k): indices = np.where(idx == i) centroids[i, :] = (np.sum(X[indices, :], axis=1) / len(indices[0])).ravel() return centroidscompute_centroids(X, idx, 3)'''array([[2.42830111, 3.15792418], [5.81350331, 2.63365645], [7.11938687, 3.6166844 ]])'''def run_k_means(X, initial_centroids, max_iters): m, n = X.shape k = initial_centroids.shape[0] idx = np.zeros(m) centroids = initial_centroids for i in range(max_iters): idx = find_closest_centroids(X, centroids) centroids = compute_centroids(X, idx, k) return idx, centroidsidx, centroids = run_k_means(X, initial_centroids, 10)cluster1 = X[np.where(idx == 0)[0],:]cluster2 = X[np.where(idx == 1)[0],:]cluster3 = X[np.where(idx == 2)[0],:]fig, ax = plt.subplots(figsize=(12,8))ax.scatter(cluster1[:,0], cluster1[:,1], s=30, color='r', label='Cluster 1')ax.scatter(cluster2[:,0], cluster2[:,1], s=30, color='g', label='Cluster 2')ax.scatter(cluster3[:,0], cluster3[:,1], s=30, color='b', label='Cluster 3')ax.legend()plt.show()
a8eabdb3686fdc30e29b110f6cdce312.png

2.2 make_blobs

# 数据构建。:创建的团状的数据集合,数据分布呈高斯分布状况。from sklearn.datasets import make_blobsN = 1000centers = 4X, Y = make_blobs(n_samples=N, n_features=2, centers=centers, random_state=0)# 模型构建:导入K-Means算法包,其底层就是按照前面讲的算法步骤一步一步创建的from sklearn.cluster import KMeans# 给出要划分的中心点树k,也可以给出算法中止条件,迭代次数,或者簇中心变化率。km = KMeans(n_clusters=centers, init='random', random_state=28)km.fit(X)# 模型的预测y_hat = km.predict(X)# 求出模型的中心点坐标,并且得到,样本到中心点的总距离,也就是前面提到的损失函数。print("所有样本距离所属簇中心点的总距离和为:%.5f" % km.inertia_)print("所有的中心点聚类中心坐标:")cluter_centers = km.cluster_centers_print(cluter_centers)print("score其实就是所有样本点离所属簇中心点距离和的相反数:")print(km.score(X))'''运行结果所有样本距离所属簇中心点的总距离和为:1734.01601所有的中心点聚类中心坐标:[[ 1.99871335 0.79038817] [-1.31360134 7.86561393] [-1.51473374 2.8755229 ] [ 0.97790397 4.28661633]]score其实就是所有样本点离所属簇中心点距离和的相反数:-1734.0160089537276'''# 画图,把原始数据和最终预测数据在图上表现出来import matplotlib.pyplot as pltimport matplotlib as mplcm = mpl.colors.ListedColormap(list('rgby'))plt.figure(figsize=(15, 9), facecolor='w')plt.subplot(121)plt.title(u'原始数据')plt.grid(True)plt.scatter(X[:, 0], X[:, 1], c=Y, s=30, cmap=cm, edgecolors='none')plt.subplot(122)plt.scatter(X[:, 0], X[:, 1], c=y_hat, s=30, cmap=cm, edgecolors='none')plt.title(u'K-Means算法聚类结果')plt.grid(True)plt.show()
c07b9bb7c325f6f11d0304bbf931ccf0.png

三、总结

3.1 K-Means 与 KNN

K-Means是无监督学习的聚类算法,没有样本输出;而KNN是监督学习的分类算法,有对应的类别输出。KNN基本不需要训练,对测试集里面的点,只需要找到在训练集中最近的k个点,用这最近的k个点的类别来决定测试点的类别。而K-Means则有明显的训练过程,找到k个类别的最佳质心,从而决定样本的簇类别。

当然,两者也有一些相似点,两个算法都包含一个过程,即找出和某一个点最近的点。两者都利用了最近邻(nearest neighbors)的思想。

3.2 K-Means的主要优点有

1)原理比较简单,实现也是很容易,收敛速度快。

2)聚类效果较优。

3)算法的可解释度比较强。

4)主要需要调参的参数仅仅是簇数k。

3.3 K-Means的主要缺点有

1)K值的选取不好把握

2)对于不是凸的数据集比较难收敛

3)如果各隐含类别的数据不平衡,比如各隐含类别的数据量严重失衡,或者各隐含类别的方差不同,则聚类效果不佳。

4) 采用迭代方法,得到的结果只是局部最优。

5) 对噪音和异常点比较的敏感。

6)每一次迭代都要重新计算各个点与质心的距离,然后排序,时间成本较高。

私信我:“学习”,可免费领取更多相关学习资料 (免费的哦)。

24b365df0910f4a8b3c56429d1c3dddf.png
929aabf4130b8aa9cfdb6e8feba23187.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值