数学建模学习-聚类分析(Cluster Analysis)教程(13) K-means 层次聚类 聚类分析

数学建模学习-聚类分析(Cluster Analysis)教程(13)

写在最前

注意本文的相关代码及例子为同学们提供参考,借鉴相关结构,在这里举一些通俗易懂的例子,方便同学们根据实际情况修改代码,很多同学私信反映能否添加一些可视化,这里每篇教程都尽可能增加一些可视化方便同学理解,但具体使用时,同学们要根据实际情况选择是否在论文中添加可视化图片。
系列教程计划持续更新,同学们可以免费订阅专栏,内容充足后专栏可能付费,提前订阅的同学可以免费阅读,同时相关代码获取可以关注博主评论或私信。

目录

  1. 算法简介
  2. 算法特点
  3. 数学原理
  4. 应用场景
  5. 环境准备
  6. K-means聚类
  7. 层次聚类
  8. 聚类评估
  9. 实际应用注意事项
  10. 完整代码

算法简介

聚类分析是一种无监督学习方法,其主要目的是将相似的对象分组到同一个簇中,而将不相似的对象分到不同簇中。在数学建模中,聚类分析常用于发现数据中的内在结构和模式,帮助我们理解数据的分布特征。
本教程主要介绍两种常用的聚类方法:

  1. K-means聚类:基于距离的划分聚类方法
  2. 层次聚类:基于层次分解的聚类方法

算法特点

K-means聚类特点

  1. 算法简单,易于实现
  2. 计算复杂度相对较低,适合处理大规模数据
  3. 对初始聚类中心的选择敏感
  4. 需要预先指定聚类数量K
  5. 对噪声和异常值敏感
  6. 只能发现球形簇
  7. 不适合处理非凸形状的簇

层次聚类特点

  1. 可以得到层次化的聚类结构
  2. 不需要预先指定聚类数量
  3. 可以通过树状图直观显示聚类过程
  4. 计算复杂度较高,不适合大规模数据
  5. 一旦合并或分裂后不能撤销
  6. 能够处理任意形状的簇
  7. 对噪声和异常值较为稳健

数学原理

K-means数学原理

K-means算法的目标是最小化所有点到其所属簇中心的距离平方和,即最小化以下目标函数:
J = ∑ j = 1 k ∑ i = 1 n ∥ x i ( j ) − c j ∥ 2 J = \sum_{j=1}^k \sum_{i=1}^n \|x_i^{(j)} - c_j\|^2 J=j=1ki=1nxi(j)cj2
其中:

  • k k k 是簇的数量
  • n n n 是数据点的数量
  • x i ( j ) x_i^{(j)} xi(j) 是属于第j个簇的第i个数据点
  • c j c_j cj 是第j个簇的中心点
    算法的收敛性可以通过以下定理保证:
  1. 目标函数J在每次迭代中都会减小
  2. 由于J有下界(0),算法最终会收敛到局部最优解

层次聚类数学原理

层次聚类中的距离度量方法包括:

  1. 单链接(Single Linkage):
    D ( C i , C j ) = min ⁡ x ∈ C i , y ∈ C j d ( x , y ) D(C_i, C_j) = \min_{x \in C_i, y \in C_j} d(x,y) D(Ci,Cj)=minxCi,yCjd(x,y)
  2. 全链接(Complete Linkage):
    D ( C i , C j ) = max ⁡ x ∈ C i , y ∈ C j d ( x , y ) D(C_i, C_j) = \max_{x \in C_i, y \in C_j} d(x,y) D(Ci,Cj)=maxxCi,yCjd(x,y)
  3. 平均链接(Average Linkage):
    D ( C i , C j ) = 1 ∣ C i ∣ ∣ C j ∣ ∑ x ∈ C i ∑ y ∈ C j d ( x , y ) D(C_i, C_j) = \frac{1}{|C_i||C_j|} \sum_{x \in C_i} \sum_{y \in C_j} d(x,y) D(Ci,Cj)=Ci∣∣Cj1xCiyCjd(x,y)
  4. Ward方法:
    最小化合并后类内平方和的增量:
    Δ ( A , B ) = ∑ i ∈ A ∪ B ∥ x i − m A ∪ B ∥ 2 − ∑ i ∈ A ∥ x i − m A ∥ 2 − ∑ i ∈ B ∥ x i − m B ∥ 2 \Delta(A,B) = \sum_{i \in A \cup B} \|x_i - m_{A \cup B}\|^2 - \sum_{i \in A} \|x_i - m_A\|^2 - \sum_{i \in B} \|x_i - m_B\|^2 Δ(A,B)=iABximAB2iAximA2iBximB2

