机器学习中无监督学习方法的聚类:划分式聚类、层次聚类、密度聚类
1.定义和特点
2.划分式聚类:K-Means 、 K-Medoids
3.层次聚类:树状图
4.密度聚类:DBSCAN
5.聚类的应用
一、定义和特点
机器学习中的无监督学习聚类是一种通过数据内在结构将样本分组的技术,无需预先标注的类别标签。 它的核心目标是将相似样本归为同一簇(Cluster),相异样本归为不同簇,广泛应用于数据探索、模式识别、市场细分等领域。聚类的典型算法有划分式聚类(K-Means、K-Medoids适用于球形簇)、层次聚类(凝聚型(自底向上)或分裂型(自顶向下),生成树状图Dendrogram)、密度聚类DBSCAN(适用于发现任意形状的簇,对噪声不敏感)、基于模型的聚类(高斯混合模型GMM、基于神经网络的聚类-自组织映射 SOM)等。
1.无监督聚类的特点
(1)无标签:完全基于样本特征的相似性或距离进行分组。
(2)探索性分析:用于发现数据中隐藏的模式、异常值或自然分组。
(3)输出:结果可以是明确的簇标签(如 K-Means)或层次结构(如层次聚类)。
(4)评价:无真值标签时,需依赖内部指标(如轮廓系数)评估聚类质量。
2.对比
通过数据特点(规模、密度、形状、噪声)和业务需求(是否需可解释性、自动调参),可快速匹配合适的聚类算法。
算法 | 核心思想 | 是否需预设 K | 噪声处理 | 簇形状 | 数据类型 | 复杂度 | 典型场景 |
---|---|---|---|---|---|---|---|
K-Means | 质心 + 最小平方误差 | 是(敏感) | 差 | 球形 / 凸形 | 数值型 | 低 - 中等 | 用户分群、图像压缩 |
K-Medoids | 中心点 + 最小总距离 | 是(敏感) | 中等 | 球形 / 凸形 | 任意(需距离) | 高 | 含噪声数据、分类数据 |
层次聚类 | 树状图层次合并 | 否(事后切割) | 差 | 任意(依赖合并策略) | 任意 | 高 | 层次结构分析、小数据集探索 |
DBSCAN | 密度可达性 | 否 | 优 | 任意形状 | 数值型(需距离) | 中等 | 地理数据、异常检测 |
HDBSCAN | 多密度层次密度树 | 否 | 优 | 任意形状 | 数值型(需距离) | 中等-高 | 多密度数据、复杂结构数据 |
二、划分式聚类:K-Means 、 K-Medoids
1.定义
划分式聚类是一种常见的聚类方法,其核心思想是将数据集划分为 K 个不重叠的簇,每个样本属于且仅属于一个簇。 这种方法的目标是优化某种准则函数,使得簇内的样本尽可能相似,而簇间的样本尽可能不相似。K-Means 和 K-Medoids 是其代表算法。K-Means 简单高效,适用于大规模数据和球形簇,但对初始质心和噪声敏感;K-Medoids 对噪声和异常值鲁棒,适用于非球形簇,但计算复杂度较高。
2.算法
(1)K-Means:基于质心迭代优化,目标是最小化簇内误差平方和(WCSS)。
过程:
1)初始化:随机选择 K 个样本点作为初始质心。
2)分配步骤(Assignment Step):将每个样本点分配到最近的质心所代表的簇中。距离度量通常使用欧几里得距离。
3)更新步骤(Update Step):重新计算每个簇的质心,质心是簇内所有样本点的均值。
4)迭代:重复分配步骤和更新步骤,直到质心不再变化或达到预设的迭代次数。
(2)K-Medoids:用簇内的实际样本点(称为中心点)替代质心。
过程:
1)初始化:随机选择 K 个样本点作为初始中心点。
2)分配步骤:将每个样本点分配到最近的中心点所代表的簇中。
3)更新步骤:在每个簇内,尝试将每个样本点作为新的中心点,计算新的总代价(如簇内距离之和),选择使代价最小的样本点作为新的中心点。
4)迭代:重复分配步骤和更新步骤,直到中心点不再变化或达到预设的迭代次数。
3.质心(Centroid) 和 中心点(Medoid)说明
(1)质心(Centroid):K-Means 的簇中心
关键特点说明
1)可能不是实际数据点
质心是通过数学计算得到的 “虚拟点”,可能位于数据点之间的空白区域。例:假设簇内有 3 个点 (1,1)、(3,3)、(5,5),质心为 (3,3)(恰好是中间点);但若簇内有 2 个点 (1,1)、(3,3),质心为 (2,2)(非实际数据点)。
2)对异常值敏感
异常值的数值会直接拉高或拉低平均值。例:簇内有 4 个正常点 (1,1)、(2,2)、(3,3)、(4,4),质心为 (2.5,2.5);若加入异常值 (100,100),质心变为 (22,22),明显偏离正常数据密集区。
3)依赖数据连续性
需计算均值,因此要求数据是连续数值型(如身高、温度),无法直接用于分类数据(如 “颜色 = 红 / 蓝 / 绿”)。
(2)中心点(Medoid):K-Medoids 的簇中心
关键特点说明
1)必须是实际数据点
中心点从簇内现有数据点中选择,不会是虚拟点。例:假设簇内有 5 个点 (1,1)、(2,2)、(3,3)、(4,4)、(100,100),计算每个点到其他点的距离总和:
点 (1,1) 的总距离:d(1,2)+d(1,3)+d(1,4)+d(1,100)=1+2+3+99=105
点 (3,3)的总距离:d(3,1)+d(3,2)+d(3,4)+d(3,100)=2+1+1+97=101
点 (100,100)的总距离:99+98+97+96=390
显然,(3,3)的总距离最小,被选为中心点,而异常值 (100,100)不会成为中心点。
2)对异常值鲁棒
异常值即使存在,因其到其他点的距离总和很大,不会被选为中心点,因此簇中心仍位于正常数据密集区。
3)支持任意距离函数
无需计算均值,可处理分类数据(如用 “汉明距离” 计算文本差异)或非连续数据。
4.示例代码展示
(1)K-Means 示例
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt# 生成含异常值的数据
X, y = make_blobs(n_samples=300, centers=3, random_state=42)
X = np.vstack([X, [[10, 5]]]) # 添加异常值# K-Means聚类
kmeans = KMeans(n_clusters=3, random_state=42)
labels = kmeans.fit_predict(X)# 可视化
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=200, c='red', marker='*')
plt.title('K-Means Clustering (with Outlier)')
plt.show()
(2)K-Medoids 示例
from sklearn_extra.cluster import KMedoids
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt# 生成相同数据
X, y = make_blobs(n_samples=300, centers=3, random_state=42)
X = np.vstack([X, [[10, 5]]]) # 添加异常值# K-Medoids聚类
kmedoids = KMedoids(n_clusters=3, random_state=42, method='pam')
labels = kmedoids.fit_predict(X)# 可视化
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.scatter(X[kmedoids.medoid_indices_, 0], X[kmedoids.medoid_indices_, 1], s=200, c='red', marker='*')
plt.title('K-Medoids Clustering (with Outlier)')
plt.show()
三、层次聚类
1.定义
层次聚类是一种通过构建数据点之间的层次结构(树状图,Dendrogram)来实现聚类的算法。它不需要预先指定聚类数量,而是根据数据点的相似性或距离,逐步合并或分裂簇,最终形成一个嵌套的层次结构。
2.算法:凝聚式与分裂式
(1)凝聚式层次聚类(自底向上)
初始时,每个数据点自成一个簇。计算所有簇间的距离,将距离最近的两个簇合并为一个新簇。重复合并过程,直到所有数据点合并为一个大簇或满足停止条件(如簇数量阈值)。适用于小规模数据集,直观展示数据层次结构。
(2)分裂式层次聚类(自顶向下)
初始时,所有数据点属于一个大簇。将当前簇分裂为两个子簇(通常选择差异最大的点作为分裂中心)。重复分裂过程,直到每个簇仅包含一个数据点或满足条件。较少使用,计算复杂度较高。
3.关键步骤与参数
(1)距离度量:用于衡量数据点或簇之间的相似性。
欧氏距离(Euclidean Distance):最常用,适用于连续数据。
曼哈顿距离(Manhattan Distance):适用于城市街区等网格状数据。
余弦相似度(Cosine Similarity):适用于文本、高维数据,衡量方向而非距离。
(2)簇间距离计算方法:合并或分裂簇时,需定义簇间距离。
单链接(Single Linkage):取两个簇中距离最近的点对的距离作为簇间距离(易形成链式结构,对噪声敏感)。
全链接(Complete Linkage):取两个簇中距离最远的点对的距离作为簇间距离(倾向于紧凑簇,对异常值敏感)。
平均链接(Average Linkage):取两个簇中所有点对距离的平均值(平衡性较好,常用)。
质心链接(Centroid Linkage):取两个簇质心之间的距离(适用于凸形簇)。
(3)停止条件
(1)手动指定聚类数量(如分成 5 个簇)。
(2)设置距离阈值:当簇间距离超过阈值时停止合并。
(3)树状图切割:根据树状图的结构,选择合适的层次切割点。
4.树状图(Dendrogram)
(1)作用:直观展示层次聚类的过程和数据点的层次关系。
(2)横轴:数据点或簇(通常为索引或样本编号)。
(3)纵轴:簇间合并时的距离(高度)。
(4)切割树状图:通过水平切割线确定最终聚类数量,切割线对应的高度即簇间合并的距离阈值。
5.示例代码展示
# 层次聚类的树状图
import numpy as np
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import linkage, dendrogram, fcluster# 生成示例数据(二维点,分为3个自然簇)
np.random.seed(42)
X1 = np.random.randn(10, 2) + [5, 5] # 簇1:中心在(5,5)附近
X2 = np.random.randn(10, 2) + [0, 0] # 簇2:中心在(0,0)附近
X3 = np.random.randn(10, 2) + [10, 0] # 簇3:中心在(10,0)附近
X = np.vstack([X1, X2, X3]) # 合并所有点# 计算层次聚类(使用沃德方法,最小化方差)
Z = linkage(X, method='ward', metric='euclidean')# 绘制树状图
plt.figure(figsize=(12, 6))# 主图:树状图
plt.subplot(1, 2, 1)
dendrogram(Z, leaf_rotation=90, leaf_font_size=8)
plt.title('Hierarchical Clustering Dendrogram')
plt.xlabel('Data Points (Indices)')
plt.ylabel('Distance (Ward\'s method)')# 添加水平切割线(示例:切割为3个簇)
plt.axhline(y=20, color='r', linestyle='--', label='Cut-off for 3 clusters')
plt.legend()# 副图:原始数据点与聚类结果
plt.subplot(1, 2, 2)
# 基于距离阈值(20)获取聚类标签
labels = fcluster(Z, t=20, criterion='distance')
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', s=50)
plt.title('Clustering Result (k=3)')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')plt.tight_layout()
plt.show()
四、密度聚类
1.核心思想
密度聚类的核心在于基于样本分布的密度来划分簇。具体来说,它假设簇是由高密度区域组成,而簇与簇之间由低密度区域分隔。如果一个区域内样本点足够密集,那么这些点就被认为属于同一个簇;而那些孤立的、稀疏分布的点则被视为噪声。这种方法不依赖于簇的形状,而是通过密度来定义簇的边界,因此能够很好地处理任意形状的簇。
2. 算法
(1)DBSCAN(Density-Based Spatial Clustering of Applications with Noise)
DBSCAN 是密度聚类中最经典的算法之一,其基本思想是通过邻域密度来识别核心点、边界点和噪声点。
核心点(Core Point):如果一个点的 ε-邻域内(即以该点为中心,半径为 ε 的区域内)包含的样本数大于或等于 MinPts,则该点是核心点。
边界点(Border Point):如果一个点不是核心点,但它的 ε-邻域内包含至少一个核心点,则该点是边界点。
噪声点(Noise Point):既不是核心点也不是边界点的点被认为是噪声点。
算法流程:
1)遍历数据集中的每个点,判断其是否为核心点。
2)对于每个核心点,通过不断扩展其 ε-邻域内的点(包括核心点和边界点)来形成一个簇。
3)如果一个点是边界点,它会被分配到包含它的核心点所在的簇。
4)噪声点不会被分配到任何簇中。
(2) HDBSCAN(Hierarchical Density-Based Spatial Clustering of Applications with Noise)
HDBSCAN 是 DBSCAN 的一种改进算法,它基于层次密度来自动确定簇数,解决了 DBSCAN 在参数选择上的困难。核心思想是HDBSCAN 通过构建一个层次化的密度图来识别簇。它首先计算每个点的局部密度(即每个点的密度可达性),然后通过合并密度相近的点来形成簇。与 DBSCAN 不同,HDBSCAN 不需要手动设置 ε 参数,而是通过层次化的方法自动确定簇的边界。
算法流程:
1)计算每个点的局部密度和密度可达性。
2)构建一个层次化的密度图,将密度相近的点合并为簇。
3)通过剪枝操作去除噪声点,最终得到聚类结果。
3.示例代码展示:代码示例:K-Means vs. DBSCAN
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans, DBSCAN
from sklearn.datasets import make_moons, make_blobs# 生成模拟数据(包含噪声的月牙形数据)
X, y = make_moons(n_samples=200, noise=0.05, random_state=42)# K-Means聚类
kmeans = KMeans(n_clusters=2, random_state=42)
y_kmeans = kmeans.fit_predict(X)# DBSCAN聚类
dbscan = DBSCAN(eps=0.3, min_samples=5)
y_dbscan = dbscan.fit_predict(X)# 可视化结果
plt.figure(figsize=(12, 4))plt.subplot(1, 3, 1)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis')
plt.title('Original Data')plt.subplot(1, 3, 2)
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, cmap='viridis')
plt.title('K-Means Clustering')plt.subplot(1, 3, 3)
plt.scatter(X[:, 0], X[:, 1], c=y_dbscan, cmap='viridis')
plt.title('DBSCAN Clustering')plt.show()
五、聚类的应用
1. 数据探索与分类
(1)发现数据结构
从无标签数据中识别潜在的分组或类别,例如:在客户分群中,根据用户行为数据(如消费频率、购买金额等)将客户划分为 “高价值客户、普通客户、潜在流失客户” 等群体。在生物学中,根据基因表达数据对物种或细胞类型进行聚类。
(2)辅助传统分类
为有监督学习(如分类算法)提供预处理,例如通过聚类筛选代表性样本,或发现数据中的异常类别。
2. 市场细分与精准营销
根据用户属性(年龄、性别、消费习惯等)或行为数据,将市场划分为不同细分群体,针对每个群体设计个性化营销策略。例如电商平台根据用户浏览、购买记录聚类,向不同群体推送定制化商品推荐。银行通过客户金融数据聚类,识别高风险客户或优质理财客户。
3. 图像识别与计算机视觉
(1)图像分割
将图像像素点按颜色、纹理等特征聚类,实现目标区域分割(如从背景中提取物体)。
(2)特征提取
在图像特征(如 SIFT、HOG)层面聚类,用于图像检索或目标识别(如人脸识别中的特征分组)。
4. 异常检测
识别与大部分样本差异显著的 “离群点” 或异常数据,例如:信用卡交易数据中聚类正常消费模式,检测可能的盗刷交易(异常簇)。工业传感器数据中聚类设备正常运行状态,监控设备故障前的异常信号。
5. 推荐系统
通过用户行为数据聚类,将相似兴趣的用户分组,基于群体偏好生成推荐列表(如 “协同过滤” 中的用户聚类)。
6. 城市规划与地理信息系统(GIS)
根据地理位置、人口密度、设施分布等数据聚类,优化资源配置(如划分商业圈、规划交通路线)。