学习日记_20241110_聚类方法(K-Means)

embedded/2024/11/19 13:04:22/

前言

提醒:
文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。
其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展及意见建议,欢迎评论区讨论交流。

文章目录

  • 前言
  • 聚类算法
    • 经典应用场景
    • K-Means 聚类
      • 简单实例(函数库实现)
      • 数学表达
        • K-Means 算法步骤
        • 数学优化目标
        • 收敛性
        • 优点
        • 缺点
      • 手动实现
        • 代码分析


聚类算法

聚类算法在各种领域中有广泛的应用,主要用于发现数据中的自然分组和模式。以下是一些常见的应用场景以及每种算法的优缺点:

经典应用场景

  1. 市场细分:根据消费者的行为和特征,将他们分成不同的群体,以便进行有针对性的营销。

  2. 图像分割: 将图像划分为多个区域或对象,以便进行进一步的分析或处理。

  3. 社交网络分析:识别社交网络中的社区结构。

  4. 文档分类:自动将文档分组到不同的主题或类别中。

  5. 异常检测识别数据中的异常点或异常行为。

  6. 基因表达分析:在生物信息学中,根据基因表达模式对基因进行聚类

K-Means 聚类

  1. K-Means 聚类
  • 优点
    • 算法简单,容易实现。
    • 计算速度快,适用于大规模数据集。
  • 缺点
    • 需要预先指定簇的数量 K K K
    • 对于初始中心点选择敏感。
    • 只能找到球状簇,无法处理非凸形状的簇。
    • 对噪声和异常值敏感。

简单实例(函数库实现)

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
# 生成数据
X = np.random.rand(100, 2)
# K-Means 聚类
kmeans = KMeans(n_clusters=3)
kmeans.fit(X)
labels = kmeans.labels_
# 可视化
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], color='red')
plt.title('K-Means Clustering')
plt.show()

X数据分布:
在这里插入图片描述
代码运行结果:
在这里插入图片描述

数学表达

K-Means 聚类是一种常用的无监督学习算法,目的是将数据分为 K K K 个簇,以最小化簇内数据点与簇中心的方差之和。下面是对
K-Means 聚类算法的详细介绍,包括其数学公式和步骤。

K-Means 算法步骤
  1. 初始化

    从数据集中随机选择 K K K 个点作为初始簇中心(质心),记作 { μ 1 , μ 2 , … , μ K } \{\mu_1, \mu_2, \ldots, \mu_K\} {μ1,μ2,,μK}

  2. 分配数据点

    对于每个数据点 x i \mathbf{x}_i xi,计算其与每个簇中心的距离,将其分配到距离最近的簇中。通常采用欧氏距离作为距离度量:

    assign  x i to cluster  j = arg ⁡ min ⁡ k ∥ x i − μ k ∥ 2 \text{assign } \mathbf{x}_i \text{ to cluster } j = \arg\min_{k} \|\mathbf{x}_i - \mu_k\|^2 assign xi to cluster j=argkminxiμk2

  3. 更新簇中心

    对于每个簇 j j j,计算簇中所有数据点的均值作为新的簇中心:

    μ j = 1 N j ∑ x i ∈ C j x i \mu_j = \frac{1}{N_j} \sum_{\mathbf{x}_i \in C_j} \mathbf{x}_i μj=Nj1xiCjxi

    其中 C j C_j Cj 表示簇 j j j 中的所有数据点, N j N_j Nj 是簇 j j j 中的点的数量。

  4. 重复

    重复步骤 2 和步骤 3,直到簇中心不再发生变化或达到预设的迭代次数。

数学优化目标

K-Means 聚类的目标是最小化所有数据点到其所属簇中心的距离平方和。其优化目标函数为:

J = ∑ j = 1 K ∑ x i ∈ C j ∥ x i − μ j ∥ 2 J = \sum_{j=1}^{K} \sum_{\mathbf{x}_i \in C_j} \|\mathbf{x}_i - \mu_j\|^2 J=j=1KxiCjxiμj2

这里, J J J 是代价函数,表示簇内平方误差和。

收敛性

K-Means 算法通过交替优化分配和更新步骤最终收敛,因为每一步都使得代价函数 J J J单调递减。然而,算法可能收敛到局部最小值,因此初始化方式对最终结果有较大影响。

优点
  • 实现简单,计算速度快。
  • 在簇形状是凸的、簇的大小相似的情况下效果较好。
缺点
  • 选择 K K K 值比较困难,通常需要通过经验或使用评估指标(如肘部法则、轮廓系数)来选择。
  • 对初始值敏感,可能导致收敛到局部最优。
  • 适用于凸形簇,对于不同大小和密度的簇效果不好。
  • 对噪声和孤立点敏感。

K-Means 聚类是一种简单有效的聚类方法,广泛应用于各种实际问题,但在使用中需注意其局限性和对参数选择的要求。

手动实现