应用场景

1. 客户分群

  • 根据客户的消费行为、人口统计特征等进行分群
  • 制定针对性的营销策略
  • 识别高价值客户群体

2. 图像分割

  • 医学图像分割
  • 遥感图像分析
  • 计算机视觉应用

3. 异常检测

  • 金融欺诈检测
  • 网络入侵检测
  • 工业质量控制

4. 文本分析

  • 文档聚类
  • 主题发现
  • 新闻分类

5. 生物信息学

  • 基因表达分析
  • 蛋白质结构分类
  • 疾病亚型识别

环境准备

本教程需要以下Python库:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans, AgglomerativeClustering
from sklearn.datasets import make_blobs
import seaborn as sns
from scipy.cluster.hierarchy import dendrogram, linkage

K-means聚类

K-means算法的基本步骤:

  1. 随机选择K个点作为初始聚类中心
  2. 计算每个数据点到各个聚类中心的距离,将其划分到最近的聚类中心所属的类
  3. 重新计算每个类的中心点(均值)
  4. 重复步骤2和3,直到聚类中心基本不再变化

初始中心点选择策略

  1. 随机选择
  2. K-means++算法:
    • 随机选择第一个中心点
    • 计算每个点到已选中心点的最短距离
    • 按距离的平方作为概率选择新的中心点
    • 重复直到选择K个中心点

代码实现

def kmeans_clustering(X, n_clusters=4):
    """执行K-means聚类"""
    kmeans = KMeans(n_clusters=n_clusters, random_state=0)
    y_kmeans = kmeans.fit_predict(X)
    
    # 可视化结果
    plt.figure(figsize=(10, 6))
    plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, cmap='viridis')
    plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], 
                c='red', marker='x', s=200, linewidths=3, label='聚类中心')
    plt.title('K-means聚类结果')
    plt.xlabel('特征1')
    plt.ylabel('特征2')
    plt.legend()
    plt.savefig('cluster_analysis_13/images/kmeans_result.png')
    plt.close()

K-means聚类结果

在这里插入图片描述

层次聚类

层次聚类可以自底向上(凝聚式)或自顶向下(分裂式)进行,本教程采用凝聚式层次聚类。

凝聚式层次聚类步骤

  1. 将每个数据点视为一个簇
  2. 计算所有簇对之间的距离
  3. 合并距离最近的两个簇
  4. 更新簇间距离
  5. 重复步骤3和4,直到达到预期的簇数量或所有点都在同一个簇中

代码实现

def hierarchical_clustering(X, n_clusters=4):
    """执行层次聚类"""
    # 使用层次聚类
    clustering = AgglomerativeClustering(n_clusters=n_clusters)
    y_hc = clustering.fit_predict(X)
    
    # 可视化聚类结果
    plt.figure(figsize=(10, 6))
    plt.scatter(X[:, 0], X[:, 1], c=y_hc, cmap='viridis')
    plt.title('层次聚类结果')
    plt.xlabel('特征1')
    plt.ylabel('特征2')
    plt.savefig('cluster_analysis_13/images/hierarchical_result.png')
    plt.close()
    
    # 绘制树状图
    plt.figure(figsize=(10, 7))
    linkage_matrix = linkage(X, method='ward')
    dendrogram(linkage_matrix)
    plt.title('层次聚类树状图')
    plt.xlabel('样本索引')
    plt.ylabel('距离')
    plt.savefig('cluster_analysis_13/images/dendrogram.png')
    plt.close()

层次聚类结果

在这里插入图片描述

