CustomerID | Gender | Age | Annual Income (k$) | Spending Score (1-100) | |
---|---|---|---|---|---|
0 | 1 | Male | 19 | 15 | 39 |
1 | 2 | Male | 21 | 15 | 81 |
2 | 3 | Female | 20 | 16 | 6 |
3 | 4 | Female | 23 | 16 | 77 |
4 | 5 | Female | 31 | 17 | 40 |
想象你是腾讯视频的CEO,手握数亿用户的观影数据。
这些问题的答案,都指向一个核心技术:聚类分析 (Clustering)。
我们将通过一次深度旅程,全面掌握聚类分析的核心思想与实践。
更好的策略是:识别出具有相似品味的用户群体,然后针对性地进行推荐。
这种“物以类聚”的过程,就是我们今天要学习的核心——聚类 (Clustering)。它是在没有预先定义好的类别下,自动将相似的数据对象组合成簇的艺术和科学。
在进入聚类世界前,必须厘清一个重要概念:聚类 (Clustering) 与 分类 (Classification) 的区别。
分类 (监督学习)
聚类是一种经典的无监督学习 (Unsupervised Learning) 方法。
聚类的任务,就是将相似的数据点划归到同一个组(簇)中。
给定一个包含 N 个样本的数据集 \(X = \{x_1, x_2, \ldots, x_N\}\),聚类的目标是将其划分为 K 个簇 \(\{C_1, C_2, \ldots, C_K\}\)。
这个划分必须满足三个基本性质,共同构成一个划分 (Partition)。
每个被定义的簇,都必须真实地包含至少一个数据点。我们不做没有意义的划分。
\[ \large{\forall k \in \{1, \dots, K\}, C_k \neq \emptyset} \]
每个数据点只能属于唯一的一个簇,不能脚踏两只船。
\[ \large{\forall k \neq l, C_k \cap C_l = \emptyset} \]
数据集中的每一个数据点都必须被划分到某个簇中,不能有“漏网之鱼”。
\[ \large{\bigcup_{k=1}^{K} C_k = X} \]
聚类的核心思想非常直观:
簇内样本应尽可能“相似”,而簇间样本应尽可能“不相似”。
要实现“物以类聚”,我们必须首先解决两个根本性问题:
在聚类算法中,“不相似”的程度通常由“距离”来衡量。距离越远,越不相似。
一个有效的距离测度 \(DM(x, y)\) 必须满足以下四个性质:
性质 | 数学表达 | 经济学直觉 |
---|---|---|
非负性 | \(DM(x, y) \geq 0\) | 两个客户之间的差异度不能是负数。 |
同一性 | \(DM(x, x) = 0\) | 一个客户与自身的差异度为零。 |
对称性 | \(DM(x, y) = DM(y, x)\) | 客户A到B的差异度等于B到A的差异度。 |
三角不等式 | \(DM(x, z) \leq DM(x, y) + DM(y, z)\) | 经由第三者引入的间接差异,不会小于直接差异。 |
这是最常用、最直观的距离定义,即空间中两点间的直线距离。
对于两个 d 维向量 \(x=(x_1, \dots, x_d)\) 和 \(y=(y_1, \dots, y_d)\),其欧氏距离为:
\[ \large{DM_{euc}(x, y) = \sqrt{\sum_{i=1}^{d} (x_i - y_i)^2}} \]
应用场景: 当数据的各个维度是可比较的,并且我们关心绝对的物理距离时,欧氏距离是首选。
也称为“城市街区距离”,计算的是两点在标准坐标系上的绝对轴距总和。
\[ \large{DM_{man}(x, y) = \sum_{i=1}^{d} |x_i - y_i|} \]
应用场景: 当数据维度的移动是受限制的(例如,只能在棋盘格上移动),或者当不同维度的量纲差异很大时,曼哈顿距离可能比欧氏距离更鲁棒。
警告:在使用基于距离的聚类算法(如K-Means)之前,必须对数据进行标准化处理!
客户 | 年龄 (岁) | 年收入 (美元) |
---|---|---|
A | 25 | 50,000 |
B | 30 | 50,100 |
StandardScaler
等工具将所有特征缩放到相似的尺度上(例如,均值为0,方差为1)。如果不进行缩放,距离计算会被数值范围大的特征“绑架”。
类簇中心(或称质心)是一个簇的代表点。不同算法的定义方式不同,主要分为两类。
1. 基于均值的簇中心
2. 基于密度的簇中心
聚类需要一套客观的指标来评估其效果。评估方法分为两大类:
外部指标 (External Measures)
内部指标 (Internal Measures)
思想:一个簇的纯度有多高?我们查看簇中数量最多的那个“真实类别”占该簇总样本的比例。
计算方法:
\[ \large{\text{Purity} = \sum_{k=1}^{K} \frac{|C_k|}{N} \max_s \left( \frac{|C_k \cap L_s|}{|C_k|} \right)} \]
优点:简单直观。
缺点:如果簇的数量非常多(极端情况每个点一个簇),Purity会虚高,无法惩罚过于破碎的聚类结果。
假设我们有10个样本,真实类别是5个菱形和5个六边形。聚类算法将其分为两个簇 K1
和 K2
。
真实类别 | 菱形 | 六边形 |
---|---|---|
簇 K1 | 5 (主导) | 1 |
簇 K2 | 0 | 4 (主导) |
计算 K1 的纯度: \(Purity(K_1) = \max(\frac{5}{6}, \frac{1}{6}) = \frac{5}{6}\)
计算 K2 的纯度: \(Purity(K_2) = \max(\frac{0}{4}, \frac{4}{4}) = \frac{4}{4} = 1\)
计算整体纯度 (加权平均): \(Purity_{total} = \frac{|K1|}{N} \times Purity(K_1) + \frac{|K_2|}{N} \times Purity(K_2) = \frac{6}{10} \times \frac{5}{6} + \frac{4}{10} \times 1 = 0.5 + 0.4 = 0.9\)
思想:衡量一个簇内部的“混乱”程度。如果一个簇里各种真实类别的样本混杂在一起,它的熵就高;反之,如果它很“纯”,熵就低。
计算方法: 对于簇 \(C_k\),其熵的计算公式为: \[ \large{\text{Entropy}(C_k) = - \sum_{s=1}^{S} p_{ks} \log_2(p_{ks})} \]
其中,\(p_{ks} = \frac{|C_k \cap L_s|}{|C_k|}\) 是真实类别 \(s\) 在簇 \(k\) 中出现的概率。
我们继续使用上个例子中的簇 K1
来计算它的熵。
K1
中有6个样本。\[ \large{\text{Entropy}(K_1) = - \left( \frac{5}{6} \log_2\left(\frac{5}{6}\right) + \frac{1}{6} \log_2\left(\frac{1}{6}\right) \right) \approx 0.65} \]
这个值越接近0,说明簇越纯净。而 K2
中只有六边形,所以 \(p_{六边形} = 1\), \(\text{Entropy}(K_2) = -1 \log_2(1) = 0\),是完全纯净的。
Purity和Entropy都只看了一方面。同质性和完整性提供了一个更全面的视角。
同质性 (Homogeneity): 衡量 一个簇是否只包含单一类别的样本。如果每个簇都完美地只包含一个真实类别的成员,那么同质性为1。它类似于经济学中的“精确率”。
完整性 (Completeness): 衡量 同一类别的样本是否都被划分到了同一个簇中。如果某个真实类别的所有成员都被完美地分到了一个簇里,那么完整性就高。它类似于“召回率”。
这两个指标常常是相互制约的。
假设真实情况是 {3个苹果, 3个梨}。
完美聚类
高同质性, 低完整性
低同质性, 高完整性
当我们没有真实标签时,如何评估聚类效果?轮廓系数是一个强大的工具。
思想:对于每个数据点,我们都希望它 与自己簇内的点足够近,同时与别的簇的点足够远。
计算方法:对于样本 \(x_n\)
\[ \large{SC(x_n) = \frac{b(x_n) - a(x_n)}{\max\{a(x_n), b(x_n)\}}} \]
轮廓系数 \(SC(x_n)\) 的取值范围在 [-1, 1] 之间。
我们可以计算所有数据点的平均轮廓系数,作为整个聚类结果的评价指标。
K-Means 是最著名、最广泛使用的聚类算法之一。
K-Means 的目标是最小化所有簇的簇内误差平方和 (Sum of Squared Errors, SSE),也称为惯性 (Inertia)。
\[ \large{\text{minimize} \sum_{k=1}^{K} \sum_{x_n \in C_k} ||x_n - \mu_k||^2} \]
其中:
算法的每一步(分配和更新)都是为了让这个总误差值变得更小。
K-Means的算法过程就像一场“抢地盘”的游戏,分四步循环进行:
假设 K=3。我们随机在数据空间中选择三个点作为初始质心。
根据每个点到这三个初始中心的距离,将它们涂上最近中心的颜色。
对每个颜色的簇,计算其所有点的均值,并将簇中心移动到这个新位置。
重复“分配-更新”步骤,直到簇中心不再移动。此时,我们得到了最终的聚类结果。
随机初始化可能会导致次优的聚类结果,甚至完全错误的结果。
scikit-learn
中,init='k-means++'
是默认选项,我们通常无需担心。K-Means 算法本身无法告诉我们最佳的 K 是多少。这是一个需要我们利用领域知识和数据洞察来决定的超参数。
幸运的是,我们有两种常用的启发式方法来辅助决策:
思想: 尝试不同的 K 值(例如从2到10),并计算每个 K 值对应的簇内误差平方和 (SSE, a.k.a. Inertia)。
随着 K 值的增加,SSE 必然会下降。我们寻找的,是 SSE 下降速度由快变缓的那个“拐点”,即“肘部”。
思想: 对每个尝试的 K 值,计算其聚类结果的平均轮廓系数。我们选择那个使得平均轮廓系数最高的 K 值。
相比肘部法则,轮廓分析不仅考虑了簇内凝聚度,还考虑了簇间分离度,通常是更可靠的指标。
使用一个模拟的客户数据集,包含客户的年收入和消费分数。我们的目标是识别出不同的客户群体。
CustomerID | Gender | Age | Annual Income (k$) | Spending Score (1-100) | |
---|---|---|---|---|---|
0 | 1 | Male | 19 | 15 | 39 |
1 | 2 | Male | 21 | 15 | 81 |
2 | 3 | Female | 20 | 16 | 6 |
3 | 4 | Female | 23 | 16 | 77 |
4 | 5 | Female | 31 | 17 | 40 |
在应用 K-Means 之前,我们先用肘部法则和轮廓分析来确定最佳的簇数量 K。
两种方法都指向 K=5
是一个很好的选择。现在我们用 K=5
来运行K-Means。
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
# 1. 加载和准备数据
url = 'https://raw.githubusercontent.com/subashgandyer/datasets/main/mall_customers.csv'
# 此处为演示,实际项目中应加入更完整的错误处理
try:
df = pd.read_csv(url)
except: # 如果URL失效,创建模拟数据
print("URL数据加载失败,使用模拟数据代替。")
data = {'Annual Income (k$)': np.random.randint(15, 140, 200),
'Spending Score (1-100)': np.random.randint(1, 100, 200)}
df = pd.DataFrame(data)
X = df[['Annual Income (k$)', 'Spending Score (1-100)']]
# 2. 特征缩放 (至关重要的一步)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 3. 运行K-Means (我们已确定 K=5)
kmeans = KMeans(n_clusters=5, random_state=42, n_init='auto')
# 使用缩放后的数据进行训练和预测
df['Cluster'] = kmeans.fit_predict(X_scaled)
URL数据加载失败,使用模拟数据代替。
我们将聚类结果可视化,看看我们发现了哪些客户群体。
聚类结果清晰地揭示了五个不同的客户群体:
这种划分,为商场的精准营销、会员管理和资源分配提供了清晰的数据驱动依据。
与K-Means一次性将数据分成K个簇不同,层次聚类会创建一个聚类的层级结构。
整个过程的合并历史,就构成了一个树状的层次结构。
这通过链接准则 (Linkage Criterion) 来定义。
树状图是层次聚类的标志性输出。它直观地展示了簇的合并过程。
我们可以通过在某个高度“横切”树状图,来得到指定数量的簇。
当K-Means遇到瓶颈时:K-Means假设簇是球状的,对于不规则形状的簇(如月牙形、环形)则无能为力。
DBSCAN (Density-Based Spatial Clustering of Applications with Noise) 的登场:
eps
和 min_samples
)的选择很敏感,处理密度不均的数据集时效果不佳。DBSCAN 的工作依赖于三个关键定义,由两个参数 eps
(半径) 和 min_samples
(最少点数) 控制。
DBSCAN 的过程就像“滚雪球”:
P
。P
是否为核心点。
P
为起点,创建一个新簇。然后,通过 P
的 ε
-邻域,找到所有密度可达的点(包括其他核心点和边界点),将它们全部加入这个簇。这个过程会像链式反应一样不断扩展,直到整个密度相连的区域都被覆盖。让我们看一个K-Means无法处理,而DBSCAN能完美解决的例子:“双月”数据集。
超越“硬”聚类: K-Means 对每个点进行“非黑即白”的硬分配 (Hard Assignment)。但有时,一个点可能位于两个簇的边界,我们更希望得到一个概率描述。
高斯混合模型 (Gaussian Mixture Model, GMM) 提供了一种软聚类 (Soft Clustering) 方法。
特性 | K-Means | Gaussian Mixture Model (GMM) |
---|---|---|
簇形状 | 假设为球形 (圆形) | 可适应椭圆形 |
分配方式 | 硬分配 (Hard Assignment) | 软分配 (Soft Assignment) |
数学基础 | 基于距离 | 基于概率 (期望最大化算法) |
灵活性 | 较低 | 较高,能更好地拟合复杂数据 |
GMM 可以看作是 K-Means 的一个概率泛化版本。
当簇的形状不是圆形而是椭圆形时,GMM 的优势就体现出来了。
今天我们学习了四种主流的聚类算法,它们各有千秋。在实际应用中,没有“最好”的算法,只有“最合适”的算法。
算法 | 主要优点 | 主要缺点 | 适用场景 |
---|---|---|---|
K-Means | 速度快,简单易懂 | 需预设K,对球形簇敏感 | 大规模、簇结构简单的数据集 |
层次聚类 | 无需预设K,提供层次结构 | 计算复杂度高 (O(N^2)) | 需要探索数据层次结构,小数据集 |
DBSCAN | 无需预设K,可发现任意形状 | 对参数敏感,密度不均时困难 | 簇形状不规则,含噪声的数据集 |
GMM | 软聚类,簇形状灵活(椭圆) | 算法复杂,计算成本高 | 需要概率输出,簇有重叠 |
这是一个简化的决策流程,帮助你在实践中选择合适的聚类算法。
聚类分析不仅仅是一套算法,更是一种强大的商业洞察工具。
掌握聚类,就是掌握了从海量数据中发现结构、创造价值的关键钥匙。
Q & A