Python 在科研中的应用 12:聚类分析
今天总结了最常见的五种聚类算法。涉及到的算法有:
- K均值聚类(K-Means Clustering)
- 层次聚类(Hierarchical Clustering)
- DBSCAN(Density-Based Spatial Clustering of Applications with Noise)
- 高斯混合模型(Gaussian Mixture Model,GMM)
- 谱聚类(Spectral Clustering)
课程作业03 占总成绩25%
构建四组二维空间中的随机分布散点,每组散点符合二维高斯分布,高斯分布的中心点与两个方向的标准差均随机产生,且二维高斯分布的中心点落在[[0,100],[0,100]]的方形区域内。
通过K均值聚类分析方法对上述随机散点执行聚类分析,绘制分类结果,并计算K-means聚类分析的准确率。
K均值聚类(K-Means Clustering)
K均值聚类(K-Means Clustering)是一种常用的无监督学习算法,用于将数据集分成K个簇(clusters)。其目标是将相似的数据点归为同一簇,而将不同的数据点分到不同的簇中,从而使得每个簇内的数据点之间的相似度最大,而不同簇之间的相似度最小。
核心原理
K均值聚类的核心思想是通过迭代优化的方法,最小化簇内点到簇中心的总距离平方和。
基本步骤如下:
初始化:随机选择K个点作为初始簇中心。
分配簇:将每个数据点分配到最近的簇中心。
更新簇中心:重新计算每个簇的中心(即簇内所有点的平均值)。
重复:重复步骤2和3,直到簇中心不再发生显著变化或达到预定的迭代次数。
核心公式
假设数据集为$x_1,x_2,…,x_n$,每个数据点$x_i$有$d$维。簇的中心为$\mu_1,\mu_2,…,\mu_K$。
距离计算:通常使用欧氏距离:
\begin{equation}
{\bf dist}(x_i,\mu_k) = \Arrowvert x_i-\mu_k\Arrowvert_2 = \sqrt{\sum^d_{j=1} (x_{ij}-\mu_{kj})^2}
\end{equation}簇分配:将每个点分配到最近的簇中心:
\begin{equation}
C_k = {x_i:\Arrowvert x_i-\mu_k \Arrowvert_2 \leq \Arrowvert x_i - \mu_j\Arrowvert_2, \forall j,1 \leq j \leq K }
\end{equation}更新簇中心:重新计算每个簇的中心:
\begin{equation}
\mu_k = \frac{1}{|C_k|} \sum_{x_i \in C_k} x_i
\end{equation}
Python示例代码
1 | import numpy as np |
生成数据:使用make_blobs生成了500个二维数据点,分为4个簇。
训练模型:使用KMeans模型进行训练,设定簇数为4。
预测与绘图:根据训练结果进行预测,并将数据点按簇绘制成不同颜色,同时用红色标注出簇中心。
大家可以清晰地看到K均值聚类的效果,即每个簇内的数据点被分为同一种颜色,而不同簇的数据点被分为不同颜色,同时簇中心用红色圆点表示。
层次聚类(Hierarchical Clustering)
层次聚类(Hierarchical Clustering)是一种常见的无监督学习算法,旨在通过构建层次树状结构将数据点进行分组。它可以分为两种类型:自底向上的聚合(agglomerative)和自顶向下的分裂(divisive)聚类方法。
核心原理
层次聚类的核心思想是通过递归地合并或分裂簇,构建一个层次树(树状图或树状图),表示数据的嵌套分组。这里我们以自底向上的聚合层次聚类为例:
初始化:将每个数据点视为一个独立的簇。
计算距离:计算所有簇之间的距离矩阵。
合并簇:找到距离最近的两个簇并合并它们。
更新距离矩阵:更新合并后的簇与其他簇之间的距离。
重复:重复步骤3和4,直到所有数据点合并成一个簇。
核心公式
假设数据集为$x_1, x_2, …,x_n$,簇之间的距离可以通过多种方式计算,包括最小距离(single linkage)、最大距离(complete linkage)和平均距离(average linkage)等。
- 距离计算:假设簇$A$和簇$B$中的点分别为$a_1, a_2,…,a_p$和$b_1,b_2,…b_q$,则不同的距离计算方法如下:
最小距离(单链法):
\begin{equation}
d(A,B) = \min_{i,j} \Arrowvert a_i-b_j \Arrowvert
\end{equation}最大距离(全链法):
\begin{equation}
d(A,B) = \max_{i,j} \Arrowvert a_i-b_j \Arrowvert
\end{equation}平均距离(平均链法):
\begin{equation}
d(A,B) = \frac{1}{pq} \sum^{p}{i=1} \sum^{q}{j=1} \Arrowvert a_i-b_j \Arrowvert
\end{equation}
Python案例
1 | import numpy as np |
生成数据:使用make_blobs生成500个二维数据点,分为3个簇。
层次聚类:使用linkage函数进行层次聚类,采用Ward方法计算簇间距离。
绘制树状图:使用dendrogram函数绘制树状图,展示聚类的层次结构。
通过树状图,大家可以清晰地看到层次聚类的合并过程,从最底层的单个数据点逐渐合并到最终的一个簇。树状图的高度表示簇之间的距离,合并越早的簇之间距离越近,合并越晚的簇之间距离越远。
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,可以发现任意形状的簇,同时能够识别出噪声点。与K均值和层次聚类不同,DBSCAN不需要事先指定簇的数量。
核心原理
DBSCAN通过在数据点周围划定一个$\varepsilon$半径,计算半径内的数据点数量来定义簇。其基本思想是密度足够高的区域形成簇,而密度较低的区域被认为是噪声。主要步骤如下:
定义核心点:对于数据集中每个点,如果在其ε半径内的点数大于或等于最小点数(minPts),则该点为核心点。
扩展簇:从核心点出发,将其邻域内的所有点(包括边界点和其他核心点)归入该簇,然后递归地将这些点的邻域内的点也归入该簇。
标记噪声点:如果一个点既不是核心点也不是边界点,则将其标记为噪声点。
核心公式
- 邻域定义:对于点$p$,其邻域定义为:
\begin{equation}
N_{\varepsilon}(p) = { q \in D|{\bf dist}(p,q)\leq \varepsilon }
\end{equation}
其中 $D$ 是数据集,${\bf dist}(p,q)$ 是点 $p$ 和点 $q$ 之间的距离,通常使用欧氏距离。
- 核心点:如果点 $p$ 的邻域包含至少 minPts 个点,则 $p$ 是核心点:
\begin{equation}
|N_{\varepsilon}(p)| \geq {\bf minPts}
\end{equation}
Python案例
1 | import numpy as np |
生成数据:使用make_moons生成500个二维数据点,这些数据点形成两个半月形簇,并添加了一定的噪声。
训练模型:使用DBSCAN模型进行训练,设置$\varepsilon$为0.2,minPts为5。
预测与绘图:根据训练结果进行预测,并将数据点按簇绘制成不同颜色,同时用红色标注出噪声点。
大家可以清晰地看到DBSCAN的聚类效果,两个半月形的簇被正确识别出来,噪声点用红色标注。DBSCAN能够很好地处理复杂形状的簇,并且能够识别出数据中的噪声点。
高斯混合模型(Gaussian Mixture Model,GMM)
高斯混合模型(GMM)是一种概率模型,它假设所有的数据点是由若干个不同的高斯分布(即正态分布)组成的混合生成。GMM常用于聚类分析,特别适合于发现复杂数据分布中的潜在群体结构。
核心原理
GMM通过期望最大化(EM)算法来估计模型参数。EM算法是一个迭代优化算法,包括两个主要步骤:
E步(Expectation):计算给定当前参数下每个数据点属于每个高斯分布的概率(即责任)。
M步(Maximization):根据计算出的责任,重新估计每个高斯分布的参数(均值、方差和权重)。
核心公式
- 高斯混合模型的概率密度函数:
\begin{equation}
p(x) = \sum^{K}_{k = 1}\pi_k \mathcal{N}(x|\mu_k,\Sigma_k)
\end{equation}
其中,$\pi_k$是第$k$个高斯分布的权重,$\mathcal{N}(x|\mu_k,\sum_k)$是第$k$个高斯分布的概率密度函数,其参数为均值$\mu_k$和协方差矩阵$\Sigma_k$。
- E步(计算责任):
\begin{equation}
\gamma_{ik} = \frac{\pi_k\mathcal{N}(x|\mu_k,\Sigma_k)}{\sum_{j = 1}^{K}\pi_j \mathcal{N}(x|\mu_k,\Sigma_k)}
\end{equation}
其中,$\gamma_{ik}$是数据点$x_i$属于第$k$个高斯分布的概率。
- M步(更新参数):
更新权重:
\begin{equation}
\pi_k = \frac{N_k}{N}
\end{equation}
其中,$N_k = \sum_{i=1}^{N} \gamma_{ik}$是第$k$个高斯分布的有效样本数,$N$是数据点总数。
更新均值:
\begin{equation}
\mu_k = \frac{1}{N_k}\sum_{i=1}^{N} \gamma_{ik}x_i
\end{equation}
更新协方差矩阵:
\begin{equation}
\Sigma_k = \frac{1}{N_k}\sum_{i=1}^{N}\gamma_{ik}(x_i-\mu_k)(x_i-\mu_k)^{T}
\end{equation}
Python案例
1 | import numpy as np |
生成数据:使用make_blobs生成500个二维数据点,分为3个簇,并添加一定的噪声。
训练模型:使用GaussianMixture模型进行训练,设定簇数为3。
预测与绘图:根据训练结果进行预测,并将数据点按簇绘制成不同颜色,同时用红色标注出每个高斯分布的均值。
大家可以看到GMM的聚类效果,每个簇用不同的颜色表示,红色的X标记出每个高斯分布的中心。GMM能够很好地处理复杂的簇结构,并且可以估计每个簇的概率分布。
谱聚类(Spectral Clustering)
谱聚类(Spectral Clustering)是一种基于图论的聚类方法,通过利用数据点之间的相似性构建图,并利用图的谱(特征值和特征向量)进行聚类。它特别适合处理非凸形状的簇,并且能有效处理高维数据。
核心原理
谱聚类的核心思想是将数据点看作图中的节点,通过计算节点之间的相似性构建加权图,然后通过图的拉普拉斯矩阵的特征向量将数据映射到低维空间,再在低维空间中进行K均值聚类。
主要步骤如下:
构建相似度矩阵:计算数据点之间的相似度,构建相似度矩阵。
构建拉普拉斯矩阵:根据相似度矩阵构建图的拉普拉斯矩阵。
计算特征向量:计算拉普拉斯矩阵的前k个特征向量,将数据点映射到低维空间。
聚类:在低维空间中对映射后的数据点进行K均值聚类。
核心公式
- 相似度矩阵$W$:
\begin{equation}
W_{ij} = \exp\left(-\frac{\Arrowvert x_i-x_j \Arrowvert^2}{2\sigma^2}\right) \quad {\bf if} \quad \Arrowvert x_i - x_j \Arrowvert \leq \varepsilon, {\bf else} \quad 0
\end{equation}
其中,$\sigma$是高斯核函数的参数,$\varepsilon$是邻域范围。
度矩阵$D$:
\begin{equation}
D_{ij} = \sum_{j} W_{ij}
\end{equation}拉普拉斯矩阵$L$:
\begin{equation}
L = D-W
\end{equation}
或归一化的拉普拉斯矩阵:
\begin{equation}
L_{sym} = D^{-1/2}LD^{-1/2}
\end{equation}
特征向量:计算$L$或$L_{sym}$的前$k$个特征向量$u_1,u_2,…,u_k$。
聚类:将每个数据点$x_i$映射到特征向量组成的低维空间,再对这些向量进行$K$均值聚类。
Python案例
1 | import numpy as np |
生成数据:使用
make_moons
生成500个二维数据点,形成两个半月形簇,并添加一定的噪声。训练模型:使用
SpectralClustering
模型进行训练,设定簇数为2,使用最近邻相似度计算,标签分配使用K均值。预测与绘图:根据训练结果进行预测,并将数据点按簇绘制成不同颜色。
可以看到谱聚类的效果,两个半月形的簇被正确识别出来,每个簇用不同的颜色表示。谱聚类通过利用数据点之间的相似性构建图结构,并通过图的谱(特征向量)进行聚类,有效地处理了复杂形状的簇结构。