层次聚类树状图

在这里插入图片描述

聚类评估

在K-means聚类中,我们常用以下方法评估聚类效果:

1. 肘部法则(Elbow Method)

通过计算不同K值下的聚类内平方和(WCSS)来确定最佳的聚类数量。

2. 轮廓系数(Silhouette Coefficient)

衡量簇的紧密度和分离度:
s ( i ) = b ( i ) − a ( i ) max ⁡ { a ( i ) , b ( i ) } s(i) = \frac{b(i) - a(i)}{\max\{a(i), b(i)\}} s(i)=max{a(i),b(i)}b(i)a(i)
其中:

  • a ( i ) a(i) a(i) 是点i与同簇其他点的平均距离
  • b ( i ) b(i) b(i) 是点i与最近的其他簇中的点的平均距离

3. Calinski-Harabasz指数

计算簇间离散度与簇内离散度的比值:
C H = t r ( B k ) t r ( W k ) × n − k k − 1 CH = \frac{tr(B_k)}{tr(W_k)} \times \frac{n-k}{k-1} CH=tr(Wk)tr(Bk)×k1nk

代码实现

def evaluate_k_values(X, max_k=10):
    """评估不同K值的聚类效果"""
    inertias = []
    for k in range(1, max_k + 1):
        kmeans = KMeans(n_clusters=k, random_state=0)
        kmeans.fit(X)
        inertias.append(kmeans.inertia_)
    
    plt.figure(figsize=(10, 6))
    plt.plot(range(1, max_k + 1), inertias, 'bo-')
    plt.title('肘部法则图')
    plt.xlabel('聚类数量 (k)')
    plt.ylabel('聚类内平方和 (WCSS)')
    plt.savefig('cluster_analysis_13/images/elbow_method.png')
    plt.close()

肘部法则结果

在这里插入图片描述

实际应用注意事项

1. 数据预处理

  • 特征标准化:确保各个特征的尺度一致
  • 异常值处理:移除或处理异常值
  • 缺失值处理:填充或删除缺失值

2. 特征选择

  • 选择有区分度的特征
  • 降维处理(如PCA)
  • 避免使用相关性过高的特征

3. 聚类数量选择

  • 结合业务需求
  • 使用多种评估指标
  • 考虑计算资源限制

4. 结果验证

  • 交叉验证
  • 稳定性分析
  • 业务解释性验证

5. 性能优化

  • 数据采样
  • 并行计算
  • 增量式聚类

完整代码

完整的示例代码包括数据生成、聚类实现和结果可视化:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans, AgglomerativeClustering
from sklearn.datasets import make_blobs
import seaborn as sns
from scipy.cluster.hierarchy import dendrogram, linkage
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
# 生成示例数据
def generate_data(n_samples=300):
    """生成示例数据"""
    X, y = make_blobs(n_samples=n_samples, centers=4, 
                      cluster_std=0.60, random_state=0)
    return X
# K-means聚类
def kmeans_clustering(X, n_clusters=4):
    """执行K-means聚类"""
    kmeans = KMeans(n_clusters=n_clusters, random_state=0)
    y_kmeans = kmeans.fit_predict(X)
    
    # 可视化结果
    plt.figure(figsize=(10, 6))
    plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, cmap='viridis')
    plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], 
                c='red', marker='x', s=200, linewidths=3, label='聚类中心')
    plt.title('K-means聚类结果')
    plt.xlabel('特征1')
    plt.ylabel('特征2')
    plt.legend()
    plt.savefig('cluster_analysis_13/images/kmeans_result.png')
    plt.close()
# 层次聚类
def hierarchical_clustering(X, n_clusters=4):
    """执行层次聚类"""
    # 使用层次聚类
    clustering = AgglomerativeClustering(n_clusters=n_clusters)
    y_hc = clustering.fit_predict(X)
    
    # 可视化聚类结果
    plt.figure(figsize=(10, 6))
    plt.scatter(X[:, 0], X[:, 1], c=y_hc, cmap='viridis')
    plt.title('层次聚类结果')
    plt.xlabel('特征1')
    plt.ylabel('特征2')
    plt.savefig('cluster_analysis_13/images/hierarchical_result.png')
    plt.close()
    
    # 绘制树状图
    plt.figure(figsize=(10, 7))
    linkage_matrix = linkage(X, method='ward')
    dendrogram(linkage_matrix)
    plt.title('层次聚类树状图')
    plt.xlabel('样本索引')
    plt.ylabel('距离')
    plt.savefig('cluster_analysis_13/images/dendrogram.png')
    plt.close()
