Scikit Learn - 聚类方法
Scikit-learn - 聚类方法
Section titled “Scikit-learn - 聚类方法”聚类 (Clustering) 是一种基础的无监督机器学习任务,它涉及将一组对象(样本)分组,使得同一组(称为簇,Cluster)中的对象彼此之间比与其它组中的对象更相似。本章探讨了 Scikit-learn 的 sklearn.cluster 模块中提供的各种聚类算法。
聚类方法对于发现无标签数据中的内在结构和模式至关重要。它们有助于完成客户细分、异常检测和图像压缩等任务。
K-Means
Section titled “K-Means”K-Means 算法旨在将 n 个观测值划分为 k 个簇,其中每个观测值属于与其最近的平均值(簇中心)所在的簇。它是一种迭代算法,用于最小化簇内平方和(惯量)。簇的数量 k 必须预先指定。
Scikit-learn 提供了 sklearn.cluster.KMeans。关键参数包括 n_clusters(簇的数量,k)、init(初始化方法,‘k-means++’ 是默认推荐选项)和 n_init(K-Means 算法使用不同簇中心种子运行的次数,取最佳结果)。sample_weight 参数允许在计算簇中心时为样本分配不同的权重。
优点:简单,对于大型数据集计算效率高。适用于相似大小的球形、良好分离的簇。
缺点:需要指定 k。对初始簇中心位置敏感(尽管 ‘k-means++’ 缓解了这个问题)。难以处理非球形簇、密度不同或大小不均匀的簇。
Affinity Propagation
Section titled “Affinity Propagation”Affinity Propagation 通过在样本对之间发送消息来创建簇,直到收敛。与 K-Means 不同,它不需要预先指定簇的数量。它识别代表簇的“代表点”(exemplars)。
Scikit-learn 提供了 sklearn.cluster.AffinityPropagation。关键参数包括 damping 和 preference。一个显著的缺点是其时间复杂度通常为 O(N^2 * T),其中 N 是样本数,T 是迭代次数,这使得它不适用于非常大的数据集。
优点:无需指定 k。可以找到非平面几何形状的簇。
缺点:计算成本高。性能取决于消息传递参数。
Mean Shift
Section titled “Mean Shift”Mean Shift 是一种基于簇中心的算法,旨在发现样本平滑密度中的“斑点”。它的工作原理是通过将簇中心候选点更新为给定区域(由 bandwidth 定义)内点的均值。这个过程迭代进行直到收敛。簇的数量是自动确定的。
Scikit-learn 提供了 sklearn.cluster.MeanShift。bandwidth 参数至关重要;它决定了搜索区域的大小。如果未设置,则使用 estimate_bandwidth 进行估计。
优点:不假定特定的簇形状。自动确定簇的数量。
缺点:性能对 bandwidth 参数敏感。对于大型特征空间计算成本可能很高。
Spectral Clustering
Section titled “Spectral Clustering”Spectral Clustering(谱聚类)在数据相似度矩阵(或亲和矩阵)上使用其特征值(谱)进行降维,然后在降维后的空间(通常使用 K-Means)进行聚类。它对于找到非凸簇非常有用。
Scikit-learn 提供了 sklearn.cluster.SpectralClustering。关键参数包括 n_clusters 和 affinity(如何构建亲和矩阵,例如 ‘rbf’,‘nearest_neighbors’)。不建议用于非常多的簇。
优点:对非平面几何形状(例如,同心圆)有效。可以处理复杂的簇形状。
缺点:对于大型数据集计算成本可能很高。性能取决于亲和矩阵的选择。
Hierarchical Clustering
Section titled “Hierarchical Clustering”Hierarchical Clustering(层次聚类)构建簇的层次结构,通常表示为一棵树(树状图,dendrogram)。主要有两种类型:
- Agglomerative(凝聚式):一种“自下而上”的方法,每个观测值开始时自成一个簇,然后随着层次结构的向上移动,成对的簇被合并。
- Divisive(分裂式):一种“自上而下”的方法,所有观测值开始时都在一个簇中,然后随着层次结构的向下移动,递归地进行分裂。
Scikit-learn 提供了 sklearn.cluster.AgglomerativeClustering 用于凝聚式层次聚类。关键参数包括 n_clusters(或用于截断树状图的 distance_threshold)、linkage(‘ward’,‘complete’,‘average’,‘single’)和 affinity(用于计算连接的度量)。
优点:生成树状图,有助于理解数据结构。如果使用 distance_threshold,则无需指定 k。
缺点:计算成本可能很高(通常根据连接方法和实现不同,为 O(N^2 log N) 或 O(N^3))。在合并/分裂早期做出的决定是不可逆的。
DBSCAN (Density-Based Spatial Clustering of Applications with Noise)
Section titled “DBSCAN (Density-Based Spatial Clustering of Applications with Noise)”DBSCAN (基于密度的含噪声空间聚类) 将紧密排列的点分组(有许多附近邻居的点),并将孤立在低密度区域的点标记为离群点。它可以找到任意形状的簇,并且不需要指定 k。
Scikit-learn 提供了 sklearn.cluster.DBSCAN。关键参数是 eps(两个样本点之间被视为邻居的最大距离)和 min_samples(一个点被视为核心点所需的邻域中的样本数)。
优点:可以找到任意形状的簇。对离群点具有鲁棒性(将它们识别为噪声)。无需指定 k。
缺点:性能对 eps 和 min_samples 敏感。难以处理密度不均匀的簇。
OPTICS (Ordering Points To Identify the Clustering Structure)
Section titled “OPTICS (Ordering Points To Identify the Clustering Structure)”OPTICS (识别聚类结构的有序点集) 与 DBSCAN 相似,但解决了其主要缺点之一:检测密度不均匀数据中有意义的簇。它创建数据库的增强排序,表示其基于密度的聚类结构。然后可以使用此排序来提取簇。
Scikit-learn 提供了 sklearn.cluster.OPTICS。关键参数包括 min_samples、max_eps 和 xi。它可以被视为 DBSCAN 的泛化。
优点:比 DBSCAN 更好地处理密度不均匀的簇。生成可达性图,有助于理解簇结构。
缺点:比 DBSCAN 更复杂,难以解释。参数调优可能具有挑战性。
BIRCH (Balanced Iterative Reducing and Clustering using Hierarchies)
Section titled “BIRCH (Balanced Iterative Reducing and Clustering using Hierarchies)”BIRCH (使用层次结构进行平衡迭代归约和聚类) 专为非常大的数据集设计。它以增量和动态方式对传入的多维指标数据点进行聚类,以尝试利用可用资源(内存和时间)产生最佳质量的聚类结果。它构建一个称为聚类特征树(Clustering Feature Tree, CFT)的树结构。
Scikit-learn 提供了 sklearn.cluster.Birch。关键参数包括 threshold、branching_factor 和 n_clusters(如果不需要进行全局聚类或对 CF 子簇应用其他聚类算法,可以将其设置为 None)。
优点:对于大型数据集高效(单次扫描)。很好地处理离群点。
缺点:仅适用于数值数据。簇倾向于球形。对数据点的顺序敏感。
聚类算法比较
Section titled “聚类算法比较”聚类算法的选择取决于数据集的特征和问题的目标。以下是简要比较:
| 算法 | 关键参数 | 可伸缩性 (n_samples) | 用例 / 几何形状 |
|---|---|---|---|
| K-Means | n_clusters, init | 非常好 | 球形、大小均匀的簇。 |
| Affinity Propagation | damping, preference | 差 (O(N^2)) | 簇数量多,非平面几何形状,k 未知时。 |
| Mean Shift | bandwidth | 差到中等 | 寻找斑点,k 未知时。 |
| Spectral Clustering | n_clusters, affinity | 中等 | 非平面几何形状,复杂形状,少量簇。 |
| Hierarchical (Agglomerative) | n_clusters/distance_threshold, linkage | 中等到差 (O(N^2) 到 O(N^3)) | 层次结构,当 k 未知时 (使用阈值)。 |
| DBSCAN | eps, min_samples | 好 (O(N log N) 或 O(N^2)) | 非平面几何形状,大小不均匀,存在噪声。 |
| OPTICS | min_samples, xi, max_eps | 好 (类似于 DBSCAN) | 密度不均匀,存在噪声。 |
| BIRCH | threshold, branching_factor, n_clusters | 非常好 | 大型数据集,流式数据,球形簇。 |
在 Digits 数据集上应用 K-Means 聚类示例
Section titled “在 Digits 数据集上应用 K-Means 聚类示例”让我们在 digits 数据集上应用 K-Means。这个数据集包含手写数字的图片。我们将尝试在不使用真实标签的情况下对它们进行聚类,然后将簇分配与真实标签进行比较,看看 K-Means 对相似数字的分组效果如何。
import numpy as npfrom sklearn.cluster import KMeansfrom sklearn.datasets import load_digitsfrom sklearn.preprocessing import StandardScalerfrom sklearn.metrics import accuracy_score, adjusted_rand_score, silhouette_scorefrom scipy.stats import mode
# Load digits datasetdigits = load_digits()X, y_true = digits.data, digits.targetprint(f"Data shape: {X.shape}") # (1797 samples, 64 features)
# Scale the data for better K-Means performancescaler = StandardScaler()X_scaled = scaler.fit_transform(X)
# Apply K-Means clustering# We know there are 10 digits (0-9), so set n_clusters=10kmeans = KMeans(n_clusters=10, random_state=42, n_init='auto')clusters_pred = kmeans.fit_predict(X_scaled)
print(f"Shape of cluster centers: {kmeans.cluster_centers_.shape}") # (10 clusters, 64 features)
# Evaluate clustering performance (if ground truth is available for reference)# 1. Map predicted cluster labels to true labelslabels_mapped = np.zeros_like(clusters_pred)for i in range(10): mask = (clusters_pred == i) # Assign the most frequent true label in that cluster if np.any(mask): labels_mapped[mask] = mode(y_true[mask], keepdims=True)[0]
accuracy = accuracy_score(y_true, labels_mapped)print(f"Accuracy (after mapping clusters to true labels): {accuracy:.4f}")
# 2. Use clustering-specific metricsari_score = adjusted_rand_score(y_true, clusters_pred)print(f"Adjusted Rand Index (ARI): {ari_score:.4f}")
# Silhouette Score (does not use true labels, measures cluster cohesion and separation)sil_score = silhouette_score(X_scaled, clusters_pred)print(f"Silhouette Score: {sil_score:.4f}")
# Note: Accuracy here is for illustrative purposes, showing how well clusters align with true classes.# ARI and Silhouette Score are more standard for evaluating clustering itself.输出 (如果 n_init 不是 ‘auto’ 或 random_state 发生变化,结果可能会略有不同,因为 K-Means 初始化是随机的)
Section titled “输出 (如果 n_init 不是 ‘auto’ 或 random_state 发生变化,结果可能会略有不同,因为 K-Means 初始化是随机的)”Data shape: (1797, 64)Shape of cluster centers: (10, 64)Accuracy (after mapping clusters to true labels): 0.7902Adjusted Rand Index (ARI): 0.6570Silhouette Score: 0.1880这个示例演示了 K-Means 的应用和结果评估。K-Means 学习到的簇中心代表了每个发现的数字组的“平均”图片。将这些中心可视化(例如,将它们重塑为 8x8 图片)可以深入了解算法学习到的内容。有关更多评估信息,请参阅“聚类性能评估”章节。