三种基础聚类算法与Python实现
聚类算法是一种无监督学习方法,旨在将数据集中的样本划分为若干个互不相交的子集(称为“簇”),使得同一簇内的样本尽可能相似,而不同簇间的样本尽可能不同。根据其核心思想和构建方式,聚类算法主要可分为以下几大类:
1. 基于划分的聚类
这类算法预先指定聚类数量 k,通过迭代优化将数据划分到 k 个簇中。
- 代表算法:K-Means、K-Medoids。
- 核心思想:首先随机选择
k个初始质心,然后将每个点分配到最近的质心所属的簇,再重新计算每个簇的质心,重复此过程直至质心稳定或达到最大迭代次数。 - 特点:计算效率高,适用于凸形数据集和大规模数据。但需要预先指定
k,对初始质心敏感,且对噪声和异常值(离群点)鲁棒性较差。
K-Means Python 代码实现示例:
import numpy as np
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
# 1. 生成模拟数据
X, y_true = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)
# X 为特征数据, y_true 为真实标签(用于对比,实际无监督学习中不可用)
# 2. 创建K-Means模型并拟合数据
kmeans = KMeans(n_clusters=4, random_state=0, n_init='auto')
kmeans.fit(X)
# 3. 获取预测的簇标签和质心坐标
y_kmeans = kmeans.predict(X)
centroids = kmeans.cluster_centers_
# 4. 可视化聚类结果
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis')
plt.scatter(centroids[:, 0], centroids[:, 1], c='red', s=200, alpha=0.8, marker='X')
plt.title('K-Means Clustering Result')
plt.show()
2. 基于层次的聚类
这类算法不预先指定簇的数量,而是通过构建树状的簇层次结构(树状图)来展示数据点之间的嵌套聚类关系。主要分为两种策略:
-
凝聚(自底向上):开始时每个样本点自成一簇,然后迭代地将最相似的两个簇合并,直到所有点合并为一个簇或满足终止条件。AGNES 是该策略的典型算法。
-
分裂(自顶向下):开始时所有样本点属于一个簇,然后迭代地分裂出最不相似的子簇,直到每个点自成一簇或满足终止条件。
-
特点:无需预先指定簇数,可通过树状图直观地确定任意层次的聚类结构。但计算复杂度通常较高(尤其是凝聚法),且已做的合并或分裂操作不可撤销。
AGNES(凝聚层次聚类)Python 代码实现示例:
import numpy as np
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
# 1. 生成模拟数据
X, _ = make_blobs(n_samples=150, centers=3, cluster_std=0.5, random_state=0)
# 2. 计算连接矩阵(linkage matrix)
# 参数 ‘ward’ 表示使用沃德方差最小化方法计算类间距离,其他可选 ‘single‘, 'complete', 'average' 等
Z = linkage(X, method='ward')
# 3. 绘制树状图
plt.figure(figsize=(10, 7))
plt.title('AGNES Dendrogram')
plt.xlabel('Sample index')
plt.ylabel('Distance')
dendrogram(Z)
plt.show()
# 4. 根据距离阈值或指定簇数量,从层次结构中提取平面聚类结果
# 例如,提取3个簇
clusters = fcluster(Z, t=3, criterion='maxclust')
print("Cluster assignments:", clusters)
3. 基于密度的聚类
这类算法将簇定义为数据空间中密度高于周围区域的区域,能够发现任意形状的簇,并能有效识别噪声点。
- 代表算法:DBSCAN。
- 核心思想:基于两个参数——邻域半径
eps和最小样本数min_samples。如果一个点的eps邻域内包含至少min_samples个点,则该点被视为核心点。由核心点密度可达的所有点形成一个簇,不属于任何簇的点被标记为噪声。 - 特点:无需预设簇数,能处理任意形状的簇和噪声。但对参数
eps和min_samples敏感,在高维数据上可能效果不佳。
DBSCAN Python 代码实现示例:
import numpy as np
from sklearn.cluster import DBSCAN
from sklearn.datasets import make_moons
import matplotlib.pyplot as plt
# 1. 生成非凸形状的模拟数据(如月牙形)
X, _ = make_moons(n_samples=200, noise=0.05, random_state=0)
# 2. 创建DBSCAN模型并拟合数据
# eps: 邻域半径, min_samples: 核心点所需的最小邻域样本数
dbscan = DBSCAN(eps=0.3, min_samples=5)
y_db = dbscan.fit_predict(X)
# 3. 可视化聚类结果(噪声点通常标记为-1,用不同颜色表示)
plt.scatter(X[:, 0], X[:, 1], c=y_db, s=50, cmap='viridis')
plt.title('DBSCAN Clustering Result')
plt.show()
4. 基于模型的聚类
这类算法为每个簇假定一个数学模型(如概率分布),然后通过拟合模型来发现数据的内在结构。
- 代表算法:高斯混合模型。
- 核心思想:假设数据是由多个高斯分布混合生成,通过期望最大化等算法估计每个高斯分布的参数(均值、协方差)和混合权重,从而将数据点软分配到各分布(簇)。
- 特点:提供概率归属,可以处理软聚类。模型本身可能对数据的分布假设敏感。
5. 基于网格的聚类
这类算法将数据空间划分为有限个单元的网格结构,然后在网格单元上进行聚类操作。
- 代表算法:STING。
- 核心思想:通过网格划分,将聚类操作从数据对象转移到网格单元,利用网格单元的统计信息进行快速聚类。
- 特点:处理速度快,但聚类精度受网格粒度影响,可能无法捕获更精细的边界。
算法选择与对比
| 特性/算法 | K-Means | AGNES (层次-凝聚) | DBSCAN |
|---|---|---|---|
| 簇形状 | 凸形,球形 | 任意(取决于连接度量) | 任意形状 |
| 噪声处理 | 敏感 | 敏感(除非专门处理) | 鲁棒,能识别噪声点 |
| 需预设簇数 (k) | 是 | 否(可从树状图切分得到) | 否 |
| 计算复杂度 | 低,O(n*k*t) | 高,O(n²) 到 O(n³) | 中等,O(n log n) (使用索引) |
| 结果稳定性 | 受初始质心影响,可能局部最优 | 确定性(给定连接方法) | 对参数敏感 |
| 主要应用场景 | 客户分群、图像分割 | 生物分类、文档层次组织 | 空间数据、异常检测 |
应用场景举例:在客户细分中,若客户特征分布近似球形且无大量异常值,可选用 K-Means。若希望探索客户群体的自然层次结构(如从大类到小类),层次聚类(AGNES) 并可视化树状图是合适的选择。在地理位置点聚类或网络入侵检测中,数据可能呈现任意形状且包含噪声,DBSCAN 则更具优势。
参考来源
- spark调用python算法_利用Spark-mllab进行聚类,分类,回归分析的代码实现(python)
- 使用随机森林和Kmeans算法进行降维和分类聚类,最终将数据合并。以下是Python的代码实现。
- kmeans鸢尾花分类python代码_python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan)
- AGNES聚类算法实战:用Python手把手教你实现数据分类(附完整代码)
- 【机器学习】:Kmeans均值聚类算法原理(附带Python代码实现)
- 聚类算法:Hierarchical Clustering层次聚类
更多推荐
所有评论(0)