# 评估不同K值的聚类效果
def evaluate_k_values(X, max_k=10):
    """评估不同K值的聚类效果"""
    inertias = []
    for k in range(1, max_k + 1):
        kmeans = KMeans(n_clusters=k, random_state=0)
        kmeans.fit(X)
        inertias.append(kmeans.inertia_)
    
    plt.figure(figsize=(10, 6))
    plt.plot(range(1, max_k + 1), inertias, 'bo-')
    plt.title('肘部法则图')
    plt.xlabel('聚类数量 (k)')
    plt.ylabel('聚类内平方和 (WCSS)')
    plt.savefig('cluster_analysis_13/images/elbow_method.png')
    plt.close()
if __name__ == "__main__":
    # 生成数据
    X = generate_data()
    
    # 执行K-means聚类
    kmeans_clustering(X)
    
    # 执行层次聚类
    hierarchical_clustering(X)
    
    # 评估最佳K值
    evaluate_k_values(X) 

总结

本项目实现了两种常用的聚类算法:K-means聚类和层次聚类,并对其进行了可视化和评估。主要包含以下内容:

  1. 数据生成:使用make_blobs生成用于聚类分析的模拟数据
  2. K-means聚类:
    • 实现基本的K-means聚类算法
    • 可视化聚类结果
    • 使用肘部法则评估最佳K值
  3. 层次聚类:
    • 使用Ward方法进行层次聚类
    • 可视化聚类结果
    • 生成树状图展示聚类层次结构
  4. 评估方法:
    • 使用轮廓系数评估聚类效果
    • 通过肘部法则图选择最优聚类数量
      通过本项目可以直观地理解和比较不同聚类算法的特点和适用场景。K-means适合球形簇,计算速度快;层次聚类则可以发现任意形状的簇,并提供聚类的层次结构信息。
### 聚类分析中用于图像处理和特征提取的算法 #### K-均值聚类算法 K-均值聚类是一种常用的无监督学习方法,在图像处理领域广泛应用。该算法的目标是将数据点分配到最接近它们中心的簇中,从而形成多个群集。对于图像而言,这可以通过像素的颜色或其他属性来进行分组。 ```python from sklearn.cluster import KMeans import numpy as np import matplotlib.pyplot as plt from PIL import Image def kmeans_image_segmentation(image_path, n_clusters=5): image = Image.open(image_path) image_np = np.array(image).reshape(-1, 3) kmeans = KMeans(n_clusters=n_clusters, random_state=0).fit(image_np) segmented_img = kmeans.cluster_centers_[kmeans.labels_].reshape(image.size[1], image.size[0], 3) return segmented_img.astype(np.uint8), kmeans segmented_image, model = kmeans_image_segmentation('example.jpg') plt.imshow(segmented_image) plt.show() ``` 上述代码实现了基于`sklearn`库的简单图像分割功能[^2]。 #### 特征提取技术概述 为了提高图像分类的效果,通常会先执行一系列预处理步骤并从中抽取有用的特性。以下是几种常见的图像特征提取方式: - **灰度化**:降低色彩复杂度的同时保留亮度信息。 - **边缘检测**:利用梯度算子(如Sobel、Prewitt或Canny)捕捉物体轮廓。 - **颜色直方图**:统计各通道强度分布情况作为描述符。 - **纹理分析**:借助局部二值模式(LBP)或者高斯滤波器(Gabor Filters)揭示表面结构细节[^4]。 这些手段有助于增强后续机器学习模型的表现力,并且当与合适的聚类策略相结合时,可以在诸如医学影像诊断等领域发挥重要作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值