16 - 聚类算法进阶¶
🎯 本章概述¶
本章深入探讨聚类算法的高级主题,包括密度聚类、层次聚类、谱聚类等。
🔍 DBSCAN 深入¶
核心概念¶
Text Only
已在 03-无监督学习.md 中介绍,这里补充更多细节
参数选择:
- eps: 邻域半径
* 太小:大量噪声点
* 太大:所有点聚为一类
- min_samples: 核心点最小邻居数
* 通常设为维度数+1
* 越大,核心点越少,聚类越稀疏
参数选择方法¶
Python
from sklearn.neighbors import NearestNeighbors
import numpy as np
# k-距离图选择eps
def plot_k_distance(X, k=4):
neigh = NearestNeighbors(n_neighbors=k)
neigh.fit(X)
distances, _ = neigh.kneighbors(X)
# 第k近邻的距离排序
k_distances = np.sort(distances[:, k-1])
plt.plot(k_distances)
plt.ylabel(f'{k}-distance')
plt.xlabel('Points (sorted)')
plt.show()
# 拐点处的距离作为eps
return k_distances
# 使用
k_distances = plot_k_distance(X, k=4)
# 选择拐点处的值作为eps
OPTICS (Ordering Points To Identify Clustering Structure)¶
Text Only
DBSCAN的改进:
- 不需要指定全局eps
- 可以处理不同密度的簇
- 生成可达距离图
核心概念:
- 核心距离: 成为核心点所需的最小半径
- 可达距离: 点到最近核心点的距离
Python
from sklearn.cluster import OPTICS
optics = OPTICS(min_samples=5, xi=0.05, min_cluster_size=0.05)
labels = optics.fit_predict(X)
# 可视化可达距离
plt.plot(optics.reachability_[optics.ordering_])
plt.title('Reachability Plot')
plt.show()
🌳 层次聚类进阶¶
链接准则比较¶
Text Only
已在 03-无监督学习.md 中介绍,这里详细对比
单链接 (Single Linkage):
- 优点:可以处理非球形簇
- 缺点:链式效应,对噪声敏感
全链接 (Complete Linkage):
- 优点:紧凑的球形簇
- 缺点:倾向于打破大簇
平均链接 (Average Linkage):
- 平衡单链接和全链接
- 计算复杂度高
Ward链接:
- 最小化簇内方差
- 适合球形、等大小簇
BIRCH (Balanced Iterative Reducing and Clustering)¶
Text Only
适合大规模数据的层次聚类
特点:
- 单次扫描数据
- 使用CF树 (Clustering Feature Tree)
- 内存高效
CF向量:
- N: 子簇中点的数量
- LS: 线性和
- SS: 平方和
Python
from sklearn.cluster import Birch
birch = Birch(n_clusters=3, threshold=0.5, branching_factor=50)
birch.fit(X)
labels = birch.predict(X)
🎵 谱聚类 (Spectral Clustering)¶
核心思想¶
Text Only
将数据映射到特征空间,在特征空间进行聚类
步骤:
1. 构建相似度图(邻接矩阵)
2. 计算拉普拉斯矩阵
3. 特征分解,取前k个特征向量
4. 在特征向量构成的空间进行K-Means
算法详解¶
Python
from sklearn.cluster import SpectralClustering
from sklearn.metrics.pairwise import rbf_kernel
# 方法1:使用sklearn
sc = SpectralClustering(
n_clusters=3,
affinity='rbf', # 或 'nearest_neighbors'
gamma=1.0,
assign_labels='kmeans'
)
labels = sc.fit_predict(X)
# 方法2:手动实现
def spectral_clustering(X, n_clusters, gamma=1.0):
# 1. 构建相似度矩阵 (RBF核)
W = rbf_kernel(X, gamma=gamma)
# 2. 计算度矩阵
D = np.diag(W.sum(axis=1))
# 3. 计算归一化拉普拉斯矩阵
D_inv_sqrt = np.diag(1.0 / np.sqrt(W.sum(axis=1)))
L_sym = np.eye(len(X)) - D_inv_sqrt @ W @ D_inv_sqrt
# 4. 特征分解
eigenvalues, eigenvectors = np.linalg.eigh(L_sym)
# 5. 取前k个特征向量
X_embedded = eigenvectors[:, 1:n_clusters+1]
# 6. K-Means聚类
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=n_clusters)
labels = kmeans.fit_predict(X_embedded)
return labels
应用场景¶
🎯 高斯混合模型 (GMM) 进阶¶
模型选择¶
Python
from sklearn.mixture import GaussianMixture
import numpy as np
# 使用BIC选择最佳组件数
n_components_range = range(1, 10)
bics = []
for n_components in n_components_range:
gmm = GaussianMixture(n_components=n_components, random_state=42)
gmm.fit(X)
bics.append(gmm.bic(X))
# 选择BIC最小的模型
best_n = n_components_range[np.argmin(bics)]
print(f"最佳组件数: {best_n}")
# 可视化BIC曲线
plt.plot(n_components_range, bics)
plt.xlabel('Number of Components')
plt.ylabel('BIC')
plt.show()
协方差类型¶
Text Only
'full': 每个组件有自己的协方差矩阵
'tied': 所有组件共享协方差矩阵
'diag': 每个组件有自己的对角协方差矩阵
'spherical': 每个组件有自己的单一方差
📊 聚类评估进阶¶
内部指标¶
Python
from sklearn.metrics import silhouette_score, calinski_harabasz_score, davies_bouldin_score
# 轮廓系数 (-1到1,越大越好)
sil_score = silhouette_score(X, labels)
# Calinski-Harabasz指数 (越大越好)
ch_score = calinski_harabasz_score(X, labels)
# Davies-Bouldin指数 (越小越好)
db_score = davies_bouldin_score(X, labels)
稳定性评估¶
Python
from sklearn.metrics import adjusted_rand_score
import numpy as np
def clustering_stability(X, clusterer, n_bootstrap=10):
"""评估聚类稳定性"""
labels_original = clusterer.fit_predict(X)
scores = []
for _ in range(n_bootstrap):
# Bootstrap采样
indices = np.random.choice(len(X), size=len(X), replace=True)
X_resampled = X[indices]
labels_resampled = clusterer.fit_predict(X_resampled)
# 比较引导样本上的聚类与原始聚类的一致性
score = adjusted_rand_score(labels_original[indices], labels_resampled)
scores.append(score)
return np.mean(scores), np.std(scores)
🎯 高级主题¶
半监督聚类¶
Text Only
利用少量标签信息指导聚类
方法:
1. 约束K-Means: must-link/cannot-link约束
2. 种子K-Means: 使用标签初始化
3. 约束GMM: 带约束的EM算法
Python
from sklearn.semi_supervised import LabelSpreading
# 先进行半监督学习
label_spread = LabelSpreading(kernel='knn', alpha=0.2)
label_spread.fit(X, y_partial) # y_partial包含-1(未标记)
labels = label_spread.transduction_
流聚类 (Streaming Clustering)¶
Python
from sklearn.cluster import MiniBatchKMeans
mbk = MiniBatchKMeans(n_clusters=3, batch_size=100)
# 增量训练
for batch in stream_data():
mbk.partial_fit(batch)
labels = mbk.predict(X)
💡 聚类算法选择指南¶
Text Only
数据规模:
- 小数据 (<1000): 所有方法
- 中数据 (1K-100K): K-Means, DBSCAN, 层次聚类
- 大数据 (>100K): MiniBatchKMeans, BIRCH
簇形状:
- 球形: K-Means, GMM
- 任意形状: DBSCAN, 谱聚类, 单链接层次聚类
- 不同密度: OPTICS, 谱聚类
其他考虑:
- 需要概率: GMM
- 需要层次结构: 层次聚类
- 有噪声: DBSCAN, 谱聚类
- 需要稳定性: 多次运行取平均
🎯 总结¶
Text Only
聚类算法演进:
K-Means → 层次聚类 → DBSCAN → 谱聚类 → GMM
关键要点:
1. 没有 universally best 算法
2. 理解数据特点选择算法
3. 多种评估指标综合判断
4. 可视化验证结果
实践建议:
- 先用K-Means和DBSCAN探索
- 使用多种评估指标
- 可视化结果验证
- 考虑领域知识
下一步:学习 17-图神经网络.md,进入深度学习新领域!