import numpy as npdef initialize_centroids(X, K):# 从数据集中随机选择K个样本作为初始质心indices = np.random.choice(X.shape[0], K, replace=False)centroids = X[indices]return centroidsdef assign_clusters(X, centroids):# 计算每个样本到每个质心的距离,并将样本分配到最近的质心distances = np.sqrt(((X - centroids[:, np.newaxis])**2).sum(axis=2))return np.argmin(distances, axis=0)def update_centroids(X, labels, K):# 根据分配结果更新质心为每个簇中所有样本的均值centroids = np.array([X[labels == k].mean(axis=0) for k in range(K)])return centroidsdef kmeans(X, K, max_iters=100, tol=1e-4):# 初始化质心centroids = initialize_centroids(X, K)for i in range(max_iters):# 分配样本到最近的质心labels = assign_clusters(X, centroids)# 计算新的质心new_centroids = update_centroids(X, labels, K)# 检查质心是否收敛if np.all(np.abs(new_centroids - centroids) < tol):breakcentroids = new_centroidsreturn labels, centroids
# 示例用法
if __name__ == "__main__":# 生成一些测试数据X = np.array([[1.0, 2.0], [1.5, 1.8], [5.0, 8.0], [8.0, 8.0], [1.0, 0.6], [9.0, 11.0],[8.0, 2.0], [10.0, 2.0], [9.0, 3.0]])# 设定簇的数量K = 3# 运行K-Means算法labels, centroids = kmeans(X, K)print("Cluster labels:", labels)print("Centroids:", centroids)
代码分析

1. np.random.choice(X.shape[0], K, replace=False)
numpy.random.choice(a, size=None, replace=True, p=None)
np.random.choice 是 NumPy 库中的一个函数,用于从给定的一维数组中生成随机样本。它可以指定样本的数量、是否允许重复选择等参数。
在这里插入图片描述
2. np.sqrt(((X - centroids[:, np.newaxis])**2).sum(axis=2))

  • centroids[:, np.newaxis]: 使用 np.newaxiscentroids 的形状从 (K, n_features) 变为 (K, 1, n_features),这样做是为了实现广播(broadcasting),以便在后续计算中能够对每个质心与每个样本进行逐元素运算。
  • X - centroids[:, np.newaxis]:这个操作会创建一个形状为 (K, n_samples, n_features) 的数组,表示每个质心与每个样本之间的差值。
  • .sum(axis=2):这个操作会对最后一个维度(特征维度)进行求和,结果是一个形状为 (K, n_samples) 的数组,表示每个样本与每个质心之间的特征平方和。
  1. np.argmin(distances, axis=0)
  • np.argmin 是一个NumPy函数,用于找到数组中最小值的索引。
  • axis=0 表示沿着第一个轴(即行)查找最小值。这意味着对每个样本(每列)比较所有质心的距离,找到最小值对应的质心索引。

http://www.ppmy.cn/embedded/138771.html

相关文章

R语言/Rstudio 报错

记录R语言和Rstudio的报错&#xff1a; 1. Error 28 (inotify_add_watch: No watches available) File monitoring failed for project at "~xxx" Error 28 (inotify_add_watch: No watches available) Features disabled: R source file indexing, Diagnostics不少…

力扣(leetcode)题目总结——辅助栈篇

leetcode 经典题分类 链表数组字符串哈希表二分法双指针滑动窗口递归/回溯动态规划二叉树辅助栈 本系列专栏&#xff1a;点击进入 leetcode题目分类 关注走一波 前言&#xff1a;本系列文章初衷是为了按类别整理出力扣&#xff08;leetcode&#xff09;最经典题目&#xff0c…

【C++之STL】摸清 string 的模拟实现(上)

文章目录 1. 为什么要模拟实现&#xff1f;2. 基本框架搭建3. 构造函数3. 1 默认构造/from c_str3. 2 拷贝构造3. 2. 1 深浅拷贝 3. 3 fill3. 4 迭代器区间构造 4. 容量操作4. 1 size()和capacity()和empty()4. 2 clear()4. 3 resize()4. 4 reserve() 1. 为什么要模拟实现&…

【青牛科技】汽车收音机调频中频放大器——D1145

性能优势 内置多种电路&#xff1a;内置芯片中频计数缓冲电路及 ETR 微处理控制开关电路&#xff0c;这些电路的集成有助于提升整体性能和功能的集成度&#xff0c;减少外部电路的复杂性和成本1.线性输出信号好&#xff1a;能够输出质量较高的线性信号&#xff0c;这对于保证收…

Linux 中怎样把正在执行的任务放到后台执行

在使用 Linux 的过程中&#xff0c;可能会遇到某些任务需要在后台运行的情况&#xff0c;例如长时间运行的脚本或占用终端的命令。将正在执行的任务放到后台&#xff0c;可以提高操作效率&#xff0c;不需要为每个任务单独开一个终端窗口。本文将介绍几种常用的方法来实现这一目…

Android OpenGL ES详解——实例化

目录 一、实例化 1、背景 2、概念 实例化、实例数量 gl_InstanceID 应用举例 二、实例化数组 1、概念 2、应用举例 三、应用举例——小行星带 1、不使用实例化 2、使用实例化 四、总结 一、实例化 1、背景 假如你有一个有许多模型的场景&#xff0c;而这些模型的…

Amazon Linux 搭建Zookeeper+Kafka集群

Zookeeper集群搭建 Kafka集群是把状态保存在Zookeeper中的&#xff0c;首先要搭建Zookeeper集群。 Zookeeper 集群模式一共有三种类型的角色 Leader: 处理所有的事务请求&#xff08;写请求&#xff09;&#xff0c;可以处理读请求&#xff0c;集群中只能有一个Leader。 Follo…

如何在MindMaster思维导图中制作PPT课件?

思维导图是一种利用色彩、图画、线条等图文并茂的形式&#xff0c;来帮助人们增强知识或者事件的记忆。因此&#xff0c;思维导图也被常用于教育领域&#xff0c;比如&#xff1a;教学课件、读书笔记、时间管理等等。那么&#xff0c;在MindMaster免费思维导图软件中&#xff0…