聚类分析主要算法详解
摘要: 本文全面且深入地阐述了聚类分析中的几种主要算法,包括 K - 均值算法、EM 最大期望算法、DBScan 密度算法、改进 K - 均值算法以及多层次聚类算法。详细介绍了各算法的原理、工作流程、优缺点,并通过实际案例展示其应用过程,同时提供丰富的代码示例以辅助理解。旨在帮助读者深入掌握这些聚类算法,从而能够根据不同的数据特征和应用场景灵活选择合适的算法。
一、引言
聚类分析作为数据挖掘和机器学习领域的关键技术之一,旨在将数据集中具有相似特征的数据对象划分到同一类簇中,使得不同类簇之间的数据对象具有较大差异。这有助于从海量数据中发现内在的数据结构和规律,在众多领域如市场分析、图像识别、生物信息学等有着广泛的应用。以下将详细介绍几种主要的聚类算法。
二、K - 均值算法
(一)算法原理
K - 均值算法基于划分的思想,试图将数据划分为 K 个互不相交的簇,使得每个簇内的数据点到其簇中心的距离之和最小。其具体步骤如下:
- 首先随机初始化 K 个簇中心,这些中心可以是数据集中的 K 个数据点,也可以是随机生成的 K 个向量。
- 对于数据集中的每个数据点,计算它到 K 个簇中心的距离,通常采用欧几里得距离公式d(xi,cj)=∑k=1n(xik−cjk)2d(x_i, c_j)=\sqrt{\sum_{k = 1}^{n}(x_{ik}-c_{jk})^2}d(xi,cj)=∑k=1n(xik−cjk)2(其中xix_ixi是第iii个数据点,cjc_jcj是第jjj个簇中心,nnn是数据的维度),然后将数据点分配到距离最近的簇中心所在的簇。
- 重新计算每个簇的中心,即将簇内所有数据点的坐标值分别求平均,得到新的簇中心。
- 重复步骤 2 和 3,直到簇中心不再发生变化或者达到预设的最大迭代次数。
(二)代码示例
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
# 生成模拟数据
X, y = make_blobs(n_samples=300, centers=4, random_state=42)
# 绘制原始数据
plt.scatter(X[:, 0], X[:, 1])
plt.title("Original Data")
plt.show()
# 使用 K-Means 算法进行聚类
kmeans = KMeans(n_clusters=4, random_state=42)
kmeans.fit(X)
labels = kmeans.labels_
centers = kmeans.cluster_centers_
# 绘制聚类结果
plt.scatter(X[:, 0], X[:, 1], c=labels)
plt.scatter(centers[:, 0], centers[:, 1], marker='*', s=200, c='red')
plt.title("K-Means Clustering Result")
plt.show()
(三)优缺点
- 优点:
- 算法简单直观,易于理解和实现,计算复杂度相对较低,适合大规模数据集的初步聚类分析。
- 当数据具有明显的球形簇结构且簇与簇之间区分度较高时,能够取得较好的聚类效果。
- 缺点:
- 需要事先指定簇的数量 K,而在实际应用中,K 的确定往往比较困难,且不同的 K 值可能导致截然不同的聚类结果。
- 对初始簇中心的选择非常敏感,如果初始中心选择不当,很容易收敛到局部最优解而非全局最优解。
- 只能处理数值型数据,对于分类数据需要进行特殊的编码转换才能处理。
- 无法发现非球形的簇结构,例如具有不同形状、大小和密度的簇。
三、EM 最大期望算法
(一)算法原理
EM 算法常用于含有隐变量的数据聚类问题,它是一种迭代优化算法,通过不断地期望(E 步)和最大化(M 步)来估计模型参数。以高斯混合模型(GMM)为例,其原理如下:
- E 步:根据当前的模型参数(如各高斯分量的均值、协方差和混合系数),计算每个数据点属于每个高斯分量的后验概率(即期望)。计算公式为wij=πjN(xi∣μj,Σj)∑k=1KπkN(xi∣μk,Σk)w_{ij}=\frac{\pi_j\mathcal{N}(x_i|\mu_j,\Sigma_j)}{\sum_{k = 1}^{K}\pi_k\mathcal{N}(x_i|\mu_k,\Sigma_k)}wij=∑k=1KπkN(xi∣μk,Σk)πjN(xi∣μj,Σj)(其中wijw_{ij}wij是数据点xix_ixi属于第jjj个高斯分量的后验概率,πj\pi_jπj是第jjj个高斯分量的混合系数,N(xi∣μj,Σj)\mathcal{N}(x_i|\mu_j,\Sigma_j)N(xi∣μj,Σj)是数据点xix_ixi在第jjj个高斯分布下的概率密度函数)。
- M 步:根据 E 步计算得到的后验概率,重新估计模型参数,包括各高斯分量的均值μj=∑i=1nwijxi∑i=1nwij\mu_j=\frac{\sum_{i = 1}^{n}w_{ij}x_i}{\sum_{i = 1}^{n}w_{ij}}μj=∑i=1nwij∑i=1nwijxi、协方差Σj=∑i=1nwij(xi−μj)(xi−μj)T∑i=1nwij\Sigma_j=\frac{\sum_{i = 1}^{n}w_{ij}(x_i-\mu_j)(x_i-\mu_j)^T}{\sum_{i = 1}^{n}w_{ij}}Σj=∑i=1nwij∑i=1nwij(xi−μj)(xi−μj)T和混合系数πj=∑i=1nwijn\pi_j=\frac{\sum_{i = 1}^{n}w_{ij}}{n}πj=n∑i=1nwij。
- 重复 E 步和 M 步,直到模型参数收敛,即相邻两次迭代中参数的变化小于预设的阈值。
(二)代码示例
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.mixture import GaussianMixture
# 生成模拟数据
X, y = make_blobs(n_samples=300, centers=4, random_state=42)
# 绘制原始数据
plt.scatter(X[:, 0], X[:, 1])
plt.title("Original Data")
plt.show()
# 使用 EM 算法(通过 GaussianMixture 实现)进行聚类
gmm = GaussianMixture(n_components=4, random_state=42)
gmm.fit(X)
labels = gmm.predict(X)
means = gmm.means_
# 绘制聚类结果
plt.scatter(X[:, 0], X[:, 1], c=labels)
plt.scatter(means[:, 0], means[:, 1], marker='*', s=200, c='red')
plt.title("EM Clustering Result")
plt.show()
(三)优缺点
- 优点:
- 能够处理具有复杂分布的数据,尤其是当数据可以用多个高斯分布混合来建模时,效果较好。
- 相比于 K - 均值算法,不需要事先确定簇的形状为球形,对数据的适应性更强。
- 缺点:
- 计算复杂度较高,尤其是在处理大规模数据集或高维数据时,计算量会显著增加。
- 对初始参数的设置比较敏感,如果初始参数设置不合理,可能会收敛到局部最优解。
- 模型的解释性相对较弱,因为涉及到多个高斯分量的参数估计,理解起来较为复杂。
四、DBScan 密度算法
(一)算法原理
DBScan 算法基于密度的概念来发现数据集中的簇,它将数据点分为核心点、边界点和噪声点。核心点是在其邻域内(半径为ϵ\epsilonϵ的邻域)包含至少 MinPts 个数据点的点;边界点是在某个核心点邻域内但自身邻域内数据点数量不足 MinPts 的点;噪声点是既不是核心点也不是边界点的点。算法步骤如下:
- 从数据集中任选一个未被访问的数据点。
- 如果该点是核心点,则创建一个新的簇,并将其邻域内的所有点(包括核心点和边界点)都加入到该簇中,然后递归地处理这些新加入点的邻域,不断扩展簇。
- 如果该点是边界点,则将其标记为噪声点或者分配到某个已有的簇中,具体取决于其与已发现簇的关系。
- 重复步骤 1 到 3,直到所有数据点都被访问过。
(二)代码示例
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.cluster import DBSCAN
# 生成模拟数据
X, y = make_moons(n_samples=300, noise=0.05, random_state=42)
# 绘制原始数据
plt.scatter(X[:, 0], X[:, 1])
plt.title("Original Data")
plt.show()
# 使用 DBSCAN 算法进行聚类
dbscan = DBSCAN(eps=0.3, min_samples=5)
labels = dbscan.fit_predict(X)
# 绘制聚类结果
plt.scatter(X[:, 0], X[:, 1], c=labels)
plt.title("DBSCAN Clustering Result")
plt.show()
(三)优缺点
- 优点:
- 不需要事先指定簇的数量,能够自动发现数据集中的簇结构,并且可以识别出数据中的噪声点,对噪声具有较好的鲁棒性。
- 能够处理任意形状的簇,包括非球形、凹形等复杂形状的簇,对于数据分布不均匀的情况也有一定的适应性。
- 缺点:
- 对参数ϵ\epsilonϵ(邻域半径)和 MinPts(最小点数)非常敏感,不同的参数设置可能会导致完全不同的聚类结果,而且这两个参数的选择往往比较困难,需要对数据有一定的先验了解。
- 在数据密度差异较大的情况下,可能会将一个大的密度不均匀的簇划分成多个小簇,或者将多个密度相近但实际应分开的簇合并在一起。
五、改进 K - 均值算法
(一)算法原理
改进 K - 均值算法是针对传统 K - 均值算法的一些缺陷进行优化的算法,常见的改进策略有多种,例如:
- K - 均值++算法:在初始化簇中心时,不再是随机选择,而是首先随机选择一个数据点作为第一个簇中心,然后对于每个数据点,计算它到已选簇中心的最短距离D(x)D(x)D(x),并以概率P(x)=D(x)2∑i=1nD(xi)2P(x)=\frac{D(x)^2}{\sum_{i = 1}^{n}D(x_i)^2}P(x)=∑i=1nD(xi)2D(x)2选择下一个簇中心。这样可以使得初始簇中心的分布更加合理,减少收敛到局部最优解的可能性。
- 二分 K - 均值算法:首先将所有数据点作为一个簇,然后不断地将簇进行二分,选择使得划分后 SSE(误差平方和,即每个数据点到其所属簇中心的距离平方和)增加最小的簇进行划分,直到达到预设的簇数量 K。这种方法可以在一定程度上避免传统 K - 均值算法对初始值敏感的问题,并且能够得到相对较好的聚类结果。
(二)代码示例(以 K - 均值++为例)
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
# 生成模拟数据
X, y = make_blobs(n_samples=300, centers=4, random_state=42)
# 绘制原始数据
plt.scatter(X[:, 0], X[:, 1])
plt.title("Original Data")
plt.show()
# 使用 K-Means++算法进行聚类
kmeans_pp = KMeans(n_clusters=4, init='k-means++', random_state=42)
kmeans_pp.fit(X)
labels_pp = kmeans_pp.labels_
centers_pp = kmeans_pp.cluster_centers_
# 绘制聚类结果
plt.scatter(X[:, 0], X[:, 1], c=labels_pp)
plt.scatter(centers_pp[:, 0], centers_pp[:, 1], marker='*', s=200, c='red')
plt.title("K-Means++ Clustering Result")
plt.show()
(三)优缺点
- 优点:
- 相比传统 K - 均值算法,K - 均值++算法在初始化方面有很大改进,能够提高找到全局最优解的概率,从而得到更准确的聚类结果。
- 二分 K - 均值算法在处理簇数量的确定和初始值敏感问题上有一定优势,聚类结果相对稳定且质量较高。
- 缺点:
- 虽然在一定程度上改善了传统 K - 均值算法的问题,但仍然不能完全克服 K - 均值算法的固有缺陷,例如对于非球形簇结构的处理能力有限。
- 改进算法在计算复杂度上可能会略有增加,尤其是二分 K - 均值算法,因为需要不断地进行簇的划分和评估。
六、多层次聚类
(一)算法原理
多层次聚类算法构建了一个聚类的层次结构,主要有凝聚式和分裂式两种方法。
- 凝聚式层次聚类:从每个数据点作为一个单独的簇开始,然后不断合并最相似的簇。相似性度量可以采用多种方法,如单链法(两个簇之间的距离定义为两个簇中最近的两个数据点之间的距离)、全链法(两个簇之间的距离定义为两个簇中最远的两个数据点之间的距离)、平均链法(两个簇之间的距离定义为两个簇中所有数据点对之间距离的平均值)等。在每一步合并中,选择距离最近(根据所选相似性度量)的两个簇进行合并,直到所有数据点都合并到一个簇中或者达到预设的停止条件,如簇的数量达到期望的值。
- 分裂式层次聚类:与凝聚式相反,它从所有数据点都在一个簇开始,不断分裂簇。首先选择一个簇,然后根据某种分裂准则将其分裂成两个子簇,重复这个过程,直到每个数据点都成为一个单独的簇或者满足停止条件。
(二)代码示例(以凝聚式层次聚类为例)
import numpy as np
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import dendrogram, linkage
from sklearn.datasets import make_blobs
# 生成模拟数据
X, y = make_blobs(n_samples=300, centers=4, random_state=42)
# 计算层次聚类的连接矩阵(采用平均链法)
Z = linkage(X, method='average')
# 绘制层次聚类的树状图
plt.figure(figsize=(10, 5))
dendrogram(Z)
plt.title("Hierarchical Clustering Dendrogram")
plt.show()
# 根据树状图确定簇的数量并提取簇标签
from scipy.cluster.hierarchy import fcluster
k = 4 # 根据树状图确定的簇数量
labels = fcluster(Z, k, criterion='maxclust')
# 绘制聚类结果
plt.scatter(X[:, 0], X[:, 1], c=labels)
plt.title("Hierarchical Clustering Result")
plt.show()
(三)优缺点
- 优点:
- 不需要事先指定簇的数量,聚类结果以树状图的形式呈现,能够清晰地展示数据的层次结构,用户可以根据实际需求在不同的层次上选择合适的簇数量。
- 能够处理不同形状、大小和密度的簇结构,相对较为灵活,对于数据分布复杂的情况有较好的适应性。
- 缺点:
- 计算复杂度较高,尤其是对于大规模数据集,因为需要计算所有数据点对之间的相似性,计算量会随着数据点数量的增加而急剧增加。
- 一旦一个合并或者分裂被执行,就不能再撤销,可能会导致聚类结果不好,如果在早期阶段出现错误的合并或分裂,会影响整个聚类的质量。
七、算法比较与总结
- K - 均值算法:适用于数据分布较为均匀、呈球形或近似球形的情况,计算速度快,但需事先确定 K,对初始值敏感且无法处理非球形簇。
- EM 最大期望算法:能处理复杂分布数据,不限于球形簇,但计算复杂,对初始参数敏感且模型解释性弱。
- DBScan 密度算法:自动确定簇数量和形状,可识别噪声,能处理任意形状簇,但对参数敏感,在密度差异大的数据上有局限。
- 改进 K - 均值算法:改善了传统 K - 均值算法的部分问题,如初始化或簇数量确定,但仍有 K - 均值算法的固有缺陷且计算复杂度可能增加。
- 多层次聚类:无需事先指定簇数量,展示层次结构,可处理各种形状簇,但计算复杂且聚类结果不可撤销。
在实际应用中,需要综合考虑数据的特点、应用场景以及对聚类结果的要求来选择合适的聚类算法。如果数据规模大且近似球形分布,K - 均值或其改进算法可能较为合适;如果数据分布复杂且形状不规则,DBScan 或多层次聚类算法可能更能满足需求;如果数据可由多个高斯分布混合建模,EM 最大期望算法则可作为一种选择。
1124

被折叠的 条评论
为什么被折叠?



