Python scikit-learn 1.4 实战:3种聚类算法(系统/动态/有序)核心差异与代码对比
2026/7/9 21:50:24 网站建设 项目流程

Python scikit-learn 1.4 实战:3种聚类算法核心差异与代码对比

在数据科学领域,聚类分析是最常用的无监督学习技术之一。不同于分类问题,聚类算法不需要预先标记的训练数据,而是通过发现数据中的自然分组来揭示隐藏的模式。本文将聚焦于三种最具代表性的聚类方法:系统聚类(层次聚类)、动态聚类(K-means)和有序聚类(SOM),通过scikit-learn 1.4版本的实际代码演示,帮助读者理解它们的内在机理和适用场景。

1. 环境准备与数据生成

在开始比较三种聚类算法之前,我们需要准备一个标准化的实验环境。这里使用scikit-learn的make_blobs函数生成包含三个明显簇的数据集,同时添加一些噪声点以增加挑战性:

import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import make_blobs # 生成样本数据 X, y = make_blobs(n_samples=500, centers=3, cluster_std=0.8, random_state=42) # 添加随机噪声 np.random.seed(42) noise = np.random.uniform(low=-5, high=5, size=(20, 2)) X = np.vstack([X, noise]) plt.figure(figsize=(8, 6)) plt.scatter(X[:, 0], X[:, 1], s=50, alpha=0.6) plt.title("原始数据分布") plt.show()

这个数据集具有以下特点:

  • 包含520个二维数据点
  • 三个主要簇的中心明显分离
  • 添加了20个均匀分布的噪声点
  • 簇内标准差设置为0.8以保证适度重叠

提示:在实际项目中,数据预处理(如标准化)通常是必要步骤。本例省略此步骤是因为生成的数据已处于相近尺度。

2. 系统聚类(层次聚类)实现与分析

系统聚类,又称层次聚类,通过构建树状图(dendrogram)来展示数据的层次分解过程。scikit-learn中的AgglomerativeClustering实现了自底向上的聚合策略。

2.1 算法原理与参数选择

层次聚类的核心是定义簇间距离度量方式。常见选项包括:

  • Ward:最小化簇内方差(默认)
  • Complete:最大簇间距离
  • Average:平均簇间距离
  • Single:最小簇间距离
from sklearn.cluster import AgglomerativeClustering from scipy.cluster.hierarchy import dendrogram, linkage # 计算连接矩阵 Z = linkage(X, method='ward') # 绘制树状图 plt.figure(figsize=(12, 6)) dendrogram(Z, truncate_mode='lastp', p=12) plt.title("层次聚类树状图") plt.xlabel("样本索引") plt.ylabel("距离") plt.show()

2.2 模型训练与结果可视化

# 训练模型 hierarchical = AgglomerativeClustering(n_clusters=3, affinity='euclidean', linkage='ward') hierarchical_labels = hierarchical.fit_predict(X) # 可视化结果 plt.figure(figsize=(8, 6)) plt.scatter(X[:, 0], X[:, 1], c=hierarchical_labels, s=50, alpha=0.6, cmap='viridis') plt.title("层次聚类结果") plt.show()

层次聚类的优势在于:

  • 不需要预先指定簇数(可通过树状图分析)
  • 能够展示数据的层次结构
  • 对噪声相对鲁棒

但计算复杂度较高(O(n³)),不适合大规模数据集。

3. 动态聚类(K-means)实现与分析

K-means是最著名的动态聚类算法,通过迭代优化簇中心和样本分配来最小化簇内平方和。

3.1 算法流程与关键参数

K-means的核心参数是n_clusters(簇数)。我们可以使用肘部法则确定最佳K值:

from sklearn.cluster import KMeans # 计算不同K值的SSE sse = [] for k in range(1, 10): kmeans = KMeans(n_clusters=k, random_state=42) kmeans.fit(X) sse.append(kmeans.inertia_) # 绘制肘部图 plt.figure(figsize=(8, 6)) plt.plot(range(1, 10), sse, marker='o') plt.xlabel("簇数 (K)") plt.ylabel("SSE") plt.title("肘部法则确定最佳K值") plt.show()

3.2 模型训练与性能评估

# 训练K-means模型 kmeans = KMeans(n_clusters=3, random_state=42) kmeans_labels = kmeans.fit_predict(X) # 可视化结果 plt.figure(figsize=(8, 6)) plt.scatter(X[:, 0], X[:, 1], c=kmeans_labels, s=50, alpha=0.6, cmap='viridis') plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], c='red', s=200, marker='X') plt.title("K-means聚类结果") plt.show()

K-means的优势包括:

  • 计算效率高(O(n))
  • 实现简单,易于理解
  • 对球形簇效果良好

但存在以下局限:

  • 需要预先指定K值
  • 对初始中心敏感
  • 对非球形簇效果不佳
  • 对噪声和异常值敏感

4. 有序聚类(自组织映射SOM)实现与分析

自组织映射(SOM)是一种特殊的神经网络,通过竞争学习将高维数据映射到低维(通常是二维)网格上,保持拓扑结构。

4.1 SOM实现与训练

虽然scikit-learn未直接提供SOM实现,我们可以使用minisom库:

!pip install minisom from minisom import MiniSom # 初始化SOM som = MiniSom(x=5, y=5, input_len=2, sigma=1.0, learning_rate=0.5, random_seed=42) # 训练SOM som.train_random(X, 500) # 获取聚类标签 som_labels = np.array([som.winner(x) for x in X]) som_labels = som_labels[:, 0] * 5 + som_labels[:, 1] # 转换为单一标签 # 可视化结果 plt.figure(figsize=(10, 8)) plt.pcolor(som.distance_map().T, cmap='bone_r') plt.colorbar() for i, (x, y) in enumerate(X): w = som.winner(x) plt.plot(w[0]+0.5, w[1]+0.5, 'o', markerfacecolor=plt.cm.viridis(som_labels[i]/25.), markeredgecolor='k', markersize=10, alpha=0.7) plt.title("SOM聚类结果") plt.show()

4.2 SOM特点分析

SOM的优势在于:

  • 保持数据的拓扑结构
  • 可视化能力强
  • 适合探索性数据分析

但存在以下挑战:

  • 训练过程复杂
  • 需要调整多个超参数
  • 解释性相对较差

5. 三种算法综合对比

为了系统比较三种算法的性能,我们使用轮廓系数和Calinski-Harabasz指数进行评估:

from sklearn.metrics import silhouette_score, calinski_harabasz_score # 评估指标计算 metrics = { '层次聚类': { '轮廓系数': silhouette_score(X, hierarchical_labels), 'CH指数': calinski_harabasz_score(X, hierarchical_labels) }, 'K-means': { '轮廓系数': silhouette_score(X, kmeans_labels), 'CH指数': calinski_harabasz_score(X, kmeans_labels) }, 'SOM': { '轮廓系数': silhouette_score(X, som_labels), 'CH指数': calinski_harabasz_score(X, som_labels) } } # 展示结果对比 import pandas as pd pd.DataFrame(metrics).T

算法对比总结:

特性层次聚类K-meansSOM
计算复杂度
需要预设K值
抗噪声能力
可视化能力
保持拓扑
适合大数据

在实际项目中,选择聚类算法应考虑:

  • 数据规模和维度
  • 预期的簇形状
  • 是否需要层次结构
  • 可视化需求
  • 计算资源限制

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询